Build statically linked version of dex2oat.

Change-Id: Icde39b770781095af7bd87ae6b907ad97a8a05da
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index 29b3573..2057679 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -33,6 +33,7 @@
 ART_BUILD_TARGET_DEBUG ?= true
 ART_BUILD_HOST_NDEBUG ?= true
 ART_BUILD_HOST_DEBUG ?= true
+ART_BUILD_HOST_STATIC ?= false
 
 ifeq ($(ART_BUILD_TARGET_NDEBUG),false)
 $(info Disabling ART_BUILD_TARGET_NDEBUG)
@@ -46,6 +47,9 @@
 ifeq ($(ART_BUILD_HOST_DEBUG),false)
 $(info Disabling ART_BUILD_HOST_DEBUG)
 endif
+ifeq ($(ART_BUILD_HOST_STATIC),true)
+$(info Enabling ART_BUILD_HOST_STATIC)
+endif
 
 #
 # Used to enable JIT
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index 5ed94d5..fdb2be1 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -28,6 +28,7 @@
 # $(5): target or host
 # $(6): ndebug or debug
 # $(7): value for LOCAL_MULTILIB (empty means default)
+# $(8): static or shared (empty means shared, applies only for host)
 define build-art-executable
   ifneq ($(5),target)
     ifneq ($(5),host)
@@ -42,11 +43,12 @@
 
   art_executable := $(1)
   art_source := $(2)
-  art_shared_libraries := $(3)
+  art_libraries := $(3)
   art_c_includes := $(4)
   art_target_or_host := $(5)
   art_ndebug_or_debug := $(6)
   art_multilib := $(7)
+  art_static_or_shared := $(8)
   art_out_binary_name :=
 
   include $(CLEAR_VARS)
@@ -54,7 +56,12 @@
   LOCAL_MODULE_TAGS := optional
   LOCAL_SRC_FILES := $$(art_source)
   LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime art/cmdline $$(art_c_includes)
-  LOCAL_SHARED_LIBRARIES += $$(art_shared_libraries)
+
+  ifeq ($$(art_static_or_shared),static)
+    LOCAL_STATIC_LIBRARIES += $$(art_libraries)
+  else
+    LOCAL_SHARED_LIBRARIES += $$(art_libraries)
+  endif
 
   ifeq ($$(art_ndebug_or_debug),ndebug)
     LOCAL_MODULE := $$(art_executable)
@@ -62,6 +69,10 @@
     LOCAL_MODULE := $$(art_executable)d
   endif
 
+  ifeq ($$(art_static_or_shared),static)
+    LOCAL_MODULE := $(LOCAL_MODULE)s
+  endif
+
   LOCAL_CFLAGS := $(ART_EXECUTABLES_CFLAGS)
   # Mac OS linker doesn't understand --export-dynamic.
   ifneq ($$(HOST_OS)-$$(art_target_or_host),darwin-host)
@@ -82,13 +93,26 @@
     else
       LOCAL_CFLAGS += $(ART_HOST_NON_DEBUG_CFLAGS)
     endif
-    LOCAL_LDLIBS += -lpthread -ldl
+    ifeq ($$(art_static_or_shared),static)
+      LOCAL_LDFLAGS += -static
+      # We need this because GC stress mode makes use of _Unwind_GetIP and _Unwind_Backtrace and
+      # the symbols are also defined in libgcc_eh.a(unwind-dw2.o)
+      # TODO: Having this is not ideal as it might obscure errors. Try to get rid of it.
+      LOCAL_LDFLAGS += -z muldefs
+    endif
+    LOCAL_LDLIBS += -lpthread -ldl -lrt
   endif
 
+  # If dynamically linked add libart by default. Statically linked executables
+  # needs to specify it in art_libraries to ensure proper ordering.
   ifeq ($$(art_ndebug_or_debug),ndebug)
-    LOCAL_SHARED_LIBRARIES += libart
+    ifneq ($$(art_static_or_shared),static)
+      LOCAL_SHARED_LIBRARIES += libart
+    endif
   else # debug
-    LOCAL_SHARED_LIBRARIES += libartd
+    ifneq ($$(art_static_or_shared),static)
+      LOCAL_SHARED_LIBRARIES += libartd
+    endif
   endif
 
   LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
@@ -143,11 +167,12 @@
   # Clear out local variables now that we're done with them.
   art_executable :=
   art_source :=
-  art_shared_libraries :=
+  art_libraries :=
   art_c_includes :=
   art_target_or_host :=
   art_ndebug_or_debug :=
   art_multilib :=
+  art_static_or_shared :=
   art_out_binary_name :=
 
 endef
diff --git a/compiler/Android.mk b/compiler/Android.mk
index dd21406..3947078 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -181,6 +181,7 @@
 
 # $(1): target or host
 # $(2): ndebug or debug
+# $(3): static or shared (empty means shared, applies only for host)
 define build-libart-compiler
   ifneq ($(1),target)
     ifneq ($(1),host)
@@ -195,6 +196,7 @@
 
   art_target_or_host := $(1)
   art_ndebug_or_debug := $(2)
+  art_static_or_shared := $(3)
 
   include $(CLEAR_VARS)
   ifeq ($$(art_target_or_host),host)
@@ -203,17 +205,29 @@
   LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
   ifeq ($$(art_ndebug_or_debug),ndebug)
     LOCAL_MODULE := libart-compiler
-    LOCAL_SHARED_LIBRARIES += libart
+    ifeq ($$(art_static_or_shared), static)
+      LOCAL_STATIC_LIBRARIES += libart
+    else
+      LOCAL_SHARED_LIBRARIES += libart
+    endif
     ifeq ($$(art_target_or_host),target)
       LOCAL_FDO_SUPPORT := true
     endif
   else # debug
     LOCAL_MODULE := libartd-compiler
-    LOCAL_SHARED_LIBRARIES += libartd
+    ifeq ($$(art_static_or_shared), static)
+      LOCAL_STATIC_LIBRARIES += libartd
+    else
+      LOCAL_SHARED_LIBRARIES += libartd
+    endif
   endif
 
   LOCAL_MODULE_TAGS := optional
-  LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+  ifeq ($$(art_static_or_shared), static)
+    LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+  else
+    LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+  endif
 
   LOCAL_SRC_FILES := $$(LIBART_COMPILER_SRC_FILES)
 
@@ -237,6 +251,9 @@
     LOCAL_CFLAGS += $(ART_HOST_CFLAGS)
     LOCAL_ASFLAGS += $(ART_HOST_ASFLAGS)
     LOCAL_LDLIBS := $(ART_HOST_LDLIBS)
+    ifeq ($$(art_static_or_shared),static)
+      LOCAL_LDFLAGS += -static
+    endif
     ifeq ($$(art_ndebug_or_debug),debug)
       LOCAL_CFLAGS += $(ART_HOST_DEBUG_CFLAGS)
     else
@@ -254,9 +271,17 @@
   LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
   # Vixl assembly support for ARM64 targets.
   ifeq ($$(art_ndebug_or_debug),debug)
-    LOCAL_SHARED_LIBRARIES += libvixld
+    ifeq ($$(art_static_or_shared), static)
+      LOCAL_WHOLESTATIC_LIBRARIES += libvixld
+    else
+      LOCAL_SHARED_LIBRARIES += libvixld
+    endif
   else
-    LOCAL_SHARED_LIBRARIES += libvixl
+    ifeq ($$(art_static_or_shared), static)
+      LOCAL_WHOLE_STATIC_LIBRARIES += libvixl
+    else
+      LOCAL_SHARED_LIBRARIES += libvixl
+    endif
   endif
 
   LOCAL_NATIVE_COVERAGE := $(ART_COVERAGE)
@@ -267,7 +292,11 @@
     include $(BUILD_SHARED_LIBRARY)
   else # host
     LOCAL_MULTILIB := both
-    include $(BUILD_HOST_SHARED_LIBRARY)
+    ifeq ($$(art_static_or_shared), static)
+      include $(BUILD_HOST_STATIC_LIBRARY)
+    else
+      include $(BUILD_HOST_SHARED_LIBRARY)
+    endif
   endif
 
   ifeq ($$(art_target_or_host),target)
@@ -278,20 +307,38 @@
     endif
   else # host
     ifeq ($$(art_ndebug_or_debug),debug)
-      $(HOST_OUT_EXECUTABLES)/dex2oatd: $$(LOCAL_INSTALLED_MODULE)
+      ifeq ($$(art_static_or_shared),static)
+        $(HOST_OUT_EXECUTABLES)/dex2oatds: $$(LOCAL_INSTALLED_MODULE)
+      else
+        $(HOST_OUT_EXECUTABLES)/dex2oatd: $$(LOCAL_INSTALLED_MODULE)
+      endif
     else
-      $(HOST_OUT_EXECUTABLES)/dex2oat: $$(LOCAL_INSTALLED_MODULE)
+      ifeq ($$(art_static_or_shared),static)
+        $(HOST_OUT_EXECUTABLES)/dex2oats: $$(LOCAL_INSTALLED_MODULE)
+      else
+        $(HOST_OUT_EXECUTABLES)/dex2oat: $$(LOCAL_INSTALLED_MODULE)
+      endif
     endif
   endif
 
+  # Clear locally defined variables.
+  art_target_or_host :=
+  art_ndebug_or_debug :=
+  art_static_or_shared :=
 endef
 
 # We always build dex2oat and dependencies, even if the host build is otherwise disabled, since they are used to cross compile for the target.
 ifeq ($(ART_BUILD_HOST_NDEBUG),true)
   $(eval $(call build-libart-compiler,host,ndebug))
+  ifeq ($(ART_BUILD_HOST_STATIC),true)
+    $(eval $(call build-libart-compiler,host,ndebug,static))
+  endif
 endif
 ifeq ($(ART_BUILD_HOST_DEBUG),true)
   $(eval $(call build-libart-compiler,host,debug))
+  ifeq ($(ART_BUILD_HOST_STATIC),true)
+    $(eval $(call build-libart-compiler,host,debug,static))
+  endif
 endif
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
   $(eval $(call build-libart-compiler,target,ndebug))
diff --git a/dex2oat/Android.mk b/dex2oat/Android.mk
index b4d2343..d27ee3e 100644
--- a/dex2oat/Android.mk
+++ b/dex2oat/Android.mk
@@ -40,6 +40,7 @@
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
   $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libart-compiler libsigchain,art/compiler,target,ndebug,$(dex2oat_target_arch)))
 endif
+
 ifeq ($(ART_BUILD_TARGET_DEBUG),true)
   $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libartd-compiler libsigchain,art/compiler,target,debug,$(dex2oat_target_arch)))
 endif
@@ -47,7 +48,14 @@
 # We always build dex2oat and dependencies, even if the host build is otherwise disabled, since they are used to cross compile for the target.
 ifeq ($(ART_BUILD_HOST_NDEBUG),true)
   $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libart-compiler libsigchain libziparchive-host,art/compiler,host,ndebug,$(dex2oat_host_arch)))
+  ifeq ($(ART_BUILD_HOST_STATIC),true)
+    $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libart libart-compiler libart libziparchive-host libnativehelper libnativebridge libsigchain_dummy libvixl liblog libz libbacktrace libcutils libunwindbacktrace libutils libbase,art/compiler,host,ndebug,$(dex2oat_host_arch),static))
+  endif
 endif
+
 ifeq ($(ART_BUILD_HOST_DEBUG),true)
   $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libartd-compiler libsigchain libziparchive-host,art/compiler,host,debug,$(dex2oat_host_arch)))
+  ifeq ($(ART_BUILD_HOST_STATIC),true)
+    $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libartd libartd-compiler libartd libziparchive-host libnativehelper libnativebridge libsigchain_dummy libvixld liblog libz libbacktrace libcutils libunwindbacktrace libutils libbase,art/compiler,host,debug,$(dex2oat_host_arch),static))
+  endif
 endif
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 19079cb..7f103a4 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -369,6 +369,7 @@
 
 # $(1): target or host
 # $(2): ndebug or debug
+# $(3): static or shared (empty means shared, applies only for host)
 define build-libart
   ifneq ($(1),target)
     ifneq ($(1),host)
@@ -383,6 +384,7 @@
 
   art_target_or_host := $(1)
   art_ndebug_or_debug := $(2)
+  art_static_or_shared := $(3)
 
   include $$(CLEAR_VARS)
   # Clang assembler has problem with macros in asm_support_x86.S, http://b/17443165,
@@ -403,7 +405,12 @@
   endif
 
   LOCAL_MODULE_TAGS := optional
-  LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+  ifeq ($$(art_static_or_shared),static)
+    LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+  else
+    LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+  endif
 
   ifeq ($$(art_target_or_host),target)
     LOCAL_SRC_FILES := $$(LIBART_TARGET_SRC_FILES)
@@ -431,8 +438,11 @@
   LOCAL_LDFLAGS := $$(LIBART_LDFLAGS)
   ifeq ($$(art_target_or_host),target)
     LOCAL_LDFLAGS += $$(LIBART_TARGET_LDFLAGS)
-  else
+  else #host
     LOCAL_LDFLAGS += $$(LIBART_HOST_LDFLAGS)
+    ifeq ($$(art_static_or_shared),static)
+      LOCAL_LDFLAGS += -static
+    endif
   endif
   $$(foreach arch,$$(ART_TARGET_SUPPORTED_ARCH), \
     $$(eval LOCAL_LDFLAGS_$$(arch) := $$(LIBART_TARGET_LDFLAGS_$$(arch))))
@@ -467,8 +477,12 @@
   LOCAL_C_INCLUDES += art/sigchainlib
   LOCAL_C_INCLUDES += art
 
-  LOCAL_SHARED_LIBRARIES := libnativehelper libnativebridge libsigchain
-  LOCAL_SHARED_LIBRARIES += libbacktrace
+  ifeq ($$(art_static_or_shared),static)
+    LOCAL_STATIC_LIBRARIES := libnativehelper libnativebridge libsigchain_dummy libbacktrace
+  else
+    LOCAL_SHARED_LIBRARIES := libnativehelper libnativebridge libsigchain libbacktrace
+  endif
+
   ifeq ($$(art_target_or_host),target)
     LOCAL_SHARED_LIBRARIES += libdl
     # ZipArchive support, the order matters here to get all symbols.
@@ -478,9 +492,15 @@
     # For liblog, atrace, properties, ashmem, set_sched_policy and socket_peer_is_trusted.
     LOCAL_SHARED_LIBRARIES += libcutils
   else # host
-    LOCAL_SHARED_LIBRARIES += libziparchive-host libz-host
-    # For ashmem_create_region.
-    LOCAL_SHARED_LIBRARIES += libcutils
+    ifeq ($$(art_static_or_shared),static)
+      LOCAL_STATIC_LIBRARIES += libziparchive-host libz
+      # For ashmem_create_region.
+      LOCAL_STATIC_LIBRARIES += libcutils
+    else
+      LOCAL_SHARED_LIBRARIES += libziparchive-host libz-host
+      # For ashmem_create_region.
+      LOCAL_SHARED_LIBRARIES += libcutils
+    endif
   endif
   LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
   LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk
@@ -499,7 +519,11 @@
     endif
     include $$(BUILD_SHARED_LIBRARY)
   else # host
-    include $$(BUILD_HOST_SHARED_LIBRARY)
+    ifeq ($$(art_static_or_shared),static)
+      include $$(BUILD_HOST_STATIC_LIBRARY)
+    else
+      include $$(BUILD_HOST_SHARED_LIBRARY)
+    endif
   endif
 
   # Clear locally defined variables.
@@ -508,15 +532,22 @@
   ENUM_OPERATOR_OUT_GEN :=
   art_target_or_host :=
   art_ndebug_or_debug :=
+  art_static_or_shared :=
 endef
 
 # We always build dex2oat and dependencies, even if the host build is otherwise disabled, since
 # they are used to cross compile for the target.
 ifeq ($(ART_BUILD_HOST_NDEBUG),true)
   $(eval $(call build-libart,host,ndebug))
+  ifeq ($(ART_BUILD_HOST_STATIC),true)
+    $(eval $(call build-libart,host,ndebug,static))
+  endif
 endif
 ifeq ($(ART_BUILD_HOST_DEBUG),true)
   $(eval $(call build-libart,host,debug))
+  ifeq ($(ART_BUILD_HOST_STATIC),true)
+    $(eval $(call build-libart,host,debug,static))
+  endif
 endif
 
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
diff --git a/sigchainlib/Android.mk b/sigchainlib/Android.mk
index 11f44fe..b9e37a1 100644
--- a/sigchainlib/Android.mk
+++ b/sigchainlib/Android.mk
@@ -76,3 +76,19 @@
 LOCAL_LDLIBS = -ldl
 LOCAL_MULTILIB := both
 include $(BUILD_HOST_STATIC_LIBRARY)
+
+# Create a dummy version of libsigchain which expose the necessary symbols
+# but throws when called. This can be used to get static binaries which don't
+# need the real functionality of the sig chain but need to please the linker.
+include $(CLEAR_VARS)
+LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
+LOCAL_MODULE_TAGS := optional
+LOCAL_IS_HOST_MODULE := true
+LOCAL_CFLAGS += $(ART_HOST_CFLAGS)
+LOCAL_CLANG = $(ART_HOST_CLANG)
+LOCAL_SRC_FILES := sigchain_dummy.cc
+LOCAL_MODULE:= libsigchain_dummy
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+LOCAL_LDLIBS = -ldl
+LOCAL_MULTILIB := both
+include $(BUILD_HOST_STATIC_LIBRARY)