Build changes to build multilib tests

Test files will be emitted into directories for both first and second
target architectures. Going with the naming scheme for binaries,
single-architecture and 32b cases have the standard name, and
64b goes into a directory with "64" suffix.

In multi-architecture setups, the default concrete test targets are
extended with a "32" and "64" suffix, e.g., test-art-target-oat-JniTest64.
The suffix-less form is linked to the primary architecture target (usually 64).
That means running combined targets, e.g., test-art-target-oat, will only
test the primary architecture right now.

Fixed target run tests calling the right dalvikvm. Fixed library search
path for tests derived from CommonRuntimeTest.

Missing in this work-in-progress is correct handling of dex2oat for the
secondary architecture. To make it work on 64b, comment out line 101
in build/Android.executable.mk

Change-Id: I3d260994e6efe8b73b56c71994053cc9392943a9
diff --git a/build/Android.common.mk b/build/Android.common.mk
index d80d039..b9a297b 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -127,12 +127,48 @@
 ART_DALVIK_CACHE_DIR := /data/dalvik-cache
 
 # directory used for gtests on device
-ART_NATIVETEST_DIR := /data/nativetest/art
-ART_NATIVETEST_OUT := $(TARGET_OUT_DATA_NATIVE_TESTS)/art
+ART_BASE_NATIVETEST_DIR := /data/nativetest/art
+ART_BASE_NATIVETEST_OUT := $(TARGET_OUT_DATA_NATIVE_TESTS)/art
 
 # directory used for tests on device
-ART_TEST_DIR := /data/art-test
-ART_TEST_OUT := $(TARGET_OUT_DATA)/art-test
+ART_BASE_TEST_DIR := /data/art-test
+ART_BASE_TEST_OUT := $(TARGET_OUT_DATA)/art-test
+
+# Primary vs. secondary
+2ND_TARGET_ARCH := $(TARGET_2ND_ARCH)
+ART_PHONY_TEST_TARGET_SUFFIX :=
+2ND_ART_PHONY_TEST_TARGET_SUFFIX :=
+ART_TARGET_BINARY_SUFFIX :=
+2ND_ART_TARGET_BINARY_SUFFIX :=
+ifdef TARGET_2ND_ARCH
+  art_test_primary_suffix :=
+  art_test_secondary_suffix :=
+  ifneq ($(filter %64,$(TARGET_ARCH)),)
+    art_test_primary_suffix := 64
+    ART_PHONY_TEST_TARGET_SUFFIX := 64
+    2ND_ART_PHONY_TEST_TARGET_SUFFIX := 32
+    ART_TARGET_BINARY_SUFFIX := 64
+  else
+    # TODO: ???
+    $(error Do not know what to do with this multi-target configuration!)
+  endif
+  # Primary with primary suffix
+  ART_NATIVETEST_DIR := $(ART_BASE_NATIVETEST_DIR)$(art_test_primary_suffix)
+  ART_NATIVETEST_OUT := $(ART_BASE_NATIVETEST_OUT)$(art_test_primary_suffix)
+  ART_TEST_DIR := $(ART_BASE_TEST_DIR)$(art_test_primary_suffix)
+  ART_TEST_OUT := $(ART_BASE_TEST_OUT)$(art_test_primary_suffix)
+  # Secondary with 2ND_ prefix and secondary suffix
+  2ND_ART_NATIVETEST_DIR := $(ART_BASE_NATIVETEST_DIR)$(art_test_secondary_suffix)
+  2ND_ART_NATIVETEST_OUT := $(ART_BASE_NATIVETEST_OUT)$(art_test_secondary_suffix)
+  2ND_ART_TEST_DIR := $(ART_BASE_TEST_DIR)$(art_test_secondary_suffix)
+  2ND_ART_TEST_OUT := $(ART_BASE_TEST_OUT)$(art_test_secondary_suffix)
+else
+  ART_NATIVETEST_DIR := $(ART_BASE_NATIVETEST_DIR)
+  ART_NATIVETEST_OUT := $(ART_BASE_NATIVETEST_OUT)
+  ART_TEST_DIR := $(ART_BASE_TEST_DIR)
+  ART_TEST_OUT := $(ART_BASE_TEST_OUT)
+  # No secondary
+endif
 
 ART_CPP_EXTENSION := .cc
 
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index 551b03c..88ca47e 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -98,8 +98,6 @@
 
   ifeq ($$(art_target_or_host),target)
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
-    #HACK: force 32-bit until 64-bit dex2oat can handle 32-bit
-    LOCAL_32_BIT_ONLY := true
   endif
 
   ifeq ($$(art_target_or_host),target)
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index da0b500..5b83056 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -113,6 +113,22 @@
   ART_TEST_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
 endif
 
+# Build a make target for a target test.
+# (1) Prefix for variables
+define build-art-test-make-target
+.PHONY: $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
+$$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX): $($(1)ART_NATIVETEST_OUT)/$$(LOCAL_MODULE) test-art-target-sync
+	adb shell touch $($(1)ART_TEST_DIR)/$$@
+	adb shell rm $($(1)ART_TEST_DIR)/$$@
+	adb shell chmod 755 $($(1)ART_NATIVETEST_DIR)/$$(notdir $$<)
+	adb shell sh -c "$($(1)ART_NATIVETEST_DIR)/$$(notdir $$<) && touch $($(1)ART_TEST_DIR)/$$@"
+	$(hide) (adb pull $($(1)ART_TEST_DIR)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
+	$(hide) rm /tmp/$$@
+
+    ART_TARGET_GTEST_TARGETS += $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
+endef
+
+
 # $(1): target or host
 # $(2): file name
 # $(3): extra C includes
@@ -163,10 +179,23 @@
     LOCAL_CFLAGS_x86 := $(ART_TARGET_CFLAGS_x86)
     LOCAL_SHARED_LIBRARIES += libdl libicuuc libicui18n libnativehelper libz libcutils
     LOCAL_STATIC_LIBRARIES += libgtest
-    LOCAL_MODULE_PATH := $(ART_NATIVETEST_OUT)
+    LOCAL_MODULE_PATH_32 := $(ART_BASE_NATIVETEST_OUT)
+    LOCAL_MODULE_PATH_64 := $(ART_BASE_NATIVETEST_OUT)64
+    LOCAL_MULTILIB := both
     include $(BUILD_EXECUTABLE)
-    art_gtest_exe := $$(LOCAL_MODULE_PATH)/$$(LOCAL_MODULE)
     ART_TARGET_GTEST_EXECUTABLES += $$(art_gtest_exe)
+    art_gtest_target := test-art-$$(art_target_or_host)-gtest-$$(art_gtest_name)
+
+    ifdef TARGET_2ND_ARCH
+      $(call build-art-test-make-target,2ND_)
+
+      # Bind the primary to the non-suffix rule
+      ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
+$$(art_gtest_target): $$(art_gtest_target)$(ART_PHONY_TEST_TARGET_SUFFIX)
+      endif
+    endif
+    $(call build-art-test-make-target,)
+
   else # host
     LOCAL_CLANG := $(ART_HOST_CLANG)
     LOCAL_CFLAGS += $(ART_HOST_CFLAGS) $(ART_HOST_DEBUG_CFLAGS)
@@ -180,34 +209,21 @@
     include $(BUILD_HOST_EXECUTABLE)
     art_gtest_exe := $(HOST_OUT_EXECUTABLES)/$$(LOCAL_MODULE)
     ART_HOST_GTEST_EXECUTABLES += $$(art_gtest_exe)
-  endif
-art_gtest_target := test-art-$$(art_target_or_host)-gtest-$$(art_gtest_name)
-ifeq ($$(art_target_or_host),target)
-.PHONY: $$(art_gtest_target)
-$$(art_gtest_target): $$(art_gtest_exe) test-art-target-sync
-	adb shell touch $(ART_TEST_DIR)/$$@
-	adb shell rm $(ART_TEST_DIR)/$$@
-	adb shell chmod 755 $(ART_NATIVETEST_DIR)/$$(notdir $$<)
-	adb shell sh -c "$(ART_NATIVETEST_DIR)/$$(notdir $$<) && touch $(ART_TEST_DIR)/$$@"
-	$(hide) (adb pull $(ART_TEST_DIR)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
-	$(hide) rm /tmp/$$@
-
-ART_TARGET_GTEST_TARGETS += $$(art_gtest_target)
-else
+    art_gtest_target := test-art-$$(art_target_or_host)-gtest-$$(art_gtest_name)
 .PHONY: $$(art_gtest_target)
 $$(art_gtest_target): $$(art_gtest_exe) test-art-host-dependencies
 	$$<
 	@echo $$@ PASSED
 
-ART_HOST_GTEST_TARGETS += $$(art_gtest_target)
+    ART_HOST_GTEST_TARGETS += $$(art_gtest_target)
 
 .PHONY: valgrind-$$(art_gtest_target)
 valgrind-$$(art_gtest_target): $$(art_gtest_exe) test-art-host-dependencies
 	valgrind --leak-check=full --error-exitcode=1 $$<
 	@echo $$@ PASSED
 
-ART_HOST_VALGRIND_GTEST_TARGETS += valgrind-$$(art_gtest_target)
-endif
+    ART_HOST_VALGRIND_GTEST_TARGETS += valgrind-$$(art_gtest_target)
+  endif
 endef
 
 ifeq ($(ART_BUILD_TARGET),true)
diff --git a/build/Android.libarttest.mk b/build/Android.libarttest.mk
index d807a9c..14d16ac 100644
--- a/build/Android.libarttest.mk
+++ b/build/Android.libarttest.mk
@@ -51,7 +51,9 @@
     LOCAL_CFLAGS_x86 := $(ART_TARGET_CFLAGS_x86)
     LOCAL_SHARED_LIBRARIES += libdl libcutils
     LOCAL_STATIC_LIBRARIES := libgtest
-    LOCAL_MODULE_PATH := $(ART_TEST_OUT)
+    LOCAL_MULTILIB := both
+    LOCAL_MODULE_PATH_32 := $(ART_BASE_TEST_OUT)
+    LOCAL_MODULE_PATH_64 := $(ART_BASE_TEST_OUT)64
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
     include $(BUILD_SHARED_LIBRARY)
   else # host
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index def585b..51beedc 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -31,12 +31,15 @@
 
 HOST_CORE_OAT := $(HOST_OUT_JAVA_LIBRARIES)/core.oat
 TARGET_CORE_OAT := $(ART_TEST_DIR)/core.oat
+2ND_TARGET_CORE_OAT := $(2ND_ART_TEST_DIR)/core.oat
 
 HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/core.oat
 TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/core.oat
+2ND_TARGET_CORE_OAT_OUT := $(2ND_ART_TEST_OUT)/core.oat
 
 HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/core.art
 TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/core.art
+2ND_TARGET_CORE_IMG_OUT := $(2ND_ART_TEST_OUT)/core.art
 
 TARGET_INSTRUCTION_SET_FEATURES := $(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
 
@@ -48,17 +51,25 @@
 		--oat-location=$(HOST_CORE_OAT) --image=$(HOST_CORE_IMG_OUT) --base=$(LIBART_IMG_HOST_BASE_ADDRESS) \
 		--instruction-set=$(ART_HOST_ARCH) --host --android-root=$(HOST_OUT)
 
-$(TARGET_CORE_IMG_OUT): $(TARGET_CORE_DEX_FILES) $(DEX2OAT_DEPENDENCY)
-	@echo "target dex2oat: $@ ($?)"
-	@mkdir -p $(dir $@)
-	$(hide) $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$(PRELOADED_CLASSES) $(addprefix \
-		--dex-file=,$(TARGET_CORE_DEX_FILES)) $(addprefix --dex-location=,$(TARGET_CORE_DEX_LOCATIONS)) --oat-file=$(TARGET_CORE_OAT_OUT) \
-		--oat-location=$(TARGET_CORE_OAT) --image=$(TARGET_CORE_IMG_OUT) --base=$(LIBART_IMG_TARGET_BASE_ADDRESS) \
-		--instruction-set=$(TARGET_ARCH) --instruction-set-features=$(TARGET_INSTRUCTION_SET_FEATURES) --android-root=$(PRODUCT_OUT)/system
-
 $(HOST_CORE_OAT_OUT): $(HOST_CORE_IMG_OUT)
 
-$(TARGET_CORE_OAT_OUT): $(TARGET_CORE_IMG_OUT)
+define create-oat-target-targets
+$$($(1)TARGET_CORE_IMG_OUT): $$($(1)TARGET_CORE_DEX_FILES) $$(DEX2OAT_DEPENDENCY)
+	@echo "target dex2oat: $$@ ($$?)"
+	@mkdir -p $$(dir $$@)
+	$$(hide) $$(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$$(PRELOADED_CLASSES) $$(addprefix \
+		--dex-file=,$$(TARGET_CORE_DEX_FILES)) $$(addprefix --dex-location=,$$(TARGET_CORE_DEX_LOCATIONS)) --oat-file=$$($(1)TARGET_CORE_OAT_OUT) \
+		--oat-location=$$($(1)TARGET_CORE_OAT) --image=$$($(1)TARGET_CORE_IMG_OUT) --base=$$(LIBART_IMG_TARGET_BASE_ADDRESS) \
+		--instruction-set=$$($(1)TARGET_ARCH) --instruction-set-features=$$(TARGET_INSTRUCTION_SET_FEATURES) --android-root=$$(PRODUCT_OUT)/system
+
+$$($(1)TARGET_CORE_OAT_OUT): $$($(1)TARGET_CORE_IMG_OUT)
+endef
+
+ifdef TARGET_2ND_ARCH
+$(eval $(call create-oat-target-targets,2ND_))
+endif
+$(eval $(call create-oat-target-targets,))
+
 
 ifeq ($(ART_BUILD_HOST),true)
 include $(CLEAR_VARS)