Multilib ART host.

Build ART for the host as a multilib project with dalvikvm32 and dalvikvm64
running as 32 or 64-bit repsectfully. Note, currently multilib host builds
are not the default, you make the so by setting BUILD_HOST_64bit=1.
Extend tests to execute in both 32 and 64-bit modes. By default both 32 and
64-bit tests are run, add 32 or 64 to the end of a test name to run it in
purely that flavor.
Given the extra spam, modify oat tests to only generate console output when
the test fails.
Change the test harness so that common commands are run when a test should be
skipped, when it passes or when it fails. Use these commands to generate a
summary of passing, skipped and failing tests. Tests will be skipped if they
are known to be broken or if a test has already failed. Setting the variable
TEST_ART_KEEP_GOING=true will force working tests not to be skipped.
In this change all tests running on the optimizing compiler are marked broken
due to breakages running them in a multilib environment.
Break apart Android.common.mk into its constituent parts, along with other
pieces of reorganization.

Stylistic nit, we refer to make rule targets as targets thereby overloading
the term target. While consistent with make's terminology, its confusing with
the Android notion of target. I've switched to just calling targets rules to
avoid confusion in host tests.

Change-Id: I5190fc3de46800a949fbb06b3f4c258ca89ccde9
diff --git a/Android.mk b/Android.mk
index 593ee04..18e1c64 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,13 +17,13 @@
 LOCAL_PATH := $(call my-dir)
 
 art_path := $(LOCAL_PATH)
-art_build_path := $(art_path)/build
-include $(art_build_path)/Android.common.mk
 
 ########################################################################
-# clean-oat targets
+# clean-oat rules
 #
 
+include $(art_path)/build/Android.common_path.mk
+
 # following the example of build's dont_bother for clean targets
 ifneq (,$(filter clean-oat,$(MAKECMDGOALS)))
 art_dont_bother := true
@@ -45,6 +45,11 @@
 	rm -f $(HOST_CORE_IMG_OUT)
 	rm -f $(HOST_CORE_OAT_OUT)
 	rm -f $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/*.odex
+ifneq ($(HOST_PREFER_32_BIT),true)
+	rm -f $(2ND_HOST_CORE_IMG_OUT)
+	rm -f $(2ND_HOST_CORE_OAT_OUT)
+	rm -f $(HOST_OUT_JAVA_LIBRARIES)/$(2ND_ART_HOST_ARCH)/*.odex
+endif
 	rm -f $(TARGET_CORE_IMG_OUT)
 	rm -f $(TARGET_CORE_OAT_OUT)
 ifdef TARGET_2ND_ARCH
@@ -67,9 +72,9 @@
 .PHONY: clean-oat-target
 clean-oat-target:
 	adb remount
-	adb shell rm -rf $(ART_NATIVETEST_DIR)
-	adb shell rm -rf $(ART_TEST_DIR)
-	adb shell rm -rf $(ART_DALVIK_CACHE_DIR)/*
+	adb shell rm -rf $(ART_TARGET_NATIVETEST_DIR)
+	adb shell rm -rf $(ART_TARGET_TEST_DIR)
+	adb shell rm -rf $(ART_TARGET_DALVIK_CACHE_DIR)/*/*
 	adb shell rm -rf $(DEXPREOPT_BOOT_JAR_DIR)/$(DEX2OAT_TARGET_ARCH)
 	adb shell rm -rf system/app/$(DEX2OAT_TARGET_ARCH)
 ifdef TARGET_2ND_ARCH
@@ -81,7 +86,13 @@
 ifneq ($(art_dont_bother),true)
 
 ########################################################################
-# product targets
+# cpplint rules to style check art source files
+
+include $(art_path)/build/Android.cpplint.mk
+
+########################################################################
+# product rules
+
 include $(art_path)/runtime/Android.mk
 include $(art_path)/compiler/Android.mk
 include $(art_path)/dex2oat/Android.mk
@@ -89,251 +100,203 @@
 include $(art_path)/oatdump/Android.mk
 include $(art_path)/dalvikvm/Android.mk
 include $(art_path)/tools/Android.mk
-include $(art_build_path)/Android.oat.mk
+include $(art_path)/build/Android.oat.mk
 include $(art_path)/sigchainlib/Android.mk
 
 
-
-
 # ART_HOST_DEPENDENCIES depends on Android.executable.mk above for ART_HOST_EXECUTABLES
-ART_HOST_DEPENDENCIES := $(ART_HOST_EXECUTABLES) $(HOST_OUT_JAVA_LIBRARIES)/core-libart-hostdex.jar
-ART_HOST_DEPENDENCIES += $(HOST_LIBRARY_PATH)/libjavacore$(ART_HOST_SHLIB_EXTENSION)
-ART_TARGET_DEPENDENCIES := $(ART_TARGET_EXECUTABLES) $(TARGET_OUT_JAVA_LIBRARIES)/core-libart.jar $(TARGET_OUT_SHARED_LIBRARIES)/libjavacore.so
+ART_HOST_DEPENDENCIES := $(ART_HOST_EXECUTABLES) $(HOST_OUT_JAVA_LIBRARIES)/core-libart-hostdex.jar \
+	$(HOST_LIBRARY_PATH)/libjavacore$(ART_HOST_SHLIB_EXTENSION)
+ART_TARGET_DEPENDENCIES := $(ART_TARGET_EXECUTABLES) $(TARGET_OUT_JAVA_LIBRARIES)/core-libart.jar \
+	$(TARGET_OUT_SHARED_LIBRARIES)/libjavacore.so
 ifdef TARGET_2ND_ARCH
 ART_TARGET_DEPENDENCIES += $(2ND_TARGET_OUT_SHARED_LIBRARIES)/libjavacore.so
 endif
 
 ########################################################################
-# test targets
+# test rules
 
-include $(art_path)/test/Android.mk
-include $(art_build_path)/Android.gtest.mk
+# All the dependencies that must be built ahead of sync-ing them onto the target device.
+TEST_ART_TARGET_SYNC_DEPS :=
 
-$(eval $(call combine-art-multi-target-var,ART_TARGET_GTEST_TARGETS))
-$(eval $(call combine-art-multi-target-var,ART_TARGET_GTEST_EXECUTABLES))
+include $(art_path)/build/Android.common_test.mk
+include $(art_path)/build/Android.gtest.mk
+include $(art_path)/test/Android.oat.mk
+include $(art_path)/test/Android.run-test.mk
 
-# The ART_*_TEST_DEPENDENCIES definitions:
-# - depend on Android.oattest.mk above for ART_TEST_*_DEX_FILES
-# - depend on Android.gtest.mk above for ART_*_GTEST_EXECUTABLES
-ART_HOST_TEST_DEPENDENCIES   := $(ART_HOST_DEPENDENCIES)   $(ART_HOST_GTEST_EXECUTABLES)   $(ART_TEST_HOST_DEX_FILES)   $(HOST_CORE_IMG_OUT)
+# Sync test files to the target, depends upon all things that must be pushed to the target.
+.PHONY: test-art-target-sync
+test-art-target-sync: $(TEST_ART_TARGET_SYNC_DEPS)
+	adb remount
+	adb sync
+	adb shell mkdir -p $(ART_TARGET_TEST_DIR)
 
-define declare-art-target-test-dependencies-var
-ART_TARGET_TEST_DEPENDENCIES$(1) := $(ART_TARGET_DEPENDENCIES) $(ART_TARGET_GTEST_EXECUTABLES$(1)) $(ART_TEST_TARGET_DEX_FILES$(1)) $(TARGET_CORE_IMG_OUT$(1))
-endef
-$(eval $(call call-art-multi-target-var,declare-art-target-test-dependencies-var,ART_TARGET_TEST_DEPENDENCIES))
-
-include $(art_build_path)/Android.libarttest.mk
+# Undefine variable now its served its purpose.
+TEST_ART_TARGET_SYNC_DEPS :=
 
 # "mm test-art" to build and run all tests on host and device
 .PHONY: test-art
 test-art: test-art-host test-art-target
-	@echo test-art PASSED
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
 .PHONY: test-art-gtest
 test-art-gtest: test-art-host-gtest test-art-target-gtest
-	@echo test-art-gtest PASSED
-
-.PHONY: test-art-oat
-test-art-oat: test-art-host-oat test-art-target-oat
-	@echo test-art-oat PASSED
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
 .PHONY: test-art-run-test
 test-art-run-test: test-art-host-run-test test-art-target-run-test
-	@echo test-art-run-test PASSED
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
 ########################################################################
-# host test targets
+# host test rules
 
-.PHONY: test-art-host-vixl
 VIXL_TEST_DEPENDENCY :=
 # We can only run the vixl tests on 64-bit hosts (vixl testing issue) when its a
 # top-level build (to declare the vixl test rule).
-ifneq ($(HOST_IS_64_BIT),)
+ifneq ($(HOST_PREFER_32_BIT),true)
 ifeq ($(ONE_SHOT_MAKEFILE),)
 VIXL_TEST_DEPENDENCY := run-vixl-tests
 endif
 endif
 
+.PHONY: test-art-host-vixl
 test-art-host-vixl: $(VIXL_TEST_DEPENDENCY)
 
-# "mm test-art-host" to build and run all host tests
+# "mm test-art-host" to build and run all host tests.
 .PHONY: test-art-host
 test-art-host: test-art-host-gtest test-art-host-oat test-art-host-run-test test-art-host-vixl
-	@echo test-art-host PASSED
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
+# All host tests that run solely with the default compiler.
+.PHONY: test-art-host-default
+test-art-host-default: test-art-host-oat-default test-art-host-run-test-default
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# All host tests that run solely with the optimizing compiler.
+.PHONY: test-art-host-optimizing
+test-art-host-optimizing: test-art-host-oat-optimizing test-art-host-run-test-optimizing
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# All host tests that run solely on the interpreter.
 .PHONY: test-art-host-interpreter
 test-art-host-interpreter: test-art-host-oat-interpreter test-art-host-run-test-interpreter
-	@echo test-art-host-interpreter PASSED
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-.PHONY: test-art-host-dependencies
-test-art-host-dependencies: $(ART_HOST_TEST_DEPENDENCIES) $(HOST_LIBRARY_PATH)/libarttest$(ART_HOST_SHLIB_EXTENSION) $(HOST_CORE_DEX_LOCATIONS)
+# Primary host architecture variants:
+.PHONY: test-art-host$(ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host$(ART_PHONY_TEST_HOST_SUFFIX): test-art-host-gtest$(ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-oat$(ART_PHONY_TEST_HOST_SUFFIX) test-art-host-run-test$(ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-.PHONY: test-art-host-gtest
-test-art-host-gtest: $(ART_HOST_GTEST_TARGETS)
-	@echo test-art-host-gtest PASSED
+.PHONY: test-art-host-default$(ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host-default$(ART_PHONY_TEST_HOST_SUFFIX): test-art-host-oat-default$(ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-run-test-default$(ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-# "mm valgrind-test-art-host-gtest" to build and run the host gtests under valgrind.
-.PHONY: valgrind-test-art-host-gtest
-valgrind-test-art-host-gtest: $(ART_HOST_VALGRIND_GTEST_TARGETS)
-	@echo valgrind-test-art-host-gtest PASSED
+.PHONY: test-art-host-optimizing$(ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host-optimizing$(ART_PHONY_TEST_HOST_SUFFIX): test-art-host-oat-optimizing$(ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-run-test-optimizing$(ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-.PHONY: test-art-host-oat-default
-test-art-host-oat-default: $(ART_TEST_HOST_OAT_DEFAULT_TARGETS)
-	@echo test-art-host-oat-default PASSED
+.PHONY: test-art-host-interpreter$(ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host-interpreter$(ART_PHONY_TEST_HOST_SUFFIX): test-art-host-oat-interpreter$(ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-run-test-interpreter$(ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-.PHONY: test-art-host-oat-interpreter
-test-art-host-oat-interpreter: $(ART_TEST_HOST_OAT_INTERPRETER_TARGETS)
-	@echo test-art-host-oat-interpreter PASSED
+# Secondary host architecture variants:
+ifneq ($(HOST_PREFER_32_BIT),true)
+.PHONY: test-art-host$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host$(2ND_ART_PHONY_TEST_HOST_SUFFIX): test-art-host-gtest$(2ND_ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-oat$(2ND_ART_PHONY_TEST_HOST_SUFFIX) test-art-host-run-test$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-.PHONY: test-art-host-oat
-test-art-host-oat: test-art-host-oat-default test-art-host-oat-interpreter
-	@echo test-art-host-oat PASSED
+.PHONY: test-art-host-default$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host-default$(2ND_ART_PHONY_TEST_HOST_SUFFIX): test-art-host-oat-default$(2ND_ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-run-test-default$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-FAILING_OPTIMIZING_MESSAGE := failed with the optimizing compiler. If the test passes \
-  with Quick and interpreter, it is probably just a bug in the optimizing compiler. Please \
-  add the test name to the FAILING_OPTIMIZING_TESTS Makefile variable in art/Android.mk, \
-  and file a bug.
+.PHONY: test-art-host-optimizing$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host-optimizing$(2ND_ART_PHONY_TEST_HOST_SUFFIX): test-art-host-oat-optimizing$(2ND_ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-run-test-optimizing$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 
-# Placeholder for failing tests on the optimizing compiler.
-
-define declare-test-art-host-run-test
-.PHONY: test-art-host-run-test-default-$(1)
-test-art-host-run-test-default-$(1): test-art-host-dependencies $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
-	DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) art/test/run-test $(addprefix --runtime-option ,$(DALVIKVM_FLAGS)) --host $(1)
-	@echo test-art-host-run-test-default-$(1) PASSED
-
-TEST_ART_HOST_RUN_TEST_DEFAULT_TARGETS += test-art-host-run-test-default-$(1)
-
-.PHONY: test-art-host-run-test-optimizing-$(1)
-test-art-host-run-test-optimizing-$(1): test-art-host-dependencies $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
-	DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) art/test/run-test -Xcompiler-option --compiler-backend=Optimizing $(addprefix --runtime-option ,$(DALVIKVM_FLAGS)) --host $(1) \
-	|| (echo -e "\x1b[31;01mTest $(1) $(FAILING_OPTIMIZING_MESSAGE)\x1b[0m" && exit 1)
-	@echo test-art-host-run-test-optimizing-$(1) PASSED
-
-TEST_ART_HOST_RUN_TEST_OPTIMIZING_TARGETS += test-art-host-run-test-optimizing-$(1)
-
-.PHONY: test-art-host-run-test-interpreter-$(1)
-test-art-host-run-test-interpreter-$(1): test-art-host-dependencies $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
-	DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) art/test/run-test $(addprefix --runtime-option ,$(DALVIKVM_FLAGS)) --host --interpreter $(1)
-	@echo test-art-host-run-test-interpreter-$(1) PASSED
-
-TEST_ART_HOST_RUN_TEST_INTERPRETER_TARGETS += test-art-host-run-test-interpreter-$(1)
-
-.PHONY: test-art-host-run-test-$(1)
-test-art-host-run-test-$(1): test-art-host-run-test-default-$(1) test-art-host-run-test-interpreter-$(1) test-art-host-run-test-optimizing-$(1)
-
-endef
-
-$(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call declare-test-art-host-run-test,$(test))))
-
-.PHONY: test-art-host-run-test-default
-test-art-host-run-test-default: $(TEST_ART_HOST_RUN_TEST_DEFAULT_TARGETS)
-	@echo test-art-host-run-test-default PASSED
-
-FAILING_OPTIMIZING_TESTS :=
-$(foreach test, $(FAILING_OPTIMIZING_TESTS), \
-	$(eval TEST_ART_HOST_RUN_TEST_OPTIMIZING_TARGETS := $(filter-out test-art-host-run-test-optimizing-$(test), $(TEST_ART_HOST_RUN_TEST_OPTIMIZING_TARGETS))))
-
-.PHONY: test-art-host-run-test-optimizing
-test-art-host-run-test-optimizing: $(TEST_ART_HOST_RUN_TEST_OPTIMIZING_TARGETS)
-	$(foreach test, $(FAILING_OPTIMIZING_TESTS), $(info Optimizing compiler has skipped $(test)))
-	@echo test-art-host-run-test-optimizing PASSED
-
-.PHONY: test-art-host-run-test-interpreter
-test-art-host-run-test-interpreter: $(TEST_ART_HOST_RUN_TEST_INTERPRETER_TARGETS)
-	@echo test-art-host-run-test-interpreter PASSED
-
-.PHONY: test-art-host-run-test
-test-art-host-run-test: test-art-host-run-test-default test-art-host-run-test-interpreter test-art-host-run-test-optimizing
-	@echo test-art-host-run-test PASSED
-
-########################################################################
-# target test targets
-
-# "mm test-art-target" to build and run all target tests
-define declare-test-art-target
-.PHONY: test-art-target$(1)
-test-art-target$(1): test-art-target-gtest$(1) test-art-target-oat$(1) test-art-target-run-test$(1)
-	@echo test-art-target$(1) PASSED
-endef
-$(eval $(call call-art-multi-target-rule,declare-test-art-target,test-art-target))
-
-define declare-test-art-target-dependencies
-.PHONY: test-art-target-dependencies$(1)
-test-art-target-dependencies$(1): $(ART_TARGET_TEST_DEPENDENCIES$(1)) $(ART_TARGET_LIBARTTEST_$(1))
-endef
-$(eval $(call call-art-multi-target-rule,declare-test-art-target-dependencies,test-art-target-dependencies))
-
-
-.PHONY: test-art-target-sync
-test-art-target-sync: test-art-target-dependencies$(ART_PHONY_TEST_TARGET_SUFFIX) test-art-target-dependencies$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
-	adb remount
-	adb sync
-	adb shell mkdir -p $(ART_TEST_DIR)
-
-
-define declare-test-art-target-gtest
-.PHONY: test-art-target-gtest$(1)
-test-art-target-gtest$(1): $(ART_TARGET_GTEST_TARGETS$(1))
-	@echo test-art-target-gtest$(1) PASSED
-endef
-$(eval $(call call-art-multi-target-rule,declare-test-art-target-gtest,test-art-target-gtest))
-
-
-define declare-test-art-target-oat
-.PHONY: test-art-target-oat$(1)
-test-art-target-oat$(1): $(ART_TEST_TARGET_OAT_TARGETS$(1))
-	@echo test-art-target-oat$(1) PASSED
-endef
-$(eval $(call call-art-multi-target-rule,declare-test-art-target-oat,test-art-target-oat))
-
-
-define declare-test-art-target-run-test-impl
-$(2)run_test_$(1) :=
-ifeq ($($(2)ART_PHONY_TEST_TARGET_SUFFIX),64)
- $(2)run_test_$(1) := --64
+.PHONY: test-art-host-interpreter$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+test-art-host-interpreter$(2ND_ART_PHONY_TEST_HOST_SUFFIX): test-art-host-oat-interpreter$(2ND_ART_PHONY_TEST_HOST_SUFFIX) \
+    test-art-host-run-test-interpreter$(2ND_ART_PHONY_TEST_HOST_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
 endif
-.PHONY: test-art-target-run-test-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
-test-art-target-run-test-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-sync $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
-	DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) art/test/run-test $(addprefix --runtime-option ,$(DALVIKVM_FLAGS)) $$($(2)run_test_$(1)) $(1)
-	@echo test-art-target-run-test-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX) PASSED
-endef
-
-define declare-test-art-target-run-test
-
-  ifdef TARGET_2ND_ARCH
-    $(call declare-test-art-target-run-test-impl,$(1),2ND_)
-    
-    TEST_ART_TARGET_RUN_TEST_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-run-test-$(1)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
-
-    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
-      # Link primary to non-suffix
-test-art-target-run-test-$(1): test-art-target-run-test-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
-    endif
-  endif
-  $(call declare-test-art-target-run-test-impl,$(1),)
-
-  TEST_ART_TARGET_RUN_TEST_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-run-test-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
-
-test-art-run-test-$(1): test-art-host-run-test-$(1) test-art-target-run-test-$(1)
-
-endef
-
-$(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call declare-test-art-target-run-test,$(test))))
-
-
-define declare-test-art-target-run-test
-.PHONY: test-art-target-run-test$(1)
-test-art-target-run-test$(1): $(TEST_ART_TARGET_RUN_TEST_TARGETS$(1))
-	@echo test-art-target-run-test$(1) PASSED
-endef
-$(eval $(call call-art-multi-target-rule,declare-test-art-target-run-test,test-art-target-run-test))
-
 
 ########################################################################
-# oat-target and oat-target-sync targets
+# target test rules
 
-OAT_TARGET_TARGETS :=
+# "mm test-art-target" to build and run all target tests.
+.PHONY: test-art-target
+test-art-target: test-art-target-gtest test-art-target-oat test-art-target-run-test
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# All target tests that run solely with the default compiler.
+.PHONY: test-art-target-default
+test-art-target-default: test-art-target-oat-default test-art-target-run-test-default
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# All target tests that run solely with the optimizing compiler.
+.PHONY: test-art-target-optimizing
+test-art-target-optimizing: test-art-target-oat-optimizing test-art-target-run-test-optimizing
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# All target tests that run solely on the interpreter.
+.PHONY: test-art-target-interpreter
+test-art-target-interpreter: test-art-target-oat-interpreter test-art-target-run-test-interpreter
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# Primary target architecture variants:
+.PHONY: test-art-target$(ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target$(ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-gtest$(ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-oat$(ART_PHONY_TEST_TARGET_SUFFIX) test-art-target-run-test$(ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+.PHONY: test-art-target-default$(ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target-default$(ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-oat-default$(ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-run-test-default$(ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+.PHONY: test-art-target-optimizing$(ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target-optimizing$(ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-oat-optimizing$(ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-run-test-optimizing$(ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+.PHONY: test-art-target-interpreter$(ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target-interpreter$(ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-oat-interpreter$(ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-run-test-interpreter$(ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+# Secondary target architecture variants:
+ifdef TARGET_2ND_ARCH
+.PHONY: test-art-target$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target$(2ND_ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-gtest$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-oat$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) test-art-target-run-test$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+.PHONY: test-art-target-default$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target-default$(2ND_ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-oat-default$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-run-test-default$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+.PHONY: test-art-target-optimizing$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target-optimizing$(2ND_ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-oat-optimizing$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-run-test-optimizing$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+
+.PHONY: test-art-target-interpreter$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+test-art-target-interpreter$(2ND_ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-oat-interpreter$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) \
+    test-art-target-run-test-interpreter$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+	$(hide) $(call ART_TEST_PREREQ_FINISHED,$@)
+endif
+
+########################################################################
+# oat-target and oat-target-sync rules
+
+OAT_TARGET_RULES :=
 
 # $(1): input jar or apk target location
 define declare-oat-target-target
@@ -365,7 +328,7 @@
 
 endif
 
-OAT_TARGET_TARGETS += oat-target-$(1)
+OAT_TARGET_RULES += oat-target-$(1)
 endef
 
 $(foreach file,\
@@ -375,7 +338,7 @@
   $(eval $(call declare-oat-target-target,$(subst $(PRODUCT_OUT)/,,$(file)))))
 
 .PHONY: oat-target
-oat-target: $(ART_TARGET_DEPENDENCIES) $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE) $(OAT_TARGET_TARGETS)
+oat-target: $(ART_TARGET_DEPENDENCIES) $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE) $(OAT_TARGET_RULES)
 
 .PHONY: oat-target-sync
 oat-target-sync: oat-target
@@ -396,73 +359,16 @@
 ########################################################################
 # "m art-host" for just building the files needed to run the art script
 .PHONY: art-host
-art-host:   $(HOST_OUT_EXECUTABLES)/art $(HOST_OUT)/bin/dalvikvm $(HOST_OUT)/lib/libart.so $(HOST_OUT)/bin/dex2oat $(HOST_CORE_IMG_OUT) $(HOST_OUT)/lib/libjavacore.so
+ifeq ($(HOST_PREFER_32_BIT),true)
+art-host:   $(HOST_OUT_EXECUTABLES)/art $(HOST_OUT)/bin/dalvikvm32 $(HOST_OUT)/lib/libart.so $(HOST_OUT)/bin/dex2oat $(HOST_CORE_IMG_OUT) $(HOST_OUT)/lib/libjavacore.so
+else
+art-host:   $(HOST_OUT_EXECUTABLES)/art $(HOST_OUT)/bin/dalvikvm64 $(HOST_OUT)/bin/dalvikvm32 $(HOST_OUT)/lib/libart.so $(HOST_OUT)/bin/dex2oat $(HOST_CORE_IMG_OUT) $(HOST_OUT)/lib/libjavacore.so
+endif
 
 .PHONY: art-host-debug
 art-host-debug:   art-host $(HOST_OUT)/lib/libartd.so $(HOST_OUT)/bin/dex2oatd
 
 ########################################################################
-# oatdump targets
-
-ART_DUMP_OAT_PATH ?= $(OUT_DIR)
-
-OATDUMP := $(HOST_OUT_EXECUTABLES)/oatdump$(HOST_EXECUTABLE_SUFFIX)
-OATDUMPD := $(HOST_OUT_EXECUTABLES)/oatdumpd$(HOST_EXECUTABLE_SUFFIX)
-# TODO: for now, override with debug version for better error reporting
-OATDUMP := $(OATDUMPD)
-
-.PHONY: dump-oat
-dump-oat: dump-oat-core dump-oat-boot
-
-.PHONY: dump-oat-core
-dump-oat-core: dump-oat-core-host dump-oat-core-target
-
-.PHONY: dump-oat-core-host
-ifeq ($(ART_BUILD_HOST),true)
-dump-oat-core-host: $(HOST_CORE_IMG_OUT) $(OATDUMP)
-	$(OATDUMP) --image=$(HOST_CORE_IMG_LOCATION) --output=$(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
-	@echo Output in $(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
-endif
-
-.PHONY: dump-oat-core-target
-ifeq ($(ART_BUILD_TARGET),true)
-dump-oat-core-target: $(TARGET_CORE_IMG_OUT) $(OATDUMP)
-	$(OATDUMP) --image=$(TARGET_CORE_IMG_LOCATION) --output=$(ART_DUMP_OAT_PATH)/core.target.oatdump.txt --instruction-set=$(TARGET_ARCH)
-	@echo Output in $(ART_DUMP_OAT_PATH)/core.target.oatdump.txt
-endif
-
-.PHONY: dump-oat-boot-$(TARGET_ARCH)
-ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
-dump-oat-boot-$(TARGET_ARCH): $(DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) $(OATDUMP)
-	$(OATDUMP) --image=$(DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION) --output=$(ART_DUMP_OAT_PATH)/boot.$(TARGET_ARCH).oatdump.txt --instruction-set=$(TARGET_ARCH)
-	@echo Output in $(ART_DUMP_OAT_PATH)/boot.$(TARGET_ARCH).oatdump.txt
-endif
-
-ifdef TARGET_2ND_ARCH
-dump-oat-boot-$(TARGET_2ND_ARCH): $(2ND_DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) $(OATDUMP)
-	$(OATDUMP) --image=$(2ND_DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION) --output=$(ART_DUMP_OAT_PATH)/boot.$(TARGET_2ND_ARCH).oatdump.txt --instruction-set=$(TARGET_2ND_ARCH)
-	@echo Output in $(ART_DUMP_OAT_PATH)/boot.$(TARGET_2ND_ARCH).oatdump.txt
-endif
-
-.PHONY: dump-oat-boot
-dump-oat-boot: dump-oat-boot-$(TARGET_ARCH)
-ifdef TARGET_2ND_ARCH
-dump-oat-boot: dump-oat-boot-$(TARGET_2ND_ARCH)
-endif
-
-.PHONY: dump-oat-Calculator
-ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
-dump-oat-Calculator: $(TARGET_OUT_APPS)/Calculator.odex $(DEFAULT_DEX_PREOPT_BUILT_IMAGE) $(OATDUMP)
-	$(OATDUMP) --oat-file=$< --output=$(ART_DUMP_OAT_PATH)/Calculator.oatdump.txt
-	@echo Output in $(ART_DUMP_OAT_PATH)/Calculator.oatdump.txt
-endif
-
-########################################################################
-# cpplint targets to style check art source files
-
-include $(art_build_path)/Android.cpplint.mk
-
-########################################################################
 # targets to switch back and forth from libdvm to libart
 
 .PHONY: use-art
diff --git a/build/Android.common.mk b/build/Android.common.mk
index f916e1e..4023336 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -17,156 +17,22 @@
 ifndef ANDROID_COMMON_MK
 ANDROID_COMMON_MK = true
 
-ART_SUPPORTED_ARCH := arm arm64 mips x86 x86_64
+ART_TARGET_SUPPORTED_ARCH := arm arm64 mips x86 x86_64
+ART_HOST_SUPPORTED_ARCH := x86 x86_64
 
-ifeq (,$(filter $(TARGET_ARCH),$(ART_SUPPORTED_ARCH)))
+ifeq (,$(filter $(TARGET_ARCH),$(ART_TARGET_SUPPORTED_ARCH)))
 $(warning unsupported TARGET_ARCH=$(TARGET_ARCH))
 endif
-
-# These can be overridden via the environment or by editing to
-# enable/disable certain build configuration.
-#
-# For example, to disable everything but the host debug build you use:
-#
-# (export ART_BUILD_TARGET_NDEBUG=false && export ART_BUILD_TARGET_DEBUG=false && export ART_BUILD_HOST_NDEBUG=false && ...)
-#
-# Beware that tests may use the non-debug build for performance, notable 055-enum-performance
-#
-ART_BUILD_TARGET_NDEBUG ?= true
-ART_BUILD_TARGET_DEBUG ?= true
-ART_BUILD_HOST_NDEBUG ?= true
-ART_BUILD_HOST_DEBUG ?= true
-
-ifeq ($(HOST_PREFER_32_BIT),true)
-ART_HOST_ARCH := $(HOST_2ND_ARCH)
-else
-ART_HOST_ARCH := $(HOST_ARCH)
+ifeq (,$(filter $(HOST_ARCH),$(ART_HOST_SUPPORTED_ARCH)))
+$(warning unsupported HOST_ARCH=$(HOST_ARCH))
 endif
 
-ifeq ($(ART_BUILD_TARGET_NDEBUG),false)
-$(info Disabling ART_BUILD_TARGET_NDEBUG)
-endif
-ifeq ($(ART_BUILD_TARGET_DEBUG),false)
-$(info Disabling ART_BUILD_TARGET_DEBUG)
-endif
-ifeq ($(ART_BUILD_HOST_NDEBUG),false)
-$(info Disabling ART_BUILD_HOST_NDEBUG)
-endif
-ifeq ($(ART_BUILD_HOST_DEBUG),false)
-$(info Disabling ART_BUILD_HOST_DEBUG)
-endif
-
-#
-# Used to enable smart mode
-#
-ART_SMALL_MODE := false
-ifneq ($(wildcard art/SMALL_ART),)
-$(info Enabling ART_SMALL_MODE because of existence of art/SMALL_ART)
-ART_SMALL_MODE := true
-endif
-ifeq ($(WITH_ART_SMALL_MODE), true)
-ART_SMALL_MODE := true
-endif
-
-#
-# Used to enable SEA mode
-#
-ART_SEA_IR_MODE := false
-ifneq ($(wildcard art/SEA_IR_ART),)
-$(info Enabling ART_SEA_IR_MODE because of existence of art/SEA_IR_ART)
-ART_SEA_IR_MODE := true
-endif
-ifeq ($(WITH_ART_SEA_IR_MODE), true)
-ART_SEA_IR_MODE := true
-endif
-
-#
-# Used to enable portable mode
-#
-ART_USE_PORTABLE_COMPILER := false
-ifneq ($(wildcard art/USE_PORTABLE_COMPILER),)
-$(info Enabling ART_USE_PORTABLE_COMPILER because of existence of art/USE_PORTABLE_COMPILER)
-ART_USE_PORTABLE_COMPILER := true
-endif
-ifeq ($(WITH_ART_USE_PORTABLE_COMPILER),true)
-$(info Enabling ART_USE_PORTABLE_COMPILER because WITH_ART_USE_PORTABLE_COMPILER=true)
-ART_USE_PORTABLE_COMPILER := true
-endif
-
-#
-# Used to enable optimizing compiler
-#
-ART_USE_OPTIMIZING_COMPILER := false
-ifneq ($(wildcard art/USE_OPTIMIZING_COMPILER),)
-$(info Enabling ART_USE_OPTIMIZING_COMPILER because of existence of art/USE_OPTIMIZING_COMPILER)
-ART_USE_OPTIMIZING_COMPILER := true
-endif
-ifeq ($(WITH_ART_USE_OPTIMIZING_COMPILER), true)
-ART_USE_OPTIMIZING_COMPILER := true
-endif
-
-ifeq ($(ART_USE_OPTIMIZING_COMPILER),true)
-DEX2OAT_FLAGS := --compiler-backend=Optimizing
-DALVIKVM_FLAGS += -Xcompiler-option --compiler-backend=Optimizing
-endif
-
-#
-# Used to change the default GC. Valid values are CMS, SS, GSS. The default is CMS.
-#
-ART_DEFAULT_GC_TYPE ?= CMS
-ART_DEFAULT_GC_TYPE_CFLAGS := -DART_DEFAULT_GC_TYPE_IS_$(ART_DEFAULT_GC_TYPE)
-
-ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-  LLVM_ROOT_PATH := external/llvm
-  # Don't fail a dalvik minimal host build.
-  -include $(LLVM_ROOT_PATH)/llvm.mk
-endif
-
-# Clang build support.
-
-# Host.
-ART_HOST_CLANG := false
-ifneq ($(WITHOUT_HOST_CLANG),true)
-  # By default, host builds use clang for better warnings.
-  ART_HOST_CLANG := true
-endif
-
-# Clang on the target: only enabled for ARM64. Target builds use GCC by default.
-ART_TARGET_CLANG :=
-ART_TARGET_CLANG_arm :=
-ART_TARGET_CLANG_arm64 :=
-ART_TARGET_CLANG_mips :=
-ART_TARGET_CLANG_x86 :=
-ART_TARGET_CLANG_x86_64 :=
-
-define set-target-local-clang-vars
-    LOCAL_CLANG := $(ART_TARGET_CLANG)
-    $(foreach arch,$(ART_SUPPORTED_ARCH),
-    	ifneq ($$(ART_TARGET_CLANG_$(arch)),)
-        LOCAL_CLANG_$(arch) := $$(ART_TARGET_CLANG_$(arch))
-      endif)
-endef
-
-# directory used for dalvik-cache on device
-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
-
-# directory used for oat tests on device
-ART_TEST_DIR := /data/art-test
-ART_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 :=
+TARGET_INSTRUCTION_SET_FEATURES := $(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+2ND_TARGET_INSTRUCTION_SET_FEATURES := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
 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_ARCH_32 := $(TARGET_2ND_ARCH)
@@ -176,268 +42,32 @@
     $(error Do not know what to do with this multi-target configuration!)
   endif
 else
+  ART_PHONY_TEST_TARGET_SUFFIX := 32
+  2ND_ART_PHONY_TEST_TARGET_SUFFIX :=
   ART_TARGET_ARCH_32 := $(TARGET_ARCH)
   ART_TARGET_ARCH_64 :=
 endif
 
-ART_CPP_EXTENSION := .cc
-
-ART_HOST_SHLIB_EXTENSION := $(HOST_SHLIB_SUFFIX)
-ART_HOST_SHLIB_EXTENSION ?= .so
-
-ART_C_INCLUDES := \
-	external/gtest/include \
-	external/valgrind/main/include \
-	external/valgrind/main \
-	external/vixl/src \
-	external/zlib \
-	frameworks/compile/mclinker/include
-
-art_cflags := \
-	-fno-rtti \
-	-std=gnu++11 \
-	-ggdb3 \
-	-Wall \
-	-Werror \
-	-Wextra \
-	-Wno-sign-promo \
-	-Wno-unused-parameter \
-	-Wstrict-aliasing \
-	-fstrict-aliasing
-
-ART_TARGET_CLANG_CFLAGS :=
-ART_TARGET_CLANG_CFLAGS_arm :=
-ART_TARGET_CLANG_CFLAGS_arm64 :=
-ART_TARGET_CLANG_CFLAGS_mips :=
-ART_TARGET_CLANG_CFLAGS_x86 :=
-ART_TARGET_CLANG_CFLAGS_x86_64 :=
-
-# these are necessary for Clang ARM64 ART builds
-ART_TARGET_CLANG_CFLAGS_arm64  += \
-	-Wno-implicit-exception-spec-mismatch \
-	-DNVALGRIND \
-	-Wno-unused-value
-
-ifeq ($(ART_SMALL_MODE),true)
-  art_cflags += -DART_SMALL_MODE=1
-endif
-
-ifeq ($(ART_SEA_IR_MODE),true)
-  art_cflags += -DART_SEA_IR_MODE=1
-endif
-
-art_non_debug_cflags := \
-	-O3
-
-ifeq ($(HOST_OS),linux)
-  art_non_debug_cflags += \
-	-Wframe-larger-than=1728
-endif
-
-# FIXME: upstream LLVM has a vectorizer bug that needs to be fixed
-ART_TARGET_CLANG_CFLAGS_arm64 += \
-	-fno-vectorize
-
-art_debug_cflags := \
-	-O1 \
-	-DDYNAMIC_ANNOTATIONS_ENABLED=1 \
-	-UNDEBUG
-
-ART_HOST_CFLAGS := $(art_cflags) -DANDROID_SMP=1 -DART_BASE_ADDRESS=$(LIBART_IMG_HOST_BASE_ADDRESS)
-ART_HOST_CFLAGS += -DART_DEFAULT_INSTRUCTION_SET_FEATURES=default
-ART_HOST_CFLAGS += $(ART_DEFAULT_GC_TYPE_CFLAGS)
-
-ART_TARGET_CFLAGS := $(art_cflags) -DART_TARGET -DART_BASE_ADDRESS=$(LIBART_IMG_TARGET_BASE_ADDRESS)
-ifeq ($(TARGET_CPU_SMP),true)
-  ART_TARGET_CFLAGS += -DANDROID_SMP=1
+ifeq ($(HOST_PREFER_32_BIT),true)
+  ART_PHONY_TEST_HOST_SUFFIX := 32
+  2ND_ART_PHONY_TEST_HOST_SUFFIX :=
+  ART_HOST_ARCH_32 := x86
+  ART_HOST_ARCH_64 :=
+  ART_HOST_ARCH := x86
+  2ND_ART_HOST_ARCH :=
+  2ND_HOST_ARCH :=
+  ART_HOST_OUT_SHARED_LIBRARIES := $(2ND_HOST_OUT_SHARED_LIBRARIES)
+  2ND_ART_HOST_OUT_SHARED_LIBRARIES :=
 else
-  ifeq ($(TARGET_CPU_SMP),false)
-    ART_TARGET_CFLAGS += -DANDROID_SMP=0
-  else
-    $(warning TARGET_CPU_SMP should be (true|false), found $(TARGET_CPU_SMP))
-    # Make sure we emit barriers for the worst case.
-    ART_TARGET_CFLAGS += -DANDROID_SMP=1
-  endif
+  ART_PHONY_TEST_HOST_SUFFIX := 64
+  2ND_ART_PHONY_TEST_HOST_SUFFIX := 32
+  ART_HOST_ARCH_32 := x86
+  ART_HOST_ARCH_64 := x86_64
+  ART_HOST_ARCH := x86_64
+  2ND_ART_HOST_ARCH := x86
+  2ND_HOST_ARCH := x86
+  ART_HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT_SHARED_LIBRARIES)
+  2ND_ART_HOST_OUT_SHARED_LIBRARIES := $(2ND_HOST_OUT_SHARED_LIBRARIES)
 endif
-ART_TARGET_CFLAGS += $(ART_DEFAULT_GC_TYPE_CFLAGS)
-
-# DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES is set in ../build/core/dex_preopt.mk based on
-# the TARGET_CPU_VARIANT
-ifeq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
-$(error Required DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES is not set)
-endif
-ART_TARGET_CFLAGS += -DART_DEFAULT_INSTRUCTION_SET_FEATURES=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
-
-# Enable thread-safety for GCC 4.6, and clang, but not for GCC 4.7 or later where this feature was
-# removed. Warn when -Wthread-safety is not used.
-ifneq ($(filter 4.6 4.6.%, $(TARGET_GCC_VERSION)),)
-  ART_TARGET_CFLAGS += -Wthread-safety
-else
-  # FIXME: add -Wthread-safety when the problem is fixed
-  ifeq ($(ART_TARGET_CLANG),true)
-    ART_TARGET_CFLAGS +=
-  else
-    # Warn if -Wthread-safety is not suport and not doing a top-level or 'mma' build.
-    ifneq ($(ONE_SHOT_MAKEFILE),)
-      # Enable target GCC 4.6 with: export TARGET_GCC_VERSION_EXP=4.6
-      $(info Using target GCC $(TARGET_GCC_VERSION) disables thread-safety checks.)
-    endif
-  endif
-endif
-# We compile with GCC 4.6 or clang on the host, both of which support -Wthread-safety.
-ART_HOST_CFLAGS += -Wthread-safety
-
-# To use oprofile_android --callgraph, uncomment this and recompile with "mmm art -B -j16"
-# ART_TARGET_CFLAGS += -fno-omit-frame-pointer -marm -mapcs
-
-# Addition CPU specific CFLAGS.
-ifeq ($(TARGET_ARCH),arm)
-  ifneq ($(filter cortex-a15, $(TARGET_CPU_VARIANT)),)
-    # Fake a ARM feature for LPAE support.
-    ART_TARGET_CFLAGS += -D__ARM_FEATURE_LPAE=1
-  endif
-endif
-
-ART_HOST_NON_DEBUG_CFLAGS := $(art_non_debug_cflags)
-ART_TARGET_NON_DEBUG_CFLAGS := $(art_non_debug_cflags)
-
-# TODO: move -fkeep-inline-functions to art_debug_cflags when target gcc > 4.4 (and -lsupc++)
-ART_HOST_DEBUG_CFLAGS := $(art_debug_cflags) -fkeep-inline-functions
-ART_HOST_DEBUG_LDLIBS := -lsupc++
-
-ifneq ($(HOST_OS),linux)
-  # Some Mac OS pthread header files are broken with -fkeep-inline-functions.
-  ART_HOST_DEBUG_CFLAGS := $(filter-out -fkeep-inline-functions,$(ART_HOST_DEBUG_CFLAGS))
-  # Mac OS doesn't have libsupc++.
-  ART_HOST_DEBUG_LDLIBS := $(filter-out -lsupc++,$(ART_HOST_DEBUG_LDLIBS))
-endif
-
-ART_TARGET_DEBUG_CFLAGS := $(art_debug_cflags)
-
-# $(1): ndebug_or_debug
-define set-target-local-cflags-vars
-    LOCAL_CFLAGS += $(ART_TARGET_CFLAGS)
-    LOCAL_CFLAGS_x86 += $(ART_TARGET_CFLAGS_x86)
-    art_target_cflags_ndebug_or_debug := $(1)
-    ifeq ($$(art_target_cflags_ndebug_or_debug),debug)
-      LOCAL_CFLAGS += $(ART_TARGET_DEBUG_CFLAGS)
-    else
-      LOCAL_CFLAGS += $(ART_TARGET_NON_DEBUG_CFLAGS)
-    endif
-
-    # TODO: Also set when ART_TARGET_CLANG_$(arch)!=false and ART_TARGET_CLANG==true
-    $(foreach arch,$(ART_SUPPORTED_ARCH),
-    	ifeq ($$(ART_TARGET_CLANG_$(arch)),true)
-        LOCAL_CFLAGS_$(arch) += $$(ART_TARGET_CLANG_CFLAGS_$(arch))
-      endif)
-endef
-
-ART_BUILD_TARGET := false
-ART_BUILD_HOST := false
-ART_BUILD_NDEBUG := false
-ART_BUILD_DEBUG := false
-ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
-  ART_BUILD_TARGET := true
-  ART_BUILD_NDEBUG := true
-endif
-ifeq ($(ART_BUILD_TARGET_DEBUG),true)
-  ART_BUILD_TARGET := true
-  ART_BUILD_DEBUG := true
-endif
-ifeq ($(ART_BUILD_HOST_NDEBUG),true)
-  ART_BUILD_HOST := true
-  ART_BUILD_NDEBUG := true
-endif
-ifeq ($(ART_BUILD_HOST_DEBUG),true)
-  ART_BUILD_HOST := true
-  ART_BUILD_DEBUG := true
-endif
-
-# Helper function to call a function twice with a target suffix
-# $(1): The generator function for the rules
-#         Has one argument, the suffix
-define call-art-multi-target
-  $(call $(1),$(ART_PHONY_TEST_TARGET_SUFFIX))
-
-  ifdef TARGET_2ND_ARCH
-    $(call $(1),$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
-  endif
-endef
-
-# Helper function to combine two variables with suffixes together.
-# $(1): The base name.
-define combine-art-multi-target-var
-  ifdef TARGET_2ND_ARCH
-    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
-      ifneq ($(2ND_ART_PHONY_TEST_TARGET_SUFFIX),)
-$(1) := $($(1)$(ART_PHONY_TEST_TARGET_SUFFIX)) $($(1)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
-      endif
-    endif
-  endif
-endef
-
-
-# Helper function to define a variable twice with a target suffix. Assume the name generated is
-# derived from $(2) so we can create a combined var.
-# $(1): The generator function for the rules
-#         Has one argument, the suffix
-define call-art-multi-target-var
-  $(call $(1),$(ART_PHONY_TEST_TARGET_SUFFIX))
-
-  ifdef TARGET_2ND_ARCH
-    $(call $(1),$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
-
-    # Link both together, if it makes sense
-    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
-      ifneq ($(2ND_ART_PHONY_TEST_TARGET_SUFFIX),)
-$(2) := $(2)$(ART_PHONY_TEST_TARGET_SUFFIX) $(2)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
-      endif
-    endif
-
-  endif
-endef
-
-# Helper function to call a function twice with a target suffix. Assume it generates make rules
-# with the given name, and link them.
-# $(1): The generator function for the rules
-#         Has one argument, the suffix
-# $(2): The base rule name, necessary for the link
-#       We assume we can link the names together easily...
-define call-art-multi-target-rule
-  $(call $(1),$(ART_PHONY_TEST_TARGET_SUFFIX))
-
-  ifdef TARGET_2ND_ARCH
-    $(call $(1),$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
-
-    # Link both together, if it makes sense
-    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
-      ifneq ($(2ND_ART_PHONY_TEST_TARGET_SUFFIX),)
-.PHONY: $(2)
-$(2): $(2)$(ART_PHONY_TEST_TARGET_SUFFIX) $(2)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
-      endif
-    endif
-  endif
-endef
-
-HOST_CORE_OAT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.oat
-TARGET_CORE_OAT := $(ART_TEST_DIR)/$(DEX2OAT_TARGET_ARCH)/core.oat
-ifdef TARGET_2ND_ARCH
-2ND_TARGET_CORE_OAT := $(2ND_ART_TEST_DIR)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.oat
-endif
-
-HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.oat
-TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/$(DEX2OAT_TARGET_ARCH)/core.oat
-ifdef TARGET_2ND_ARCH
-2ND_TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.oat
-endif
-
-HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.art
-TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/$(DEX2OAT_TARGET_ARCH)/core.art
-ifdef TARGET_2ND_ARCH
-2ND_TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.art
-endif
-
-HOST_CORE_IMG_LOCATION := $(HOST_OUT_JAVA_LIBRARIES)/core.art
-TARGET_CORE_IMG_LOCATION := $(ART_TEST_OUT)/core.art
 
 endif # ANDROID_COMMON_MK
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
new file mode 100644
index 0000000..90609ec
--- /dev/null
+++ b/build/Android.common_build.mk
@@ -0,0 +1,326 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifndef ANDROID_COMMON_BUILD_MK
+ANDROID_COMMON_BUILD_MK = true
+
+include art/build/Android.common.mk
+
+# These can be overridden via the environment or by editing to
+# enable/disable certain build configuration.
+#
+# For example, to disable everything but the host debug build you use:
+#
+# (export ART_BUILD_TARGET_NDEBUG=false && export ART_BUILD_TARGET_DEBUG=false && export ART_BUILD_HOST_NDEBUG=false && ...)
+#
+# Beware that tests may use the non-debug build for performance, notable 055-enum-performance
+#
+ART_BUILD_TARGET_NDEBUG ?= true
+ART_BUILD_TARGET_DEBUG ?= true
+ART_BUILD_HOST_NDEBUG ?= true
+ART_BUILD_HOST_DEBUG ?= true
+
+ifeq ($(ART_BUILD_TARGET_NDEBUG),false)
+$(info Disabling ART_BUILD_TARGET_NDEBUG)
+endif
+ifeq ($(ART_BUILD_TARGET_DEBUG),false)
+$(info Disabling ART_BUILD_TARGET_DEBUG)
+endif
+ifeq ($(ART_BUILD_HOST_NDEBUG),false)
+$(info Disabling ART_BUILD_HOST_NDEBUG)
+endif
+ifeq ($(ART_BUILD_HOST_DEBUG),false)
+$(info Disabling ART_BUILD_HOST_DEBUG)
+endif
+
+#
+# Used to enable smart mode
+#
+ART_SMALL_MODE := false
+ifneq ($(wildcard art/SMALL_ART),)
+$(info Enabling ART_SMALL_MODE because of existence of art/SMALL_ART)
+ART_SMALL_MODE := true
+endif
+ifeq ($(WITH_ART_SMALL_MODE), true)
+ART_SMALL_MODE := true
+endif
+
+#
+# Used to enable SEA mode
+#
+ART_SEA_IR_MODE := false
+ifneq ($(wildcard art/SEA_IR_ART),)
+$(info Enabling ART_SEA_IR_MODE because of existence of art/SEA_IR_ART)
+ART_SEA_IR_MODE := true
+endif
+ifeq ($(WITH_ART_SEA_IR_MODE), true)
+ART_SEA_IR_MODE := true
+endif
+
+#
+# Used to enable portable mode
+#
+ART_USE_PORTABLE_COMPILER := false
+ifneq ($(wildcard art/USE_PORTABLE_COMPILER),)
+$(info Enabling ART_USE_PORTABLE_COMPILER because of existence of art/USE_PORTABLE_COMPILER)
+ART_USE_PORTABLE_COMPILER := true
+endif
+ifeq ($(WITH_ART_USE_PORTABLE_COMPILER),true)
+$(info Enabling ART_USE_PORTABLE_COMPILER because WITH_ART_USE_PORTABLE_COMPILER=true)
+ART_USE_PORTABLE_COMPILER := true
+endif
+
+#
+# Used to enable optimizing compiler
+#
+ART_USE_OPTIMIZING_COMPILER := false
+ifneq ($(wildcard art/USE_OPTIMIZING_COMPILER),)
+$(info Enabling ART_USE_OPTIMIZING_COMPILER because of existence of art/USE_OPTIMIZING_COMPILER)
+ART_USE_OPTIMIZING_COMPILER := true
+endif
+ifeq ($(WITH_ART_USE_OPTIMIZING_COMPILER), true)
+ART_USE_OPTIMIZING_COMPILER := true
+endif
+
+ifeq ($(ART_USE_OPTIMIZING_COMPILER),true)
+DEX2OAT_FLAGS := --compiler-backend=Optimizing
+DALVIKVM_FLAGS += -Xcompiler-option --compiler-backend=Optimizing
+endif
+
+#
+# Used to change the default GC. Valid values are CMS, SS, GSS. The default is CMS.
+#
+ART_DEFAULT_GC_TYPE ?= CMS
+ART_DEFAULT_GC_TYPE_CFLAGS := -DART_DEFAULT_GC_TYPE_IS_$(ART_DEFAULT_GC_TYPE)
+
+ifeq ($(ART_USE_PORTABLE_COMPILER),true)
+  LLVM_ROOT_PATH := external/llvm
+  # Don't fail a dalvik minimal host build.
+  -include $(LLVM_ROOT_PATH)/llvm.mk
+endif
+
+# Clang build support.
+
+# Host.
+ART_HOST_CLANG := false
+ifneq ($(WITHOUT_HOST_CLANG),true)
+  # By default, host builds use clang for better warnings.
+  ART_HOST_CLANG := true
+endif
+
+# Clang on the target: only enabled for ARM64. Target builds use GCC by default.
+ART_TARGET_CLANG :=
+ART_TARGET_CLANG_arm :=
+ART_TARGET_CLANG_arm64 := true
+ART_TARGET_CLANG_mips :=
+ART_TARGET_CLANG_x86 :=
+ART_TARGET_CLANG_x86_64 :=
+
+define set-target-local-clang-vars
+    LOCAL_CLANG := $(ART_TARGET_CLANG)
+    $(foreach arch,$(ART_TARGET_SUPPORTED_ARCH),
+      ifneq ($$(ART_TARGET_CLANG_$(arch)),)
+        LOCAL_CLANG_$(arch) := $$(ART_TARGET_CLANG_$(arch))
+      endif)
+endef
+
+ART_CPP_EXTENSION := .cc
+
+ART_HOST_SHLIB_EXTENSION := $(HOST_SHLIB_SUFFIX)
+ART_HOST_SHLIB_EXTENSION ?= .so
+
+ART_C_INCLUDES := \
+  external/gtest/include \
+  external/valgrind/main/include \
+  external/valgrind/main \
+  external/vixl/src \
+  external/zlib \
+  frameworks/compile/mclinker/include
+
+art_cflags := \
+  -fno-rtti \
+  -std=gnu++11 \
+  -ggdb3 \
+  -Wall \
+  -Werror \
+  -Wextra \
+  -Wno-sign-promo \
+  -Wno-unused-parameter \
+  -Wstrict-aliasing \
+  -fstrict-aliasing
+
+ART_TARGET_CLANG_CFLAGS :=
+ART_TARGET_CLANG_CFLAGS_arm :=
+ART_TARGET_CLANG_CFLAGS_arm64 :=
+ART_TARGET_CLANG_CFLAGS_mips :=
+ART_TARGET_CLANG_CFLAGS_x86 :=
+ART_TARGET_CLANG_CFLAGS_x86_64 :=
+
+# these are necessary for Clang ARM64 ART builds
+ART_TARGET_CLANG_CFLAGS_arm64  += \
+  -Wno-implicit-exception-spec-mismatch \
+  -DNVALGRIND \
+  -Wno-unused-value
+
+ifeq ($(ART_SMALL_MODE),true)
+  art_cflags += -DART_SMALL_MODE=1
+endif
+
+ifeq ($(ART_SEA_IR_MODE),true)
+  art_cflags += -DART_SEA_IR_MODE=1
+endif
+
+art_non_debug_cflags := \
+  -O3
+
+ifeq ($(HOST_OS),linux)
+  art_non_debug_cflags += -Wframe-larger-than=1728
+endif
+
+# FIXME: upstream LLVM has a vectorizer bug that needs to be fixed
+ART_TARGET_CLANG_CFLAGS_arm64 += \
+  -fno-vectorize
+
+art_debug_cflags := \
+  -O1 \
+  -DDYNAMIC_ANNOTATIONS_ENABLED=1 \
+  -UNDEBUG
+
+ifndef LIBART_IMG_HOST_BASE_ADDRESS
+  $(error LIBART_IMG_HOST_BASE_ADDRESS unset)
+endif
+ART_HOST_CFLAGS := $(art_cflags) -DANDROID_SMP=1 -DART_BASE_ADDRESS=$(LIBART_IMG_HOST_BASE_ADDRESS)
+ART_HOST_CFLAGS += -DART_DEFAULT_INSTRUCTION_SET_FEATURES=default
+ART_HOST_CFLAGS += $(ART_DEFAULT_GC_TYPE_CFLAGS)
+
+ifndef LIBART_IMG_TARGET_BASE_ADDRESS
+  $(error LIBART_IMG_TARGET_BASE_ADDRESS unset)
+endif
+ART_TARGET_CFLAGS := $(art_cflags) -DART_TARGET -DART_BASE_ADDRESS=$(LIBART_IMG_TARGET_BASE_ADDRESS)
+ifeq ($(TARGET_CPU_SMP),true)
+  ART_TARGET_CFLAGS += -DANDROID_SMP=1
+else
+  ifeq ($(TARGET_CPU_SMP),false)
+    ART_TARGET_CFLAGS += -DANDROID_SMP=0
+  else
+    $(warning TARGET_CPU_SMP should be (true|false), found $(TARGET_CPU_SMP))
+    # Make sure we emit barriers for the worst case.
+    ART_TARGET_CFLAGS += -DANDROID_SMP=1
+  endif
+endif
+ART_TARGET_CFLAGS += $(ART_DEFAULT_GC_TYPE_CFLAGS)
+
+# DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES is set in ../build/core/dex_preopt.mk based on
+# the TARGET_CPU_VARIANT
+ifeq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
+$(error Required DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES is not set)
+endif
+ART_TARGET_CFLAGS += -DART_DEFAULT_INSTRUCTION_SET_FEATURES=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+
+# Enable thread-safety for GCC 4.6, and clang, but not for GCC 4.7 or later where this feature was
+# removed. Warn when -Wthread-safety is not used.
+ifneq ($(filter 4.6 4.6.%, $(TARGET_GCC_VERSION)),)
+  ART_TARGET_CFLAGS += -Wthread-safety
+else
+  # FIXME: add -Wthread-safety when the problem is fixed
+  ifeq ($(ART_TARGET_CLANG),true)
+    ART_TARGET_CFLAGS +=
+  else
+    # Warn if -Wthread-safety is not supported and not doing a top-level or 'mma' build.
+    ifneq ($(ONE_SHOT_MAKEFILE),)
+      # Enable target GCC 4.6 with: export TARGET_GCC_VERSION_EXP=4.6
+      $(info Using target GCC $(TARGET_GCC_VERSION) disables thread-safety checks.)
+    endif
+  endif
+endif
+# We compile with GCC 4.6 or clang on the host, both of which support -Wthread-safety.
+ART_HOST_CFLAGS += -Wthread-safety
+
+# To use oprofile_android --callgraph, uncomment this and recompile with "mmm art -B -j16"
+# ART_TARGET_CFLAGS += -fno-omit-frame-pointer -marm -mapcs
+
+# Addition CPU specific CFLAGS.
+ifeq ($(TARGET_ARCH),arm)
+  ifneq ($(filter cortex-a15, $(TARGET_CPU_VARIANT)),)
+    # Fake a ARM feature for LPAE support.
+    ART_TARGET_CFLAGS += -D__ARM_FEATURE_LPAE=1
+  endif
+endif
+
+ART_HOST_NON_DEBUG_CFLAGS := $(art_non_debug_cflags)
+ART_TARGET_NON_DEBUG_CFLAGS := $(art_non_debug_cflags)
+
+# TODO: move -fkeep-inline-functions to art_debug_cflags when target gcc > 4.4 (and -lsupc++)
+ART_HOST_DEBUG_CFLAGS := $(art_debug_cflags) -fkeep-inline-functions
+ART_HOST_DEBUG_LDLIBS := -lsupc++
+
+ifneq ($(HOST_OS),linux)
+  # Some Mac OS pthread header files are broken with -fkeep-inline-functions.
+  ART_HOST_DEBUG_CFLAGS := $(filter-out -fkeep-inline-functions,$(ART_HOST_DEBUG_CFLAGS))
+  # Mac OS doesn't have libsupc++.
+  ART_HOST_DEBUG_LDLIBS := $(filter-out -lsupc++,$(ART_HOST_DEBUG_LDLIBS))
+endif
+
+ART_TARGET_DEBUG_CFLAGS := $(art_debug_cflags)
+
+# $(1): ndebug_or_debug
+define set-target-local-cflags-vars
+  LOCAL_CFLAGS += $(ART_TARGET_CFLAGS)
+  LOCAL_CFLAGS_x86 += $(ART_TARGET_CFLAGS_x86)
+  art_target_cflags_ndebug_or_debug := $(1)
+  ifeq ($$(art_target_cflags_ndebug_or_debug),debug)
+    LOCAL_CFLAGS += $(ART_TARGET_DEBUG_CFLAGS)
+  else
+    LOCAL_CFLAGS += $(ART_TARGET_NON_DEBUG_CFLAGS)
+  endif
+
+  # TODO: Also set when ART_TARGET_CLANG_$(arch)!=false and ART_TARGET_CLANG==true
+  $(foreach arch,$(ART_SUPPORTED_ARCH),
+    ifeq ($$(ART_TARGET_CLANG_$(arch)),true)
+      LOCAL_CFLAGS_$(arch) += $$(ART_TARGET_CLANG_CFLAGS_$(arch))
+  endif)
+
+  # Clear locally used variables.
+  art_target_cflags_ndebug_or_debug :=
+endef
+
+ART_BUILD_TARGET := false
+ART_BUILD_HOST := false
+ART_BUILD_NDEBUG := false
+ART_BUILD_DEBUG := false
+ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+  ART_BUILD_TARGET := true
+  ART_BUILD_NDEBUG := true
+endif
+ifeq ($(ART_BUILD_TARGET_DEBUG),true)
+  ART_BUILD_TARGET := true
+  ART_BUILD_DEBUG := true
+endif
+ifeq ($(ART_BUILD_HOST_NDEBUG),true)
+  ART_BUILD_HOST := true
+  ART_BUILD_NDEBUG := true
+endif
+ifeq ($(ART_BUILD_HOST_DEBUG),true)
+  ART_BUILD_HOST := true
+  ART_BUILD_DEBUG := true
+endif
+
+# Clear locally defined variables that aren't necessary in the rest of the build system.
+ART_DEFAULT_GC_TYPE :=
+ART_DEFAULT_GC_TYPE_CFLAGS :=
+art_cflags :=
+
+endif # ANDROID_COMMON_BUILD_MK
diff --git a/build/Android.common_path.mk b/build/Android.common_path.mk
new file mode 100644
index 0000000..d672393
--- /dev/null
+++ b/build/Android.common_path.mk
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifndef ANDROID_COMMON_PATH_MK
+ANDROID_COMMON_PATH_MK := true
+
+include art/build/Android.common.mk
+
+# Directory used for dalvik-cache on device.
+ART_TARGET_DALVIK_CACHE_DIR := /data/dalvik-cache
+
+# Directory used for gtests on device.
+ART_TARGET_NATIVETEST_DIR := /data/nativetest/art
+ART_TARGET_NATIVETEST_OUT := $(TARGET_OUT_DATA_NATIVE_TESTS)/art
+
+# Directory used for oat tests on device.
+ART_TARGET_TEST_DIR := /data/art-test
+ART_TARGET_TEST_OUT := $(TARGET_OUT_DATA)/art-test
+
+# Directory used for temporary test files on the host.
+ART_HOST_TEST_DIR := /tmp/test-art-$(shell echo $$PPID)
+
+# Core.oat location on the device.
+TARGET_CORE_OAT := $(ART_TARGET_TEST_DIR)/$(DEX2OAT_TARGET_ARCH)/core.oat
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_CORE_OAT := $(ART_TARGET_TEST_DIR)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.oat
+endif
+
+# Core.oat locations under the out directory.
+HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.oat
+ifneq ($(HOST_PREFER_32_BIT),true)
+2ND_HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(2ND_ART_HOST_ARCH)/core.oat
+endif
+TARGET_CORE_OAT_OUT := $(ART_TARGET_TEST_OUT)/$(DEX2OAT_TARGET_ARCH)/core.oat
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_CORE_OAT_OUT := $(ART_TARGET_TEST_OUT)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.oat
+endif
+
+# Core.art locations under the out directory.
+HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.art
+ifneq ($(HOST_PREFER_32_BIT),true)
+2ND_HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(2ND_ART_HOST_ARCH)/core.art
+endif
+TARGET_CORE_IMG_OUT := $(ART_TARGET_TEST_OUT)/$(DEX2OAT_TARGET_ARCH)/core.art
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_CORE_IMG_OUT := $(ART_TARGET_TEST_OUT)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.art
+endif
+
+# Oat location of core.art.
+HOST_CORE_IMG_LOCATION := $(HOST_OUT_JAVA_LIBRARIES)/core.art
+TARGET_CORE_IMG_LOCATION := $(ART_TARGET_TEST_OUT)/core.art
+
+# Jar files for core.art.
+TARGET_CORE_JARS := core-libart conscrypt okhttp core-junit bouncycastle
+HOST_CORE_JARS := $(addsuffix -hostdex,$(TARGET_CORE_JARS))
+
+HOST_CORE_DEX_LOCATIONS   := $(foreach jar,$(HOST_CORE_JARS),  $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
+TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_CORE_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
+
+HOST_CORE_DEX_FILES   := $(foreach jar,$(HOST_CORE_JARS),  $(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),t,COMMON)/javalib.jar)
+TARGET_CORE_DEX_FILES := $(foreach jar,$(TARGET_CORE_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar), ,COMMON)/javalib.jar)
+
+endif # ANDROID_COMMON_PATH_MK
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
new file mode 100644
index 0000000..1815f50
--- /dev/null
+++ b/build/Android.common_test.mk
@@ -0,0 +1,117 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifndef ANDROID_COMMON_TEST_MK
+ANDROID_COMMON_TEST_MK = true
+
+include art/build/Android.common_path.mk
+
+# List of known broken tests that we won't attempt to execute. The test name must be the full
+# rule name such as test-art-host-oat-optimizing-HelloWorld64.
+ART_TEST_KNOWN_BROKEN :=
+
+# List of known failing tests that when executed won't cause test execution to finish. The test name
+# must be the full rule name such as test-art-host-oat-optimizing-HelloWorld64.
+ART_TEST_KNOWN_FAILING := $(ART_TEST_KNOWN_BROKEN)
+
+# Keep going after encountering a test failure?
+ART_TEST_KEEP_GOING ?= false
+
+# Define the command run on test failure. $(1) is the name of the test. Executed by the shell.
+define ART_TEST_FAILED
+  ( [ -f $(ART_HOST_TEST_DIR)/skipped/$(1) ] || \
+    (mkdir -p $(ART_HOST_TEST_DIR)/failed/ && touch $(ART_HOST_TEST_DIR)/failed/$(1) && \
+      echo $(ART_TEST_KNOWN_FAILING) | grep -q $(1) \
+        && (echo -e "$(1) \e[91mKNOWN FAILURE\e[0m") \
+        || (echo -e "$(1) \e[91mFAILED\e[0m")))
+endef
+
+# Define the command run on test success. $(1) is the name of the test. Executed by the shell.
+# The command checks prints "PASSED" then checks to see if this was a top-level make target (e.g.
+# "mm test-art-host-oat-HelloWorld32"), if it was then it does nothing, otherwise it creates a file
+# to be printed in the passing test summary.
+define ART_TEST_PASSED
+  ( echo -e "$(1) \e[92mPASSED\e[0m" && \
+    (echo $(MAKECMDGOALS) | grep -q $(1) || \
+      (mkdir -p $(ART_HOST_TEST_DIR)/passed/ && touch $(ART_HOST_TEST_DIR)/passed/$(1))))
+endef
+
+# Define the command run on test success of multiple prerequisites. $(1) is the name of the test.
+# When the test is a top-level make target then a summary of the ran tests is produced. Executed by
+# the shell.
+define ART_TEST_PREREQ_FINISHED
+  (echo -e "$(1) \e[32mCOMPLETE\e[0m" && \
+    (echo $(MAKECMDGOALS) | grep -q -v $(1) || \
+      (([ -d $(ART_HOST_TEST_DIR)/passed/ ] \
+        && (echo -e "\e[92mPASSING TESTS\e[0m" && ls -1 $(ART_HOST_TEST_DIR)/passed/) \
+        || (echo -e "\e[91mNO TESTS PASSED\e[0m")) && \
+      ([ -d $(ART_HOST_TEST_DIR)/skipped/ ] \
+        && (echo -e "\e[93mSKIPPED TESTS\e[0m" && ls -1 $(ART_HOST_TEST_DIR)/skipped/) \
+        || (echo -e "\e[92mNO TESTS SKIPPED\e[0m")) && \
+      ([ -d $(ART_HOST_TEST_DIR)/failed/ ] \
+        && (echo -e "\e[91mFAILING TESTS\e[0m" && ls -1 $(ART_HOST_TEST_DIR)/failed/) \
+        || (echo -e "\e[92mNO TESTS FAILED\e[0m")) \
+      && ([ ! -d $(ART_HOST_TEST_DIR)/failed/ ] && rm -r $(ART_HOST_TEST_DIR) \
+          || (rm -r $(ART_HOST_TEST_DIR) && false)))))
+endef
+
+# Define the command executed by the shell ahead of running an art test. $(1) is the name of the
+# test.
+define ART_TEST_SKIP
+  ((echo $(ART_TEST_KNOWN_BROKEN) | grep -q -v $(1) \
+     && ([ ! -d $(ART_HOST_TEST_DIR)/failed/ ] || [ $(ART_TEST_KEEP_GOING) = true ])\
+     && echo -e "$(1) \e[95mRUNNING\e[0m") \
+   || ((mkdir -p $(ART_HOST_TEST_DIR)/skipped/ && touch $(ART_HOST_TEST_DIR)/skipped/$(1) \
+     && ([ -d $(ART_HOST_TEST_DIR)/failed/ ] \
+       && echo -e "$(1) \e[93mSKIPPING DUE TO EARLIER FAILURE\e[0m") \
+     || echo -e "$(1) \e[93mSKIPPING BROKEN TEST\e[0m") && false))
+endef
+
+# Create a build rule to create the dex file for a test.
+# $(1): module prefix, e.g. art-test-dex
+# $(2): input test directory in art/test, e.g. HelloWorld
+# $(3): target output module path (default module path is used on host)
+# $(4): additional dependencies
+# $(5): a make variable used to collate dependencies
+define build-art-test-dex
+  ifeq ($(ART_BUILD_TARGET),true)
+    include $(CLEAR_VARS)
+    LOCAL_MODULE := $(1)-$(2)
+    LOCAL_SRC_FILES := $(call all-java-files-under, $(2))
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_DEX_PREOPT := false
+    LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_test.mk $(4)
+    LOCAL_MODULE_TAGS := tests
+    LOCAL_JAVA_LIBRARIES := $(TARGET_CORE_JARS)
+    LOCAL_MODULE_PATH := $(3)
+    LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
+    include $(BUILD_JAVA_LIBRARY)
+  endif
+  ifeq ($(ART_BUILD_HOST),true)
+    include $(CLEAR_VARS)
+    LOCAL_MODULE := $(1)-$(2)
+    LOCAL_SRC_FILES := $(call all-java-files-under, $(2))
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_DEX_PREOPT := false
+    LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_test.mk $(4)
+    LOCAL_JAVA_LIBRARIES := $(HOST_CORE_JARS)
+    LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
+    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+  endif
+  $(5) := $$(LOCAL_INSTALLED_MODULE)
+endef
+
+endif # ANDROID_COMMON_TEST_MK
diff --git a/build/Android.cpplint.mk b/build/Android.cpplint.mk
index 1ecad21..7abf863 100644
--- a/build/Android.cpplint.mk
+++ b/build/Android.cpplint.mk
@@ -14,6 +14,8 @@
 # limitations under the License.
 #
 
+include art/build/Android.common_build.mk
+
 ART_CPPLINT := art/tools/cpplint.py
 ART_CPPLINT_FILTER := --filter=-whitespace/line_length,-build/include,-readability/function,-readability/streams,-readability/todo,-runtime/references,-runtime/sizeof,-runtime/threadsafe_fn,-runtime/printf
 ART_CPPLINT_SRC := $(shell find art -name "*.h" -o -name "*$(ART_CPP_EXTENSION)" | grep -v art/compiler/llvm/generated/)
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index 49e7384..d887acd 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-include art/build/Android.common.mk
+include art/build/Android.common_build.mk
 
 ART_HOST_EXECUTABLES ?=
 ART_TARGET_EXECUTABLES ?=
@@ -85,13 +85,13 @@
     LOCAL_SHARED_LIBRARIES += libartd
   endif
 
-  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
   LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.executable.mk
 
   ifeq ($$(art_target_or_host),target)
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
-    LOCAL_MULTILIB := $$(art_multilib)
   endif
+  LOCAL_MULTILIB := $$(art_multilib)
 
   include external/libcxx/libcxx.mk
   ifeq ($$(art_target_or_host),target)
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 4c2cda4..9723b89a 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -14,147 +14,251 @@
 # limitations under the License.
 #
 
+# The path for which all the dex files are relative, not actually the current directory.
+LOCAL_PATH := art/test
+
+include art/build/Android.common_test.mk
+include art/build/Android.common_path.mk
+
+# Subdirectories in art/test which contain dex files used as inputs for gtests.
+GTEST_DEX_DIRECTORIES := \
+  AbstractMethod \
+  AllFields \
+  ExceptionHandle \
+  GetMethodSignature \
+  Interfaces \
+  Main \
+  MyClass \
+  MyClassNatives \
+  Nested \
+  NonStaticLeafMethods \
+  ProtoCompare \
+  ProtoCompare2 \
+  StaticLeafMethods \
+  Statics \
+  StaticsFromCode \
+  Transaction \
+  XandY
+
+# Create build rules for each dex file recording the dependency.
+$(foreach dir,$(GTEST_DEX_DIRECTORIES), $(eval $(call build-art-test-dex,art-gtest,$(dir), \
+  $(ART_TARGET_NATIVETEST_OUT),art/build/Android.gtest.mk,ART_GTEST_$(dir)_DEX)))
+
+# Dex file dependencies for each gtest.
+ART_GTEST_class_linker_test_DEPS := $(ART_GTEST_Interfaces_DEX) $(ART_GTEST_MyClass_DEX) \
+  $(ART_GTEST_Nested_DEX) $(ART_GTEST_Statics_DEX) $(ART_GTEST_StaticsFromCode_DEX)
+ART_GTEST_compiler_test_DEPS := $(ART_GTEST_AbstractMethod_DEX)
+ART_GTEST_dex_file_test_DEPS := $(ART_GTEST_GetMethodSignature_DEX)
+ART_GTEST_exception_test_DEPS := $(ART_GTEST_ExceptionHandle_DEX)
+ART_GTEST_jni_compiler_test_DEPS := $(ART_GTEST_MyClassNatives_DEX)
+ART_GTEST_jni_internal_test_DEPS := $(ART_GTEST_AllFields_DEX)
+ART_GTEST_object_test_DEPS := $(ART_GTEST_ProtoCompare_DEX) $(ART_GTEST_ProtoCompare2_DEX) \
+   $(ART_GTEST_StaticsFromCode_DEX) $(ART_GTEST_XandY_DEX)
+ART_GTEST_proxy_test_DEPS := $(ART_GTEST_Interfaces_DEX)
+ART_GTEST_reflection_test_DEPS := $(ART_GTEST_Main_DEX) $(ART_GTEST_NonStaticLeafMethods_DEX) \
+  $(ART_GTEST_StaticLeafMethods_DEX)
+ART_GTEST_stub_test_DEPS := $(ART_GTEST_AllFields_DEX)
+ART_GTEST_transaction_test_DEPS := $(ART_GTEST_Transaction_DEX)
+
+# The elf writer test has dependencies on core.oat.
+ART_GTEST_elf_writer_test_DEPS := $(HOST_CORE_OAT_OUT) $(2ND_HOST_CORE_OAT_OUT) \
+  $(TARGET_CORE_OAT_OUT) $(2ND_TARGET_CORE_OAT_OUT)
+
+# The path for which all the source files are relative, not actually the current directory.
 LOCAL_PATH := art
 
 RUNTIME_GTEST_COMMON_SRC_FILES := \
-	runtime/arch/arch_test.cc \
-	runtime/arch/stub_test.cc \
-	runtime/barrier_test.cc \
-	runtime/base/bit_field_test.cc \
-	runtime/base/bit_vector_test.cc \
-	runtime/base/hex_dump_test.cc \
-	runtime/base/histogram_test.cc \
-	runtime/base/mutex_test.cc \
-	runtime/base/scoped_flock_test.cc \
-	runtime/base/timing_logger_test.cc \
-	runtime/base/unix_file/fd_file_test.cc \
-	runtime/base/unix_file/mapped_file_test.cc \
-	runtime/base/unix_file/null_file_test.cc \
-	runtime/base/unix_file/random_access_file_utils_test.cc \
-	runtime/base/unix_file/string_file_test.cc \
-	runtime/class_linker_test.cc \
-	runtime/dex_file_test.cc \
-	runtime/dex_file_verifier_test.cc \
-	runtime/dex_instruction_visitor_test.cc \
-	runtime/dex_method_iterator_test.cc \
-	runtime/entrypoints/math_entrypoints_test.cc \
-	runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc \
-	runtime/entrypoints_order_test.cc \
-	runtime/exception_test.cc \
-	runtime/gc/accounting/space_bitmap_test.cc \
-	runtime/gc/heap_test.cc \
-	runtime/gc/space/dlmalloc_space_base_test.cc \
-	runtime/gc/space/dlmalloc_space_static_test.cc \
-	runtime/gc/space/dlmalloc_space_random_test.cc \
-	runtime/gc/space/rosalloc_space_base_test.cc \
-	runtime/gc/space/rosalloc_space_static_test.cc \
-	runtime/gc/space/rosalloc_space_random_test.cc \
-	runtime/gc/space/large_object_space_test.cc \
-	runtime/gtest_test.cc \
-	runtime/handle_scope_test.cc \
-	runtime/indenter_test.cc \
-	runtime/indirect_reference_table_test.cc \
-	runtime/instruction_set_test.cc \
-	runtime/intern_table_test.cc \
-	runtime/leb128_test.cc \
-	runtime/mem_map_test.cc \
-	runtime/mirror/dex_cache_test.cc \
-	runtime/mirror/object_test.cc \
-	runtime/parsed_options_test.cc \
-	runtime/reference_table_test.cc \
-	runtime/thread_pool_test.cc \
-	runtime/transaction_test.cc \
-	runtime/utils_test.cc \
-	runtime/verifier/method_verifier_test.cc \
-	runtime/verifier/reg_type_test.cc \
-	runtime/zip_archive_test.cc
+  runtime/arch/arch_test.cc \
+  runtime/arch/stub_test.cc \
+  runtime/barrier_test.cc \
+  runtime/base/bit_field_test.cc \
+  runtime/base/bit_vector_test.cc \
+  runtime/base/hex_dump_test.cc \
+  runtime/base/histogram_test.cc \
+  runtime/base/mutex_test.cc \
+  runtime/base/scoped_flock_test.cc \
+  runtime/base/timing_logger_test.cc \
+  runtime/base/unix_file/fd_file_test.cc \
+  runtime/base/unix_file/mapped_file_test.cc \
+  runtime/base/unix_file/null_file_test.cc \
+  runtime/base/unix_file/random_access_file_utils_test.cc \
+  runtime/base/unix_file/string_file_test.cc \
+  runtime/class_linker_test.cc \
+  runtime/dex_file_test.cc \
+  runtime/dex_file_verifier_test.cc \
+  runtime/dex_instruction_visitor_test.cc \
+  runtime/dex_method_iterator_test.cc \
+  runtime/entrypoints/math_entrypoints_test.cc \
+  runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc \
+  runtime/entrypoints_order_test.cc \
+  runtime/exception_test.cc \
+  runtime/gc/accounting/space_bitmap_test.cc \
+  runtime/gc/heap_test.cc \
+  runtime/gc/space/dlmalloc_space_base_test.cc \
+  runtime/gc/space/dlmalloc_space_static_test.cc \
+  runtime/gc/space/dlmalloc_space_random_test.cc \
+  runtime/gc/space/rosalloc_space_base_test.cc \
+  runtime/gc/space/rosalloc_space_static_test.cc \
+  runtime/gc/space/rosalloc_space_random_test.cc \
+  runtime/gc/space/large_object_space_test.cc \
+  runtime/gtest_test.cc \
+  runtime/handle_scope_test.cc \
+  runtime/indenter_test.cc \
+  runtime/indirect_reference_table_test.cc \
+  runtime/instruction_set_test.cc \
+  runtime/intern_table_test.cc \
+  runtime/leb128_test.cc \
+  runtime/mem_map_test.cc \
+  runtime/mirror/dex_cache_test.cc \
+  runtime/mirror/object_test.cc \
+  runtime/parsed_options_test.cc \
+  runtime/reference_table_test.cc \
+  runtime/thread_pool_test.cc \
+  runtime/transaction_test.cc \
+  runtime/utils_test.cc \
+  runtime/verifier/method_verifier_test.cc \
+  runtime/verifier/reg_type_test.cc \
+  runtime/zip_archive_test.cc
 
 COMPILER_GTEST_COMMON_SRC_FILES := \
-	runtime/jni_internal_test.cc \
-	runtime/proxy_test.cc \
-	runtime/reflection_test.cc \
-	compiler/dex/local_value_numbering_test.cc \
-	compiler/dex/mir_optimization_test.cc \
-	compiler/driver/compiler_driver_test.cc \
-	compiler/elf_writer_test.cc \
-	compiler/image_test.cc \
-	compiler/jni/jni_compiler_test.cc \
-	compiler/oat_test.cc \
-	compiler/optimizing/codegen_test.cc \
-	compiler/optimizing/dominator_test.cc \
-	compiler/optimizing/find_loops_test.cc \
-	compiler/optimizing/graph_test.cc \
-	compiler/optimizing/linearize_test.cc \
-	compiler/optimizing/liveness_test.cc \
-	compiler/optimizing/live_interval_test.cc \
-	compiler/optimizing/live_ranges_test.cc \
-	compiler/optimizing/parallel_move_test.cc \
-	compiler/optimizing/pretty_printer_test.cc \
-	compiler/optimizing/register_allocator_test.cc \
-	compiler/optimizing/ssa_test.cc \
-	compiler/output_stream_test.cc \
-	compiler/utils/arena_allocator_test.cc \
-	compiler/utils/dedupe_set_test.cc \
-	compiler/utils/arm/managed_register_arm_test.cc \
-	compiler/utils/arm64/managed_register_arm64_test.cc \
-	compiler/utils/x86/managed_register_x86_test.cc \
+  runtime/jni_internal_test.cc \
+  runtime/proxy_test.cc \
+  runtime/reflection_test.cc \
+  compiler/dex/local_value_numbering_test.cc \
+  compiler/dex/mir_optimization_test.cc \
+  compiler/driver/compiler_driver_test.cc \
+  compiler/elf_writer_test.cc \
+  compiler/image_test.cc \
+  compiler/jni/jni_compiler_test.cc \
+  compiler/oat_test.cc \
+  compiler/optimizing/codegen_test.cc \
+  compiler/optimizing/dominator_test.cc \
+  compiler/optimizing/find_loops_test.cc \
+  compiler/optimizing/graph_test.cc \
+  compiler/optimizing/linearize_test.cc \
+  compiler/optimizing/liveness_test.cc \
+  compiler/optimizing/live_interval_test.cc \
+  compiler/optimizing/live_ranges_test.cc \
+  compiler/optimizing/parallel_move_test.cc \
+  compiler/optimizing/pretty_printer_test.cc \
+  compiler/optimizing/register_allocator_test.cc \
+  compiler/optimizing/ssa_test.cc \
+  compiler/output_stream_test.cc \
+  compiler/utils/arena_allocator_test.cc \
+  compiler/utils/dedupe_set_test.cc \
+  compiler/utils/arm/managed_register_arm_test.cc \
+  compiler/utils/arm64/managed_register_arm64_test.cc \
+  compiler/utils/x86/managed_register_x86_test.cc \
 
 ifeq ($(ART_SEA_IR_MODE),true)
 COMPILER_GTEST_COMMON_SRC_FILES += \
-	compiler/utils/scoped_hashtable_test.cc \
-	compiler/sea_ir/types/type_data_test.cc \
-	compiler/sea_ir/types/type_inference_visitor_test.cc \
-	compiler/sea_ir/ir/regions_test.cc
+  compiler/utils/scoped_hashtable_test.cc \
+  compiler/sea_ir/types/type_data_test.cc \
+  compiler/sea_ir/types/type_inference_visitor_test.cc \
+  compiler/sea_ir/ir/regions_test.cc
 endif
 
 RUNTIME_GTEST_TARGET_SRC_FILES := \
-	$(RUNTIME_GTEST_COMMON_SRC_FILES)
+  $(RUNTIME_GTEST_COMMON_SRC_FILES)
 
 RUNTIME_GTEST_HOST_SRC_FILES := \
-	$(RUNTIME_GTEST_COMMON_SRC_FILES)
+  $(RUNTIME_GTEST_COMMON_SRC_FILES)
 
 COMPILER_GTEST_TARGET_SRC_FILES := \
-	$(COMPILER_GTEST_COMMON_SRC_FILES)
+  $(COMPILER_GTEST_COMMON_SRC_FILES)
 
 COMPILER_GTEST_HOST_SRC_FILES := \
-	$(COMPILER_GTEST_COMMON_SRC_FILES) \
-	compiler/utils/x86/assembler_x86_test.cc \
-	compiler/utils/x86_64/assembler_x86_64_test.cc
-
-ART_HOST_GTEST_EXECUTABLES :=
-ART_TARGET_GTEST_EXECUTABLES$(ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_TARGET_GTEST_EXECUTABLES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_HOST_GTEST_TARGETS :=
-ART_HOST_VALGRIND_GTEST_TARGETS :=
-ART_TARGET_GTEST_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_TARGET_GTEST_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
+  $(COMPILER_GTEST_COMMON_SRC_FILES) \
+  compiler/utils/x86/assembler_x86_test.cc \
+  compiler/utils/x86_64/assembler_x86_64_test.cc
 
 ART_TEST_CFLAGS :=
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   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): $(ART_NATIVETEST_OUT)/$(TARGET_$(1)ARCH)/$$(LOCAL_MODULE) test-art-target-sync
-	adb shell touch $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@
-	adb shell rm $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@
-	adb shell chmod 755 $(ART_NATIVETEST_DIR)/$(TARGET_$(1)ARCH)/$$(notdir $$<)
-	adb shell sh -c "$(ART_NATIVETEST_DIR)/$(TARGET_$(1)ARCH)/$$(notdir $$<) && touch $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@"
-	$(hide) (adb pull $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
-	$(hide) rm /tmp/$$@
+# Variables holding collections of gtest pre-requisits used to run a number of gtests.
+ART_TEST_HOST_GTEST$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_GTEST$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_GTEST_RULES :=
+ART_TEST_HOST_VALGRIND_GTEST$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_VALGRIND_GTEST$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_VALGRIND_GTEST_RULES :=
+ART_TEST_TARGET_GTEST$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_GTEST$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_GTEST_RULES :=
 
-  ART_TARGET_GTEST_TARGETS$($(1)ART_PHONY_TEST_TARGET_SUFFIX) += $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
-endef
+# Define a make rule for a target device gtest.
+# $(1): gtest name - the name of the test we're building such as leb128_test.
+# $(2): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
+define define-art-gtest-rule-target
+  gtest_rule := test-art-target-gtest-$(1)$$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
 
+  # Add the test dependencies to test-art-target-sync, which will be a prerequisit for the test
+  # to ensure files are pushed to the device.
+  TEST_ART_TARGET_SYNC_DEPS += \
+    $$(ART_GTEST_$(1)_DEPS) \
+    $$(ART_TARGET_NATIVETEST_OUT)/$$(TARGET_$(2)ARCH)/$(1) \
+    $$(TARGET_CORE_DEX_LOCATIONS)
 
+.PHONY: $$(gtest_rule)
+$$(gtest_rule): test-art-target-sync
+	$(hide) adb shell touch $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$$$$PPID
+	$(hide) adb shell rm $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$$$$PPID
+	$(hide) adb shell chmod 755 $(ART_TARGET_NATIVETEST_DIR)/$(TARGET_$(2)ARCH)/$(1)
+	$(hide) $$(call ART_TEST_SKIP,$$@) && \
+	  (adb shell sh -c "$(ART_TARGET_NATIVETEST_DIR)/$(TARGET_$(2)ARCH)/$(1) && touch $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$$$$PPID" \
+	  && (adb pull $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$$$$PPID /tmp/ \
+	      && $$(call ART_TEST_PASSED,$$@)) \
+	  || $$(call ART_TEST_FAILED,$$@))
+	$(hide) rm /tmp/$$@-$$$$PPID
+
+  ART_TEST_TARGET_GTEST$($(2)ART_PHONY_TEST_TARGET_SUFFIX)_RULES += $$(gtest_rule)
+  ART_TEST_TARGET_GTEST_RULES += $$(gtest_rule)
+  ART_TEST_TARGET_GTEST_$(1)_RULES += $$(gtest_rule)
+
+  # Clear locally defined variables.
+  gtest_rule :=
+endef  # define-art-gtest-rule-target
+
+# Define make rules for a host gtests.
+# $(1): gtest name - the name of the test we're building such as leb128_test.
+# $(2): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
+define define-art-gtest-rule-host
+  gtest_rule := test-art-host-gtest-$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
+  gtest_exe := $$(HOST_OUT_EXECUTABLES)/$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
+
+.PHONY: $$(gtest_rule)
+$$(gtest_rule): $$(gtest_exe) $$(ART_GTEST_$(1)_DEPS) $$(HOST_CORE_DEX_LOCATIONS)
+	$(hide) ($$(call ART_TEST_SKIP,$$@) && $$< && $$(call ART_TEST_PASSED,$$@)) \
+	  || $$(call ART_TEST_FAILED,$$@)
+
+  ART_TEST_HOST_GTEST$$($(2)ART_PHONY_TEST_HOST_SUFFIX)_RULES += $$(gtest_rule)
+  ART_TEST_HOST_GTEST_RULES += $$(gtest_rule)
+  ART_TEST_HOST_GTEST_$(1)_RULES += $$(gtest_rule)
+
+.PHONY: valgrind-$$(gtest_rule)
+valgrind-$$(gtest_rule): $$(gtest_exe) test-art-host-dependencies $$(ART_GTEST_$(1)_DEPS)
+	$(hide) $$(call ART_TEST_SKIP,$$@) && \
+	  valgrind --leak-check=full --error-exitcode=1 $$< && $$(call ART_TEST_PASSED,$$@) \
+	    || $$(call ART_TEST_FAILED,$$@)
+
+  ART_TEST_HOST_VALGRIND_GTEST$$($(2)ART_PHONY_TEST_HOST_SUFFIX)_RULES += valgrind-$$(gtest_rule)
+  ART_TEST_HOST_VALGRIND_GTEST_RULES += valgrind-$$(gtest_rule)
+  ART_TEST_HOST_VALGRIND_GTEST_$(1)_RULES += valgrind-$$(gtest_rule)
+
+  # Clear locally defined variables.
+  valgrind_gtest_rule :=
+  gtest_rule :=
+  gtest_exe :=
+endef  # define-art-gtest-rule-host
+
+# Define the rules to build and run host and target gtests.
 # $(1): target or host
 # $(2): file name
 # $(3): extra C includes
 # $(4): extra shared libraries
-define build-art-test
+define define-art-gtest
   ifneq ($(1),target)
     ifneq ($(1),host)
       $$(error expected target or host for argument 1, received $(1))
@@ -166,94 +270,103 @@
   art_gtest_extra_c_includes := $(3)
   art_gtest_extra_shared_libraries := $(4)
 
+  include $$(CLEAR_VARS)
   art_gtest_name := $$(notdir $$(basename $$(art_gtest_filename)))
-
-  include $(CLEAR_VARS)
-  LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
   LOCAL_MODULE := $$(art_gtest_name)
   ifeq ($$(art_target_or_host),target)
     LOCAL_MODULE_TAGS := tests
   endif
+  LOCAL_CPP_EXTENSION := $$(ART_CPP_EXTENSION)
   LOCAL_SRC_FILES := $$(art_gtest_filename) runtime/common_runtime_test.cc
-  LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime $(3)
-  LOCAL_SHARED_LIBRARIES += libartd $(4)
-  # dex2oatd is needed to go with libartd
-  LOCAL_REQUIRED_MODULES := dex2oatd
+  LOCAL_C_INCLUDES += $$(ART_C_INCLUDES) art/runtime $$(art_gtest_extra_c_includes)
+  LOCAL_SHARED_LIBRARIES += libartd $$(art_gtest_extra_shared_libraries)
 
-  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
-  LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.gtest.mk
+  # LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
+  # LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.gtest.mk
 
   # Mac OS linker doesn't understand --export-dynamic.
-  ifneq ($(HOST_OS)-$$(art_target_or_host),darwin-host)
+  ifneq ($$(HOST_OS)-$$(art_target_or_host),darwin-host)
     # Allow jni_compiler_test to find Java_MyClassNatives_bar within itself using dlopen(NULL, ...).
     LOCAL_LDFLAGS := -Wl,--export-dynamic -Wl,-u,Java_MyClassNatives_bar -Wl,-u,Java_MyClassNatives_sbar
   endif
 
-  LOCAL_CFLAGS := $(ART_TEST_CFLAGS)
+  LOCAL_CFLAGS := $$(ART_TEST_CFLAGS)
   include external/libcxx/libcxx.mk
   ifeq ($$(art_target_or_host),target)
-  	$(call set-target-local-clang-vars)
-  	$(call set-target-local-cflags-vars,debug)
+    $$(eval $$(call set-target-local-clang-vars))
+    $$(eval $$(call set-target-local-cflags-vars,debug))
     LOCAL_SHARED_LIBRARIES += libdl libicuuc libicui18n libnativehelper libz libcutils libvixl
     LOCAL_STATIC_LIBRARIES += libgtest_libc++
-    LOCAL_MODULE_PATH_32 := $(ART_NATIVETEST_OUT)/$(ART_TARGET_ARCH_32)
-    LOCAL_MODULE_PATH_64 := $(ART_NATIVETEST_OUT)/$(ART_TARGET_ARCH_64)
+    LOCAL_MODULE_PATH_32 := $$(ART_TARGET_NATIVETEST_OUT)/$$(ART_TARGET_ARCH_32)
+    LOCAL_MODULE_PATH_64 := $$(ART_TARGET_NATIVETEST_OUT)/$$(ART_TARGET_ARCH_64)
     LOCAL_MULTILIB := both
-    include $(BUILD_EXECUTABLE)
+    include $$(BUILD_EXECUTABLE)
 
-    ART_TARGET_GTEST_EXECUTABLES$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_NATIVETEST_OUT)/$(TARGET_ARCH)/$$(LOCAL_MODULE)
-    art_gtest_target := test-art-$$(art_target_or_host)-gtest-$$(art_gtest_name)
-
+    ART_TEST_TARGET_GTEST_$$(art_gtest_name)_RULES :=
     ifdef TARGET_2ND_ARCH
-      $(call build-art-test-make-target,2ND_)
-
-      ART_TARGET_GTEST_EXECUTABLES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_NATIVETEST_OUT)/$(TARGET_2ND_ARCH)/$$(LOCAL_MODULE)
-
-      # 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
+      $$(eval $$(call define-art-gtest-rule-target,$$(art_gtest_name),2ND_))
     endif
-    $(call build-art-test-make-target,)
+    $$(eval $$(call define-art-gtest-rule-target,$$(art_gtest_name),))
 
+    # A rule to run the different architecture versions of the gtest.
+.PHONY: test-art-target-gtest-$$(art_gtest_name)
+test-art-target-gtest-$$(art_gtest_name): $$(ART_TEST_TARGET_GTEST_$$(art_gtest_name)_RULES)
+	$$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+    # Clear locally defined variables.
+    ART_TEST_TARGET_GTEST_$$(art_gtest_name)_RULES :=
   else # host
-    LOCAL_CLANG := $(ART_HOST_CLANG)
-    LOCAL_CFLAGS += $(ART_HOST_CFLAGS) $(ART_HOST_DEBUG_CFLAGS)
+    LOCAL_CLANG := $$(ART_HOST_CLANG)
+    LOCAL_CFLAGS += $$(ART_HOST_CFLAGS) $$(ART_HOST_DEBUG_CFLAGS)
     LOCAL_SHARED_LIBRARIES += libicuuc-host libicui18n-host libnativehelper libz-host
     LOCAL_STATIC_LIBRARIES += libcutils libvixl
-    ifneq ($(WITHOUT_HOST_CLANG),true)
-        # GCC host compiled tests fail with this linked, presumably due to destructors that run.
-        LOCAL_STATIC_LIBRARIES += libgtest_libc++_host
+    ifneq ($$(WITHOUT_HOST_CLANG),true)
+      # GCC host compiled tests fail with this linked, presumably due to destructors that run.
+      LOCAL_STATIC_LIBRARIES += libgtest_libc++_host
     endif
     LOCAL_LDLIBS += -lpthread -ldl
     LOCAL_IS_HOST_MODULE := true
-    include $(BUILD_HOST_EXECUTABLE)
-    art_gtest_exe := $(HOST_OUT_EXECUTABLES)/$$(LOCAL_MODULE)
-    ART_HOST_GTEST_EXECUTABLES += $$(art_gtest_exe)
-    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
+    LOCAL_MULTILIB := both
+    LOCAL_MODULE_STEM_32 := $$(art_gtest_name)32
+    LOCAL_MODULE_STEM_64 := $$(art_gtest_name)64
+    include $$(BUILD_HOST_EXECUTABLE)
 
-    ART_HOST_GTEST_TARGETS += $$(art_gtest_target)
+    ART_TEST_HOST_GTEST_$$(art_gtest_name)_RULES :=
+    ART_TEST_HOST_VALGRIND_GTEST_$$(art_gtest_name)_RULES :=
+    ifneq ($$(HOST_PREFER_32_BIT),true)
+      $$(eval $$(call define-art-gtest-rule-host,$$(art_gtest_name),2ND_))
+    endif
+    $$(eval $$(call define-art-gtest-rule-host,$$(art_gtest_name),))
 
-.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
+    # Rules to run the different architecture versions of the gtest.
+.PHONY: test-art-host-gtest-$$(art_gtest_name)
+test-art-host-gtest-$$(art_gtest_name): $$(ART_TEST_HOST_GTEST_$$(art_gtest_name)_RULES)
+	$$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
 
-    ART_HOST_VALGRIND_GTEST_TARGETS += valgrind-$$(art_gtest_target)
-  endif
-endef
+.PHONY: valgrind-test-art-host-gtest-$$(art_gtest_name)
+valgrind-test-art-host-gtest-$$(art_gtest_name): $$(ART_TEST_HOST_VALGRIND_GTEST_$$(art_gtest_name)_RULES)
+	$$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+    # Clear locally defined variables.
+    ART_TEST_HOST_GTEST_$$(art_gtest_name)_RULES :=
+    ART_TEST_HOST_VALGRIND_GTEST_$$(art_gtest_name)_RULES :=
+  endif  # host_or_target
+
+  # Clear locally defined variables.
+  art_target_or_host :=
+  art_gtest_filename :=
+  art_gtest_extra_c_includes :=
+  art_gtest_extra_shared_libraries :=
+  art_gtest_name :=
+endef  # define-art-gtest
 
 ifeq ($(ART_BUILD_TARGET),true)
-  $(foreach file,$(RUNTIME_GTEST_TARGET_SRC_FILES), $(eval $(call build-art-test,target,$(file),,)))
-  $(foreach file,$(COMPILER_GTEST_TARGET_SRC_FILES), $(eval $(call build-art-test,target,$(file),art/compiler,libartd-compiler)))
+  $(foreach file,$(RUNTIME_GTEST_TARGET_SRC_FILES), $(eval $(call define-art-gtest,target,$(file),,)))
+  $(foreach file,$(COMPILER_GTEST_TARGET_SRC_FILES), $(eval $(call define-art-gtest,target,$(file),art/compiler,libartd-compiler)))
 endif
 ifeq ($(ART_BUILD_HOST),true)
-  $(foreach file,$(RUNTIME_GTEST_HOST_SRC_FILES), $(eval $(call build-art-test,host,$(file),,)))
-  $(foreach file,$(COMPILER_GTEST_HOST_SRC_FILES), $(eval $(call build-art-test,host,$(file),art/compiler,libartd-compiler)))
+  $(foreach file,$(RUNTIME_GTEST_HOST_SRC_FILES), $(eval $(call define-art-gtest,host,$(file),,)))
+  $(foreach file,$(COMPILER_GTEST_HOST_SRC_FILES), $(eval $(call define-art-gtest,host,$(file),art/compiler,libartd-compiler)))
 endif
 
 # Used outside the art project to get a list of the current tests
@@ -261,3 +374,85 @@
 $(foreach file, $(RUNTIME_GTEST_TARGET_SRC_FILES), $(eval RUNTIME_TARGET_GTEST_MAKE_TARGETS += $$(notdir $$(basename $$(file)))))
 COMPILER_TARGET_GTEST_MAKE_TARGETS :=
 $(foreach file, $(COMPILER_GTEST_TARGET_SRC_FILES), $(eval COMPILER_TARGET_GTEST_MAKE_TARGETS += $$(notdir $$(basename $$(file)))))
+
+# Define all the combinations of host/target, valgrind and suffix such as:
+# test-art-host-gtest or valgrind-test-art-host-gtest64
+# $(1): host or target
+# $(2): HOST or TARGET
+# $(3): valgrind- or undefined
+# $(4): undefined, 32 or 64
+define define-test-art-gtest-combination
+  ifeq ($(1),host)
+    ifneq ($(2),HOST)
+      $$(error argument mismatch $(1) and ($2))
+    endif
+  else
+    ifneq ($(1),target)
+      $$(error found $(1) expected host or target)
+    endif
+    ifneq ($(2),TARGET)
+      $$(error argument mismatch $(1) and ($2))
+    endif
+  endif
+
+  rule_name := $(3)test-art-$(1)-gtest$(4)
+  dependencies := $$(ART_TEST_$(2)_GTEST$(4)_RULES)
+
+.PHONY: $$(rule_name)
+$$(rule_name): $$(dependencies)
+	$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+  # Clear locally defined variables.
+  rule_name :=
+  dependencies :=
+endef  # define-test-art-gtest-combination
+
+$(eval $(call define-test-art-gtest-combination,target,TARGET,,))
+$(eval $(call define-test-art-gtest-combination,target,TARGET,,$(ART_PHONY_TEST_TARGET_SUFFIX)))
+ifdef TARGET_2ND_ARCH
+$(eval $(call define-test-art-gtest-combination,target,TARGET,,$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)))
+endif
+$(eval $(call define-test-art-gtest-combination,host,HOST,,))
+$(eval $(call define-test-art-gtest-combination,host,HOST,valgrind-,))
+$(eval $(call define-test-art-gtest-combination,host,HOST,,$(ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-gtest-combination,host,HOST,valgrind-,$(ART_PHONY_TEST_HOST_SUFFIX)))
+ifneq ($(HOST_PREFER_32_BIT),true)
+$(eval $(call define-test-art-gtest-combination,host,HOST,,$(2ND_ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-gtest-combination,host,HOST,valgrind-,$(2ND_ART_PHONY_TEST_HOST_SUFFIX)))
+endif
+
+# Clear locally defined variables.
+define-art-gtest-rule-target :=
+define-art-gtest-rule-host :=
+define-art-gtest :=
+define-test-art-gtest-combination :=
+RUNTIME_GTEST_COMMON_SRC_FILES :=
+COMPILER_GTEST_COMMON_SRC_FILES :=
+RUNTIME_GTEST_TARGET_SRC_FILES :=
+RUNTIME_GTEST_HOST_SRC_FILES :=
+COMPILER_GTEST_TARGET_SRC_FILES :=
+COMPILER_GTEST_HOST_SRC_FILES :=
+ART_TEST_CFLAGS :=
+ART_TEST_HOST_GTEST$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_GTEST$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_GTEST_RULES :=
+ART_TEST_HOST_VALGRIND_GTEST$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_VALGRIND_GTEST$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_VALGRIND_GTEST_RULES :=
+ART_TEST_TARGET_GTEST$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_GTEST$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_GTEST_RULES :=
+ART_GTEST_class_linker_test_DEPS :=
+ART_GTEST_compiler_test_DEPS :=
+ART_GTEST_dex_file_test_DEPS :=
+ART_GTEST_exception_test_DEPS :=
+ART_GTEST_jni_compiler_test_DEPS :=
+ART_GTEST_jni_internal_test_DEPS :=
+ART_GTEST_object_test_DEPS :=
+ART_GTEST_proxy_test_DEPS :=
+ART_GTEST_reflection_test_DEPS :=
+ART_GTEST_stub_test_DEPS :=
+ART_GTEST_transaction_test_DEPS :=
+$(foreach dir,$(GTEST_DEX_DIRECTORIES), $(eval ART_GTEST_TEST_$(dir)_DEX :=))
+GTEST_DEX_DIRECTORIES :=
+LOCAL_PATH :=
\ No newline at end of file
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index c67a815..3117f71 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -20,53 +20,62 @@
 #
 # The main rules to build the default "boot" image are in
 # build/core/dex_preopt_libart.mk
-TARGET_CORE_JARS := core-libart conscrypt okhttp core-junit bouncycastle
-HOST_CORE_JARS := $(addsuffix -hostdex,$(TARGET_CORE_JARS))
 
-HOST_CORE_DEX_LOCATIONS   := $(foreach jar,$(HOST_CORE_JARS),  $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
-TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_CORE_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
-
-HOST_CORE_DEX_FILES   := $(foreach jar,$(HOST_CORE_JARS),  $(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),t,COMMON)/javalib.jar)
-TARGET_CORE_DEX_FILES := $(foreach jar,$(TARGET_CORE_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar), ,COMMON)/javalib.jar)
-
-TARGET_INSTRUCTION_SET_FEATURES := $(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+include art/build/Android.common_path.mk
 
 # Use dex2oat debug version for better error reporting
-$(HOST_CORE_IMG_OUT): $(HOST_CORE_DEX_FILES) $(DEX2OATD_DEPENDENCY)
-	@echo "host dex2oat: $@ ($?)"
-	@mkdir -p $(dir $@)
-	$(hide) $(DEX2OATD) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$(PRELOADED_CLASSES) $(addprefix \
-		--dex-file=,$(HOST_CORE_DEX_FILES)) $(addprefix --dex-location=,$(HOST_CORE_DEX_LOCATIONS)) --oat-file=$(HOST_CORE_OAT_OUT) \
-		--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)
+# $(1): 2ND_ or undefined, 2ND_ for 32-bit host builds.
+define create-core-oat-host-rules
+$$($(1)HOST_CORE_IMG_OUT): $$($(1)HOST_CORE_DEX_FILES) $$(DEX2OATD_DEPENDENCY)
+	@echo "host dex2oat: $$@ ($$?)"
+	@mkdir -p $$(dir $$@)
+	$$(hide) $$(DEX2OATD) --runtime-arg -Xms16m --runtime-arg -Xmx16m \
+	  --image-classes=$$(PRELOADED_CLASSES) $$(addprefix --dex-file=,$$(HOST_CORE_DEX_FILES)) \
+	  $$(addprefix --dex-location=,$$(HOST_CORE_DEX_LOCATIONS)) --oat-file=$$($(1)HOST_CORE_OAT_OUT) \
+	  --oat-location=$$($(1)HOST_CORE_OAT) --image=$$($(1)HOST_CORE_IMG_OUT) \
+	  --base=$$(LIBART_IMG_HOST_BASE_ADDRESS) --instruction-set=$$($(1)ART_HOST_ARCH) \
+	  --instruction-set-features=$$($(1)HOST_INSTRUCTION_SET_FEATURES) \
+	  --host --android-root=$$(HOST_OUT)
 
-$(HOST_CORE_OAT_OUT): $(HOST_CORE_IMG_OUT)
+# This "renaming" eases declaration in art/Android.mk
+HOST_CORE_IMG_OUT$($(1)ART_PHONY_TEST_HOST_SUFFIX) := $($(1)HOST_CORE_IMG_OUT)
+
+$$($(1)HOST_CORE_OAT_OUT): $$($(1)HOST_CORE_IMG_OUT)
+endef  # create-core-oat-host-rules
+
+$(eval $(call create-core-oat-host-rules,))
+ifneq ($(HOST_PREFER_32_BIT),true)
+$(eval $(call create-core-oat-host-rules,2ND_))
+endif
 
 IMPLICIT_CHECKS_arm := null,stack
 IMPLICIT_CHECKS_arm64 := none
 IMPLICIT_CHECKS_x86 := none
 IMPLICIT_CHECKS_x86_64 := none
 IMPLICIT_CHECKS_mips := none
-define create-oat-target-targets
+define create-core-oat-target-rules
 $$($(1)TARGET_CORE_IMG_OUT): $$($(1)TARGET_CORE_DEX_FILES) $$(DEX2OATD_DEPENDENCY)
 	@echo "target dex2oat: $$@ ($$?)"
 	@mkdir -p $$(dir $$@)
-	$$(hide) $$(DEX2OATD) --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) \
-		--implicit-checks=$(IMPLICIT_CHECKS_$($(1)TARGET_ARCH)) \
-		--instruction-set=$$($(1)TARGET_ARCH) --instruction-set-features=$$(TARGET_INSTRUCTION_SET_FEATURES) --android-root=$$(PRODUCT_OUT)/system
+	$$(hide) $$(DEX2OATD) --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=$$($(1)TARGET_INSTRUCTION_SET_FEATURES) \
+	  --implicit-checks=$(IMPLICIT_CHECKS_$($(1)TARGET_ARCH)) \
+	  --android-root=$$(PRODUCT_OUT)/system
 
 # This "renaming" eases declaration in art/Android.mk
 TARGET_CORE_IMG_OUT$($(1)ART_PHONY_TEST_TARGET_SUFFIX) := $($(1)TARGET_CORE_IMG_OUT)
 
 $$($(1)TARGET_CORE_OAT_OUT): $$($(1)TARGET_CORE_IMG_OUT)
-endef
+endef  # create-core-oat-target-rules
 
 ifdef TARGET_2ND_ARCH
-  $(eval $(call create-oat-target-targets,2ND_))
+$(eval $(call create-core-oat-target-rules,2ND_))
 endif
-$(eval $(call create-oat-target-targets,))
+$(eval $(call create-core-oat-target-rules,))
 
 
 ifeq ($(ART_BUILD_HOST),true)
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 6d2f5d1..e197c97 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include art/build/Android.common.mk
+include art/build/Android.common_build.mk
 
 LIBART_COMPILER_SRC_FILES := \
 	compiled_method.cc \
@@ -249,13 +249,14 @@
   ifeq ($$(art_target_or_host),host)
     LOCAL_LDLIBS += -ldl -lpthread
   endif
-  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
   LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
   ifeq ($$(art_target_or_host),target)
     LOCAL_SHARED_LIBRARIES += libcutils libvixl
     include $(BUILD_SHARED_LIBRARY)
   else # host
     LOCAL_STATIC_LIBRARIES += libcutils libvixl
+    LOCAL_MULTILIB := both
     include $(BUILD_HOST_SHARED_LIBRARY)
   endif
 
diff --git a/dalvikvm/Android.mk b/dalvikvm/Android.mk
index 31fcd17..5d838c0 100644
--- a/dalvikvm/Android.mk
+++ b/dalvikvm/Android.mk
@@ -33,7 +33,7 @@
 include external/libcxx/libcxx.mk
 include $(BUILD_EXECUTABLE)
 
-# create symlink for the primary version target.
+# Create symlink for the primary version target.
 include  $(BUILD_SYSTEM)/executable_prefer_symlink.mk
 
 ART_TARGET_EXECUTABLES += $(TARGET_OUT_EXECUTABLES)/$(LOCAL_MODULE)
@@ -50,6 +50,13 @@
 LOCAL_LDFLAGS := -ldl -lpthread
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_IS_HOST_MODULE := true
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := dalvikvm32
+LOCAL_MODULE_STEM_64 := dalvikvm64
 include external/libcxx/libcxx.mk
 include $(BUILD_HOST_EXECUTABLE)
-ART_HOST_EXECUTABLES += $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)
+
+ART_HOST_EXECUTABLES += $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)32
+ifneq ($(HOST_PREFER_32_BIT),true)
+  ART_HOST_EXECUTABLES += $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)64
+endif
\ No newline at end of file
diff --git a/disassembler/Android.mk b/disassembler/Android.mk
index feacbde..a0abc9e 100644
--- a/disassembler/Android.mk
+++ b/disassembler/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include art/build/Android.common.mk
+include art/build/Android.common_build.mk
 
 LIBART_DISASSEMBLER_SRC_FILES := \
 	disassembler.cc \
@@ -80,7 +80,7 @@
 
   LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime
 
-  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
   LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
   include external/libcxx/libcxx.mk
   ifeq ($$(art_target_or_host),target)
diff --git a/oatdump/Android.mk b/oatdump/Android.mk
index ecf6a0b..c35ff85 100644
--- a/oatdump/Android.mk
+++ b/oatdump/Android.mk
@@ -16,11 +16,11 @@
 
 LOCAL_PATH := $(call my-dir)
 
+include art/build/Android.executable.mk
+
 OATDUMP_SRC_FILES := \
 	oatdump.cc
 
-include art/build/Android.executable.mk
-
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
   $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libcutils libart-disassembler,art/disassembler,target,ndebug))
 endif
@@ -34,3 +34,62 @@
 ifeq ($(ART_BUILD_HOST_DEBUG),true)
   $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libartd-disassembler,art/disassembler,host,debug))
 endif
+
+########################################################################
+# oatdump targets
+
+ART_DUMP_OAT_PATH ?= $(OUT_DIR)
+
+OATDUMP := $(HOST_OUT_EXECUTABLES)/oatdump$(HOST_EXECUTABLE_SUFFIX)
+OATDUMPD := $(HOST_OUT_EXECUTABLES)/oatdumpd$(HOST_EXECUTABLE_SUFFIX)
+# TODO: for now, override with debug version for better error reporting
+OATDUMP := $(OATDUMPD)
+
+.PHONY: dump-oat
+dump-oat: dump-oat-core dump-oat-boot
+
+.PHONY: dump-oat-core
+dump-oat-core: dump-oat-core-host dump-oat-core-target
+
+.PHONY: dump-oat-core-host
+ifeq ($(ART_BUILD_HOST),true)
+dump-oat-core-host: $(HOST_CORE_IMG_OUT) $(OATDUMP)
+	$(OATDUMP) --image=$(HOST_CORE_IMG_LOCATION) --output=$(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
+	@echo Output in $(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
+endif
+
+.PHONY: dump-oat-core-target
+ifeq ($(ART_BUILD_TARGET),true)
+dump-oat-core-target: $(TARGET_CORE_IMG_OUT) $(OATDUMP)
+	$(OATDUMP) --image=$(TARGET_CORE_IMG_LOCATION) \
+	  --output=$(ART_DUMP_OAT_PATH)/core.target.oatdump.txt --instruction-set=$(TARGET_ARCH)
+	@echo Output in $(ART_DUMP_OAT_PATH)/core.target.oatdump.txt
+endif
+
+.PHONY: dump-oat-boot-$(TARGET_ARCH)
+ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+dump-oat-boot-$(TARGET_ARCH): $(DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) $(OATDUMP)
+	$(OATDUMP) --image=$(DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION) \
+	  --output=$(ART_DUMP_OAT_PATH)/boot.$(TARGET_ARCH).oatdump.txt --instruction-set=$(TARGET_ARCH)
+	@echo Output in $(ART_DUMP_OAT_PATH)/boot.$(TARGET_ARCH).oatdump.txt
+endif
+
+ifdef TARGET_2ND_ARCH
+dump-oat-boot-$(TARGET_2ND_ARCH): $(2ND_DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) $(OATDUMP)
+	$(OATDUMP) --image=$(2ND_DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION) \
+	  --output=$(ART_DUMP_OAT_PATH)/boot.$(TARGET_2ND_ARCH).oatdump.txt --instruction-set=$(TARGET_2ND_ARCH)
+	@echo Output in $(ART_DUMP_OAT_PATH)/boot.$(TARGET_2ND_ARCH).oatdump.txt
+endif
+
+.PHONY: dump-oat-boot
+dump-oat-boot: dump-oat-boot-$(TARGET_ARCH)
+ifdef TARGET_2ND_ARCH
+dump-oat-boot: dump-oat-boot-$(TARGET_2ND_ARCH)
+endif
+
+.PHONY: dump-oat-Calculator
+ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+dump-oat-Calculator: $(TARGET_OUT_APPS)/Calculator.odex $(DEFAULT_DEX_PREOPT_BUILT_IMAGE) $(OATDUMP)
+	$(OATDUMP) --oat-file=$< --output=$(ART_DUMP_OAT_PATH)/Calculator.oatdump.txt
+	@echo Output in $(ART_DUMP_OAT_PATH)/Calculator.oatdump.txt
+endif
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 992202a..c6ac9ca 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include art/build/Android.common.mk
+include art/build/Android.common_build.mk
 
 LIBART_COMMON_SRC_FILES := \
 	atomic.cc.arm \
@@ -268,10 +268,6 @@
 $(info TODOMips64: $(LOCAL_PATH)/Android.mk Add mips64 specific runtime files)
 endif # TARGET_ARCH != mips64
 
-ifeq (,$(filter $(TARGET_ARCH),$(ART_SUPPORTED_ARCH)))
-$(warning unsupported TARGET_ARCH=$(TARGET_ARCH))
-endif
-
 LIBART_HOST_SRC_FILES := \
 	$(LIBART_COMMON_SRC_FILES) \
 	base/logging_linux.cc \
@@ -335,8 +331,8 @@
   art_target_or_host := $(1)
   art_ndebug_or_debug := $(2)
 
-  include $(CLEAR_VARS)
-  LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
+  include $$(CLEAR_VARS)
+  LOCAL_CPP_EXTENSION := $$(ART_CPP_EXTENSION)
   ifeq ($$(art_ndebug_or_debug),ndebug)
     LOCAL_MODULE := libart
   else # debug
@@ -347,13 +343,13 @@
   LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 
   ifeq ($$(art_target_or_host),target)
-    LOCAL_SRC_FILES := $(LIBART_TARGET_SRC_FILES)
-    $(foreach arch,$(ART_SUPPORTED_ARCH),
-      LOCAL_SRC_FILES_$(arch) := $$(LIBART_TARGET_SRC_FILES_$(arch)))
+    LOCAL_SRC_FILES := $$(LIBART_TARGET_SRC_FILES)
+    $$(foreach arch,$$(ART_TARGET_SUPPORTED_ARCH), \
+      $$(eval LOCAL_SRC_FILES_$$(arch) := $$$$(LIBART_TARGET_SRC_FILES_$$(arch))))
   else # host
-    LOCAL_SRC_FILES := $(LIBART_HOST_SRC_FILES)
-    LOCAL_SRC_FILES_32 := $(LIBART_HOST_SRC_FILES_32)
-    LOCAL_SRC_FILES_64 := $(LIBART_HOST_SRC_FILES_64)
+    LOCAL_SRC_FILES := $$(LIBART_HOST_SRC_FILES)
+    LOCAL_SRC_FILES_32 := $$(LIBART_HOST_SRC_FILES_32)
+    LOCAL_SRC_FILES_64 := $$(LIBART_HOST_SRC_FILES_64)
     LOCAL_IS_HOST_MODULE := true
   endif
 
@@ -368,43 +364,43 @@
 
   LOCAL_GENERATED_SOURCES += $$(ENUM_OPERATOR_OUT_GEN)
 
-  LOCAL_CFLAGS := $(LIBART_CFLAGS)
-  LOCAL_LDFLAGS := $(LIBART_LDFLAGS)
+  LOCAL_CFLAGS := $$(LIBART_CFLAGS)
+  LOCAL_LDFLAGS := $$(LIBART_LDFLAGS)
   ifeq ($$(art_target_or_host),target)
-    LOCAL_LDFLAGS += $(LIBART_TARGET_LDFLAGS)
+    LOCAL_LDFLAGS += $$(LIBART_TARGET_LDFLAGS)
   else
-    LOCAL_LDFLAGS += $(LIBART_HOST_LDFLAGS)
+    LOCAL_LDFLAGS += $$(LIBART_HOST_LDFLAGS)
   endif
-  $(foreach arch,$(ART_SUPPORTED_ARCH),
-    LOCAL_LDFLAGS_$(arch) := $$(LIBART_TARGET_LDFLAGS_$(arch)))
+  $$(foreach arch,$$(ART_TARGET_SUPPORTED_ARCH), \
+    $$(eval LOCAL_LDFLAGS_$$(arch) := $$(LIBART_TARGET_LDFLAGS_$$(arch))))
 
   # Clang usage
   ifeq ($$(art_target_or_host),target)
-    $(call set-target-local-clang-vars)
-    $(call set-target-local-cflags-vars,$(2))
+    $$(eval $$(call set-target-local-clang-vars))
+    $$(eval $$(call set-target-local-cflags-vars,$(2)))
     # TODO: Loop with ifeq, ART_TARGET_CLANG
-    ifneq ($$(ART_TARGET_CLANG_$(TARGET_ARCH)),true)
-      LOCAL_SRC_FILES_$(TARGET_ARCH) += $(LIBART_GCC_ONLY_SRC_FILES)
+    ifneq ($$(ART_TARGET_CLANG_$$(TARGET_ARCH)),true)
+      LOCAL_SRC_FILES_$$(TARGET_ARCH) += $$(LIBART_GCC_ONLY_SRC_FILES)
     endif
-    ifneq ($$(ART_TARGET_CLANG_$(TARGET_2ND_ARCH)),true)
-      LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) += $(LIBART_GCC_ONLY_SRC_FILES)
+    ifneq ($$(ART_TARGET_CLANG_$$(TARGET_2ND_ARCH)),true)
+      LOCAL_SRC_FILES_$$(TARGET_2ND_ARCH) += $$(LIBART_GCC_ONLY_SRC_FILES)
     endif
   else # host
-    LOCAL_CLANG := $(ART_HOST_CLANG)
-    ifeq ($(ART_HOST_CLANG),false)
-      LOCAL_SRC_FILES += $(LIBART_GCC_ONLY_SRC_FILES)
+    LOCAL_CLANG := $$(ART_HOST_CLANG)
+    ifeq ($$(ART_HOST_CLANG),false)
+      LOCAL_SRC_FILES += $$(LIBART_GCC_ONLY_SRC_FILES)
     endif
-    LOCAL_CFLAGS += $(ART_HOST_CFLAGS)
+    LOCAL_CFLAGS += $$(ART_HOST_CFLAGS)
     ifeq ($$(art_ndebug_or_debug),debug)
-      LOCAL_CFLAGS += $(ART_HOST_DEBUG_CFLAGS)
-      LOCAL_LDLIBS += $(ART_HOST_DEBUG_LDLIBS)
+      LOCAL_CFLAGS += $$(ART_HOST_DEBUG_CFLAGS)
+      LOCAL_LDLIBS += $$(ART_HOST_DEBUG_LDLIBS)
       LOCAL_STATIC_LIBRARIES := libgtest_host
     else
-      LOCAL_CFLAGS += $(ART_HOST_NON_DEBUG_CFLAGS)
+      LOCAL_CFLAGS += $$(ART_HOST_NON_DEBUG_CFLAGS)
     endif
   endif
 
-  LOCAL_C_INCLUDES += $(ART_C_INCLUDES)
+  LOCAL_C_INCLUDES += $$(ART_C_INCLUDES)
   LOCAL_C_INCLUDES += art/sigchainlib
 
   LOCAL_SHARED_LIBRARIES += liblog libnativehelper
@@ -416,23 +412,24 @@
   else # host
     LOCAL_STATIC_LIBRARIES += libcutils libziparchive-host libz libutils
     LOCAL_LDLIBS += -ldl -lpthread
-    ifeq ($(HOST_OS),linux)
+    ifeq ($$(HOST_OS),linux)
       LOCAL_LDLIBS += -lrt
     endif
+    LOCAL_MULTILIB := both
   endif
-  ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-    include $(LLVM_GEN_INTRINSICS_MK)
+  ifeq ($$(ART_USE_PORTABLE_COMPILER),true)
+    include $$(LLVM_GEN_INTRINSICS_MK)
     ifeq ($$(art_target_or_host),target)
-      include $(LLVM_DEVICE_BUILD_MK)
+      include $$(LLVM_DEVICE_BUILD_MK)
     else # host
-      include $(LLVM_HOST_BUILD_MK)
+      include $$(LLVM_HOST_BUILD_MK)
     endif
   endif
-  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
-  LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+#  LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk
 
   ifeq ($$(art_target_or_host),target)
-    LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
+    LOCAL_MODULE_TARGET_ARCH := $$(ART_TARGET_SUPPORTED_ARCH)
   endif
 
   ifeq ($$(art_target_or_host),target)
@@ -441,10 +438,17 @@
       # produce meaningful name resolution.
       LOCAL_STRIP_MODULE := keep_symbols
     endif
-    include $(BUILD_SHARED_LIBRARY)
+    include $$(BUILD_SHARED_LIBRARY)
   else # host
-    include $(BUILD_HOST_SHARED_LIBRARY)
+    include $$(BUILD_HOST_SHARED_LIBRARY)
   endif
+
+  # Clear locally defined variables.
+  GENERATED_SRC_DIR :=
+  ENUM_OPERATOR_OUT_CC_FILES :=
+  ENUM_OPERATOR_OUT_GEN :=
+  art_target_or_host :=
+  art_ndebug_or_debug :=
 endef
 
 # We always build dex2oat and dependencies, even if the host build is otherwise disabled, since
@@ -457,9 +461,28 @@
 endif
 
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
+#  $(error $(call build-libart,target,ndebug))
   $(eval $(call build-libart,target,ndebug))
 endif
 ifeq ($(ART_BUILD_TARGET_DEBUG),true)
   $(eval $(call build-libart,target,debug))
 endif
 
+# Clear locally defined variables.
+LOCAL_PATH :=
+LIBART_COMMON_SRC_FILES :=
+LIBART_GCC_ONLY_SRC_FILES :=
+LIBART_TARGET_LDFLAGS :=
+LIBART_HOST_LDFLAGS :=
+LIBART_TARGET_SRC_FILES :=
+LIBART_TARGET_SRC_FILES_arm :=
+LIBART_TARGET_SRC_FILES_arm64 :=
+LIBART_TARGET_SRC_FILES_x86 :=
+LIBART_TARGET_SRC_FILES_x86_64 :=
+LIBART_TARGET_SRC_FILES_mips :=
+LIBART_HOST_SRC_FILES :=
+LIBART_HOST_SRC_FILES_32 :=
+LIBART_HOST_SRC_FILES_64 :=
+LIBART_ENUM_OPERATOR_OUT_HEADER_FILES :=
+LIBART_CFLAGS :=
+build-libart :=
\ No newline at end of file
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index bac212a..044d08b 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -273,7 +273,7 @@
     } else {
       filename += "/data/nativetest/art/";
     }
-    filename += "art-test-dex-";
+    filename += "art-gtest-";
     filename += name;
     filename += ".jar";
     std::string error_msg;
diff --git a/sigchainlib/Android.mk b/sigchainlib/Android.mk
index cb1778d..8e25339 100644
--- a/sigchainlib/Android.mk
+++ b/sigchainlib/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-include art/build/Android.common.mk
+include art/build/Android.common_build.mk
 
 include $(CLEAR_VARS)
 LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
@@ -24,6 +24,7 @@
 LOCAL_CFLAGS += $(ART_TARGET_CFLAGS)
 LOCAL_SRC_FILES := sigchain.cc
 LOCAL_MODULE:= libsigchain
-LOCAL_SHARED_LIBRARIES += liblog libdl
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+LOCAL_SHARED_LIBRARIES := liblog libdl
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.common_build.mk
 include $(BUILD_SHARED_LIBRARY)
diff --git a/build/Android.libarttest.mk b/test/Android.libarttest.mk
similarity index 70%
rename from build/Android.libarttest.mk
rename to test/Android.libarttest.mk
index 76e5af0..bf3e2aa 100644
--- a/build/Android.libarttest.mk
+++ b/test/Android.libarttest.mk
@@ -14,16 +14,20 @@
 # limitations under the License.
 #
 
-LIBARTTEST_COMMON_SRC_FILES := \
-	test/JniTest/jni_test.cc \
-	test/SignalTest/signaltest.cc \
-	test/ReferenceMap/stack_walk_refmap_jni.cc \
-	test/StackWalk/stack_walk_jni.cc \
-	test/UnsafeTest/unsafe_test.cc
+LOCAL_PATH := $(call my-dir)
 
-ART_TARGET_LIBARTTEST_$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TEST_OUT)/$(TARGET_ARCH)/libarttest.so
+include art/build/Android.common_build.mk
+
+LIBARTTEST_COMMON_SRC_FILES := \
+  JniTest/jni_test.cc \
+  SignalTest/signaltest.cc \
+  ReferenceMap/stack_walk_refmap_jni.cc \
+  StackWalk/stack_walk_jni.cc \
+  UnsafeTest/unsafe_test.cc
+
+ART_TARGET_LIBARTTEST_$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libarttest.so
 ifdef TARGET_2ND_ARCH
-  ART_TARGET_LIBARTTEST_$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TEST_OUT)/$(TARGET_2ND_ARCH)/libarttest.so
+  ART_TARGET_LIBARTTEST_$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libarttest.so
 endif
 
 # $(1): target or host
@@ -45,17 +49,17 @@
   LOCAL_SRC_FILES := $(LIBARTTEST_COMMON_SRC_FILES)
   LOCAL_SHARED_LIBRARIES += libartd
   LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime
-  LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/build/Android.common.mk
-  LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/build/Android.libarttest.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.libarttest.mk
   include external/libcxx/libcxx.mk
   ifeq ($$(art_target_or_host),target)
-  	$(call set-target-local-clang-vars)
-  	$(call set-target-local-cflags-vars,debug)
+    $(call set-target-local-clang-vars)
+    $(call set-target-local-cflags-vars,debug)
     LOCAL_SHARED_LIBRARIES += libdl libcutils
     LOCAL_STATIC_LIBRARIES := libgtest
     LOCAL_MULTILIB := both
-    LOCAL_MODULE_PATH_32 := $(ART_TEST_OUT)/$(ART_TARGET_ARCH_32)
-    LOCAL_MODULE_PATH_64 := $(ART_TEST_OUT)/$(ART_TARGET_ARCH_64)
+    LOCAL_MODULE_PATH_32 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_32)
+    LOCAL_MODULE_PATH_64 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_64)
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
     include $(BUILD_SHARED_LIBRARY)
   else # host
@@ -67,8 +71,12 @@
       LOCAL_LDLIBS += -lrt
     endif
     LOCAL_IS_HOST_MODULE := true
+    LOCAL_MULTILIB := both
     include $(BUILD_HOST_SHARED_LIBRARY)
   endif
+
+  # Clear locally used variables.
+  art_target_or_host :=
 endef
 
 ifeq ($(ART_BUILD_TARGET),true)
@@ -77,3 +85,7 @@
 ifeq ($(ART_BUILD_HOST),true)
   $(eval $(call build-libarttest,host))
 endif
+
+# Clear locally used variables.
+LOCAL_PATH :=
+LIBARTTEST_COMMON_SRC_FILES :=
diff --git a/test/Android.mk b/test/Android.mk
deleted file mode 100644
index 7897449..0000000
--- a/test/Android.mk
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include art/build/Android.common.mk
-
-########################################################################
-
-# subdirectories which are used as inputs for gtests
-TEST_DEX_DIRECTORIES := \
-	AbstractMethod \
-	AllFields \
-	ExceptionHandle \
-	GetMethodSignature \
-	Interfaces \
-	Main \
-	MyClass \
-	MyClassNatives \
-	Nested \
-	NonStaticLeafMethods \
-	ProtoCompare \
-	ProtoCompare2 \
-	StaticLeafMethods \
-	Statics \
-	StaticsFromCode \
-	Transaction \
-	XandY
-
-# subdirectories of which are used with test-art-target-oat
-# Declare the simplest tests (Main, HelloWorld) first, the rest are alphabetical
-TEST_OAT_DIRECTORIES := \
-	Main \
-	HelloWorld \
-	InterfaceTest \
-	JniTest \
-	SignalTest \
-	NativeAllocations \
-	ParallelGC \
-	ReferenceMap \
-	StackWalk \
-	ThreadStress \
-	UnsafeTest
-
-# TODO: Enable when the StackWalk2 tests are passing
-#	StackWalk2 \
-
-ART_TEST_TARGET_DEX_FILES :=
-ART_TEST_TARGET_DEX_FILES$(ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_TEST_TARGET_DEX_FILES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_TEST_HOST_DEX_FILES :=
-
-# $(1): module prefix
-# $(2): input test directory
-# $(3): target output module path (default module path is used on host)
-define build-art-test-dex
-  ifeq ($(ART_BUILD_TARGET),true)
-    include $(CLEAR_VARS)
-    LOCAL_MODULE := $(1)-$(2)
-    LOCAL_MODULE_TAGS := tests
-    LOCAL_SRC_FILES := $(call all-java-files-under, $(2))
-    LOCAL_JAVA_LIBRARIES := $(TARGET_CORE_JARS)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_MODULE_PATH := $(3)
-    LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
-    LOCAL_DEX_PREOPT := false
-    LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
-    LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-    include $(BUILD_JAVA_LIBRARY)
-
-    ART_TEST_TARGET_DEX_FILES += $$(LOCAL_INSTALLED_MODULE)
-    ART_TEST_TARGET_DEX_FILES$(ART_PHONY_TEST_TARGET_SUFFIX) += $$(LOCAL_INSTALLED_MODULE)
-  endif
-
-  ifeq ($(ART_BUILD_HOST),true)
-    include $(CLEAR_VARS)
-    LOCAL_MODULE := $(1)-$(2)
-    LOCAL_SRC_FILES := $(call all-java-files-under, $(2))
-    LOCAL_JAVA_LIBRARIES := $(HOST_CORE_JARS)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
-    LOCAL_DEX_PREOPT := false
-    LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
-    LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-    ART_TEST_HOST_DEX_FILES += $$(LOCAL_INSTALLED_MODULE)
-  endif
-endef
-$(foreach dir,$(TEST_DEX_DIRECTORIES), $(eval $(call build-art-test-dex,art-test-dex,$(dir),$(ART_NATIVETEST_OUT))))
-$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call build-art-test-dex,oat-test-dex,$(dir),$(ART_TEST_OUT))))
-
-# Used outside the art project to get a list of the current tests
-ART_TEST_DEX_MAKE_TARGETS := $(addprefix art-test-dex-, $(TEST_DEX_DIRECTORIES))
-ART_TEST_OAT_MAKE_TARGETS := $(addprefix oat-test-dex-, $(TEST_OAT_DIRECTORIES))
-
-########################################################################
-
-ART_TEST_TARGET_OAT_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_TEST_TARGET_OAT_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
-ART_TEST_HOST_OAT_DEFAULT_TARGETS :=
-ART_TEST_HOST_OAT_INTERPRETER_TARGETS :=
-
-define declare-test-art-oat-targets-impl
-.PHONY: test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
-test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX): $(ART_TEST_OUT)/oat-test-dex-$(1).jar test-art-target-sync
-	adb shell touch $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@
-	adb shell rm $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@
-	adb shell sh -c "/system/bin/dalvikvm$($(2)ART_PHONY_TEST_TARGET_SUFFIX) $(DALVIKVM_FLAGS) -XXlib:libartd.so -Ximage:$(ART_TEST_DIR)/core.art -classpath $(ART_TEST_DIR)/oat-test-dex-$(1).jar -Djava.library.path=$(ART_TEST_DIR)/$(TARGET_$(2)ARCH) $(1) && touch $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@"
-	$(hide) (adb pull $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
-	$(hide) rm /tmp/$$@
-endef
-
-# $(1): directory
-# $(2): arguments
-define declare-test-art-oat-targets
-  ifdef TARGET_2ND_ARCH
-    $(call declare-test-art-oat-targets-impl,$(1),2ND_)
-
-    # Bind the primary to the non-suffix rule
-    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
-test-art-target-oat-$(1): test-art-target-oat-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
-    endif
-  endif
-  $(call declare-test-art-oat-targets-impl,$(1),)
-
-$(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/oat-test-dex-$(1).odex: $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar $(HOST_CORE_IMG_OUT) | $(DEX2OATD)
-	$(DEX2OATD) $(DEX2OAT_FLAGS) --runtime-arg -Xms16m --runtime-arg -Xmx16m --boot-image=$(HOST_CORE_IMG_LOCATION) --dex-file=$$(realpath $$<) --oat-file=$$@ --instruction-set=$(ART_HOST_ARCH) --host --android-root=$(HOST_OUT)
-
-.PHONY: test-art-host-oat-default-$(1)
-test-art-host-oat-default-$(1): $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/oat-test-dex-$(1).odex test-art-host-dependencies
-	mkdir -p /tmp/android-data/test-art-host-oat-default-$(1)
-	ANDROID_DATA=/tmp/android-data/test-art-host-oat-default-$(1) \
-	  ANDROID_ROOT=$(HOST_OUT) \
-	  LD_LIBRARY_PATH=$(HOST_LIBRARY_PATH) \
-	  $(HOST_OUT_EXECUTABLES)/dalvikvm $(DALVIKVM_FLAGS) -XXlib:libartd$(HOST_SHLIB_SUFFIX) -Ximage:$(HOST_CORE_IMG_LOCATION) -classpath $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar -Djava.library.path=$(HOST_LIBRARY_PATH) $(1) $(2) \
-          && echo test-art-host-oat-default-$(1) PASSED || (echo test-art-host-oat-default-$(1) FAILED && exit 1)
-	$(hide) rm -r /tmp/android-data/test-art-host-oat-default-$(1)
-
-.PHONY: test-art-host-oat-interpreter-$(1)
-test-art-host-oat-interpreter-$(1): $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/oat-test-dex-$(1).odex test-art-host-dependencies
-	mkdir -p /tmp/android-data/test-art-host-oat-interpreter-$(1)
-	ANDROID_DATA=/tmp/android-data/test-art-host-oat-interpreter-$(1) \
-	  ANDROID_ROOT=$(HOST_OUT) \
-	  LD_LIBRARY_PATH=$(HOST_LIBRARY_PATH) \
-	  $(HOST_OUT_EXECUTABLES)/dalvikvm -XXlib:libartd$(HOST_SHLIB_SUFFIX) -Ximage:$(HOST_CORE_IMG_LOCATION) $(DALVIKVM_FLAGS) -Xint -classpath $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar -Djava.library.path=$(HOST_LIBRARY_PATH) $(1) $(2) \
-          && echo test-art-host-oat-interpreter-$(1) PASSED || (echo test-art-host-oat-interpreter-$(1) FAILED && exit 1)
-	$(hide) rm -r /tmp/android-data/test-art-host-oat-interpreter-$(1)
-
-.PHONY: test-art-host-oat-$(1)
-test-art-host-oat-$(1): test-art-host-oat-default-$(1) test-art-host-oat-interpreter-$(1)
-
-.PHONY: test-art-oat-$(1)
-test-art-oat-$(1): test-art-host-oat-$(1) test-art-target-oat-$(1)
-
-ART_TEST_TARGET_OAT_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-oat-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
-ifdef TARGET_2ND_ARCH
-  ART_TEST_TARGET_OAT_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-oat-$(1)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
-endif
-ART_TEST_HOST_OAT_DEFAULT_TARGETS += test-art-host-oat-default-$(1)
-ART_TEST_HOST_OAT_INTERPRETER_TARGETS += test-art-host-oat-interpreter-$(1)
-endef
-$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call declare-test-art-oat-targets,$(dir))))
-
-########################################################################
-
-TEST_ART_RUN_TEST_MAKE_TARGETS :=
-art_run_tests_dir := $(call intermediates-dir-for,PACKAGING,art-run-tests)/DATA
-
-# Helper to create individual build targets for tests.
-# Must be called with $(eval)
-# $(1): the test number
-define declare-make-art-run-test
-dmart_target := $(art_run_tests_dir)/art-run-tests/$(1)/touch
-$$(dmart_target): $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
-	$(hide) rm -rf $$(dir $$@) && mkdir -p $$(dir $$@)
-	$(hide) DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) $(LOCAL_PATH)/run-test --build-only --output-path $$(abspath $$(dir $$@)) $(1)
-	$(hide) touch $$@
-
-
-TEST_ART_RUN_TEST_MAKE_TARGETS += $$(dmart_target)
-dmart_target :=
-endef
-
-# Expand all tests.
-TEST_ART_RUN_TESTS := $(wildcard $(LOCAL_PATH)/[0-9]*)
-TEST_ART_RUN_TESTS := $(subst $(LOCAL_PATH)/,, $(TEST_ART_RUN_TESTS))
-TEST_ART_TIMING_SENSITIVE_RUN_TESTS := 053-wait-some 055-enum-performance
-ifdef dist_goal # disable timing sensitive tests on "dist" builds.
-  $(foreach test, $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), \
-    $(info Skipping $(test)) \
-    $(eval TEST_ART_RUN_TESTS := $(filter-out $(test), $(TEST_ART_RUN_TESTS))))
-endif
-$(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call declare-make-art-run-test,$(test))))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE := art-run-tests
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TEST_ART_RUN_TEST_MAKE_TARGETS)
-# The build system use this flag to pick up files generated by declare-make-art-run-test.
-LOCAL_PICKUP_FILES := $(art_run_tests_dir)
-
-include $(BUILD_PHONY_PACKAGE)
-
-# clear temp vars
-TEST_ART_RUN_TEST_MAKE_TARGETS :=
-declare-make-art-run-test :=
-
-########################################################################
diff --git a/test/Android.oat.mk b/test/Android.oat.mk
new file mode 100644
index 0000000..6e43ab6
--- /dev/null
+++ b/test/Android.oat.mk
@@ -0,0 +1,449 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+LOCAL_PID := $(shell echo $$PPID)
+
+include art/build/Android.common_test.mk
+
+########################################################################
+
+# Subdirectories in art/test which contain dex files used as inputs for oat tests. Declare the
+# simplest tests (Main, HelloWorld) first, the rest are alphabetical.
+TEST_OAT_DIRECTORIES := \
+  Main \
+  HelloWorld \
+  InterfaceTest \
+  JniTest \
+  SignalTest \
+  NativeAllocations \
+  ParallelGC \
+  ReferenceMap \
+  StackWalk \
+  ThreadStress \
+  UnsafeTest
+
+# TODO: Enable when the StackWalk2 tests are passing
+#  StackWalk2 \
+
+# Create build rules for each dex file recording the dependency.
+$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call build-art-test-dex,art-oat-test,$(dir), \
+  $(ART_TARGET_TEST_OUT),$(LOCAL_PATH)/Android.oat.mk,ART_OAT_TEST_$(dir)_DEX)))
+
+########################################################################
+
+include $(LOCAL_PATH)/Android.libarttest.mk
+
+ART_TEST_TARGET_OAT_DEFAULT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_DEFAULT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_DEFAULT_RULES :=
+ART_TEST_TARGET_OAT_OPTIMIZING$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_OPTIMIZING$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_OPTIMIZING_RULES :=
+ART_TEST_TARGET_OAT_INTERPRETER$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_INTERPRETER$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_INTERPRETER_RULES :=
+ART_TEST_TARGET_OAT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_RULES :=
+
+# We need dex2oat and dalvikvm on the target as well as the core image.
+TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_EXECUTABLES) $(TARGET_CORE_IMG_OUT) $(2ND_TARGET_CORE_IMG_OUT)
+
+# Define rule to run an individual oat test on the host. Output from the test is written to the
+# host in /tmp/android-data in a directory named after test's rule name (its target) and the parent
+# process' PID (ie the PID of make). On failure the output is dumped to the console. To test for
+# success on the target device a file is created following a successful test and this is pulled
+# onto the host. If the pull fails then the file wasn't created because the test failed.
+# $(1): directory - the name of the test we're building such as HelloWorld.
+# $(2): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
+# $(3): the target (rule name), e.g. test-art-target-oat-default-HelloWorld64
+# $(4): -Xint or undefined - do we want to run with the interpreter or default.
+define define-test-art-oat-rule-target
+  # Add the test dependencies to test-art-target-sync, which will be a prerequisit for the test
+  # to ensure files are pushed to the device.
+  TEST_ART_TARGET_SYNC_DEPS += $$(ART_OAT_TEST_$(1)_DEX)
+
+.PHONY: $(3)
+$(3): test-art-target-sync
+	$(hide) mkdir -p $(ART_HOST_TEST_DIR)/android-data-$$@
+	$(hide) echo Running: $$@
+	$(hide) adb shell touch $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$(LOCAL_PID)
+	$(hide) adb shell rm $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$(LOCAL_PID)
+	$(hide) $$(call ART_TEST_SKIP,$$@) && \
+	  adb shell sh -c "/system/bin/dalvikvm$($(2)ART_PHONY_TEST_TARGET_SUFFIX) \
+	    $(DALVIKVM_FLAGS) $(4) -XXlib:libartd.so -Ximage:$(ART_TARGET_TEST_DIR)/core.art \
+	    -classpath $(ART_TARGET_TEST_DIR)/art-oat-test-$(1).jar \
+	    -Djava.library.path=$(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH) $(1) \
+	      && touch $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$(LOCAL_PID)" \
+	        > $(ART_HOST_TEST_DIR)/android-data-$$@/output.txt 2>&1 && \
+	  (adb pull $(ART_TARGET_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@-$(LOCAL_PID) $(ART_HOST_TEST_DIR)/android-data-$$@ \
+	    && $$(call ART_TEST_PASSED,$$@)) \
+	    || (([ ! -f $(ART_HOST_TEST_DIR)/android-data-$$@/output.txt ] || \
+	         cat $(ART_HOST_TEST_DIR)/android-data-$$@/output.txt) && $$(call ART_TEST_FAILED,$$@))
+	$$(hide) (echo $(MAKECMDGOALS) | grep -q $$@ && \
+	  echo "run-test run as top-level target, removing test directory $(ART_HOST_TEST_DIR)" && \
+	  rm -r $(ART_HOST_TEST_DIR)) || true
+
+endef  # define-test-art-oat-rule-target
+
+# Define rules to run oat tests on the target.
+# $(1): directory - the name of the test we're building such as HelloWorld.
+# $(2): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
+define define-test-art-oat-rules-target
+  # Define a phony rule to run a target oat test using the default compiler.
+  default_test_rule := test-art-target-oat-default-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
+  $(call define-test-art-oat-rule-target,$(1),$(2),$$(default_test_rule),)
+
+  ART_TEST_TARGET_OAT_DEFAULT$$($(2)ART_PHONY_TEST_TARGET_SUFFIX)_RULES += $$(default_test_rule)
+  ART_TEST_TARGET_OAT_DEFAULT_RULES += $$(default_test_rule)
+  ART_TEST_TARGET_OAT_DEFAULT_$(1)_RULES += $$(default_test_rule)
+
+  optimizing_test_rule := test-art-target-oat-optimizing-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
+  $(call define-test-art-oat-rule-target,$(1),$(2),$$(optimizing_test_rule), \
+    -Xcompiler-option --compiler-backend=Optimizing)
+
+  # Mark all tests with the optimizing compiler broken. TODO: fix.
+  ART_TEST_KNOWN_BROKEN += $$(optimizing_test_rule)
+
+  ART_TEST_TARGET_OAT_OPTIMIZING$$($(2)ART_PHONY_TEST_TARGET_SUFFIX)_RULES += $$(optimizing_test_rule)
+  ART_TEST_TARGET_OAT_OPTIMIZING_RULES += $$(optimizing_test_rule)
+  ART_TEST_TARGET_OAT_OPTIMIZING_$(1)_RULES += $$(optimizing_test_rule)
+
+  # Define a phony rule to run a target oat test using the interpeter.
+  interpreter_test_rule := test-art-target-oat-interpreter-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
+  $(call define-test-art-oat-rule-target,$(1),$(2),$$(interpreter_test_rule),-Xint)
+
+  ART_TEST_TARGET_OAT_INTERPRETER$$($(2)ART_PHONY_TEST_TARGET_SUFFIX)_RULES += $$(interpreter_test_rule)
+  ART_TEST_TARGET_OAT_INTERPRETER_RULES += $$(interpreter_test_rule)
+  ART_TEST_TARGET_OAT_INTERPRETER_$(1)_RULES += $$(interpreter_test_rule)
+
+  # Define a phony rule to run both the default and interpreter variants.
+  all_test_rule :=  test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
+.PHONY: $$(all_test_rule)
+$$(all_test_rule): $$(default_test_rule) $$(optimizing_test_rule) $$(interpreter_test_rule)
+	$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+  ART_TEST_TARGET_OAT$$($(2)ART_PHONY_TEST_TARGET_SUFFIX)_RULES += $$(all_test_rule)
+  ART_TEST_TARGET_OAT_RULES += $$(all_test_rule)
+  ART_TEST_TARGET_OAT_$(1)_RULES += $$(all_test_rule)
+
+  # Clear locally defined variables.
+  interpreter_test_rule :=
+  default_test_rule :=
+  optimizing_test_rule :=
+  all_test_rule :=
+endef  # define-test-art-oat-rules-target
+
+ART_TEST_HOST_OAT_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_DEFAULT_RULES :=
+ART_TEST_HOST_OAT_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_OPTIMIZING_RULES :=
+ART_TEST_HOST_OAT_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_INTERPRETER_RULES :=
+ART_TEST_HOST_OAT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_RULES :=
+
+# All tests require the host executables, libarttest and the core images.
+ART_TEST_HOST_OAT_DEPENDENCIES := \
+  $(ART_HOST_EXECUTABLES) \
+  $(HOST_LIBRARY_PATH)/libarttest$(ART_HOST_SHLIB_EXTENSION) \
+  $(HOST_CORE_IMG_OUT) \
+  $(2ND_HOST_CORE_IMG_OUT)
+
+# Define rule to run an individual oat test on the host. Output from the test is written to the
+# host in /tmp/android-data in a directory named after test's rule name (its target) and the parent
+# process' PID (ie the PID of make). On failure the output is dumped to the console.
+# $(1): directory - the name of the test we're building such as HelloWorld.
+# $(2): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
+# $(3): the target (rule name), e.g. test-art-host-oat-default-HelloWorld64
+# $(4): argument to dex2oat
+# $(5): argument to runtime, e.g. -Xint or undefined
+define define-test-art-oat-rule-host
+  # Remove the leading / from /tmp for the test directory.
+  dex_file := $$(subst /tmp,tmp,$(ART_HOST_TEST_DIR))/android-data-$(3)/oat-test-dex-$(1).jar
+  oat_file := $(ART_HOST_TEST_DIR)/android-data-$(3)/dalvik-cache/$$($(2)HOST_ARCH)/$$(subst /,@,$$(dex_file))@classes.dex
+$(3): PRIVATE_DEX_FILE := /$$(dex_file)
+$(3): PRIVATE_OAT_FILE := $$(oat_file)
+.PHONY: $(3)
+$(3): $$(ART_OAT_TEST_$(1)_DEX) $(ART_TEST_HOST_OAT_DEPENDENCIES)
+	$(hide) mkdir -p $(ART_HOST_TEST_DIR)/android-data-$$@/dalvik-cache/$$($(2)HOST_ARCH)
+	$(hide) cp $$(realpath $$<) $(ART_HOST_TEST_DIR)/android-data-$$@/oat-test-dex-$(1).jar
+	$(hide) $(DEX2OATD) $(DEX2OAT_FLAGS) --runtime-arg -Xms16m --runtime-arg -Xmx16m $(4) \
+	  --boot-image=$$(HOST_CORE_IMG_LOCATION) \
+	  --dex-file=$$(PRIVATE_DEX_FILE) --oat-file=$$(PRIVATE_OAT_FILE) \
+	  --instruction-set=$($(2)ART_HOST_ARCH) --host --android-root=$(HOST_OUT) \
+	  || $$(call ART_TEST_FAILED,$$@)
+	$(hide) $$(call ART_TEST_SKIP,$$@) && \
+	ANDROID_DATA=$(ART_HOST_TEST_DIR)/android-data-$$@/ \
+	ANDROID_ROOT=$(HOST_OUT) \
+	ANDROID_LOG_TAGS='*:d' \
+	LD_LIBRARY_PATH=$$($(2)ART_HOST_OUT_SHARED_LIBRARIES) \
+	$(HOST_OUT_EXECUTABLES)/dalvikvm$$($(2)ART_PHONY_TEST_HOST_SUFFIX) $(DALVIKVM_FLAGS) $(5) \
+	    -XXlib:libartd$(HOST_SHLIB_SUFFIX) -Ximage:$$(HOST_CORE_IMG_LOCATION) \
+	    -classpath $(ART_HOST_TEST_DIR)/android-data-$$@/oat-test-dex-$(1).jar \
+	    -Djava.library.path=$$($(2)ART_HOST_OUT_SHARED_LIBRARIES) $(1) \
+	      > $(ART_HOST_TEST_DIR)/android-data-$$@/output.txt 2>&1 \
+	  && $$(call ART_TEST_PASSED,$$@) \
+	  || (([ ! -f $(ART_HOST_TEST_DIR)/android-data-$$@/output.txt ] || \
+	       cat $(ART_HOST_TEST_DIR)/android-data-$$@/output.txt) && $$(call ART_TEST_FAILED,$$@))
+	$$(hide) (echo $(MAKECMDGOALS) | grep -q $$@ && \
+	  echo "run-test run as top-level target, removing test directory $(ART_HOST_TEST_DIR)" && \
+	  rm -r $(ART_HOST_TEST_DIR)) || true
+endef  # define-test-art-oat-rule-host
+
+# Define rules to run oat tests on the host.
+# $(1): directory - the name of the test we're building such as HelloWorld.
+# $(2): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
+define define-test-art-oat-rules-host
+  # Create a rule to run the host oat test with the default compiler.
+  default_test_rule := test-art-host-oat-default-$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
+  $(call define-test-art-oat-rule-host,$(1),$(2),$$(default_test_rule),,)
+
+  ART_TEST_HOST_OAT_DEFAULT$$($(2)ART_PHONY_TEST_HOST_SUFFIX)_RULES += $$(default_test_rule)
+  ART_TEST_HOST_OAT_DEFAULT_RULES += $$(default_test_rule)
+  ART_TEST_HOST_OAT_DEFAULT_$(1)_RULES += $$(default_test_rule)
+
+  # Create a rule to run the host oat test with the optimizing compiler.
+  optimizing_test_rule := test-art-host-oat-optimizing-$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
+  $(call define-test-art-oat-rule-host,$(1),$(2),$$(optimizing_test_rule),--compiler-backend=Optimizing,)
+
+  # Mark all tests with the optimizing compiler broken. TODO: fix.
+  ART_TEST_KNOWN_BROKEN += $$(optimizing_test_rule)
+
+  ART_TEST_HOST_OAT_OPTIMIZING$$($(2)ART_PHONY_TEST_HOST_SUFFIX)_RULES += $$(optimizing_test_rule)
+  ART_TEST_HOST_OAT_OPTIMIZING_RULES += $$(optimizing_test_rule)
+  ART_TEST_HOST_OAT_OPTIMIZING_$(1)_RULES += $$(optimizing_test_rule)
+
+  # Create a rule to run the host oat test with the interpreter.
+  interpreter_test_rule := test-art-host-oat-interpreter-$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
+  $(call define-test-art-oat-rule-host,$(1),$(2),$$(interpreter_test_rule),--compiler-filter=interpret-only,-Xint)
+
+  ART_TEST_HOST_OAT_INTERPRETER$$($(2)ART_PHONY_TEST_HOST_SUFFIX)_RULES += $$(interpreter_test_rule)
+  ART_TEST_HOST_OAT_INTERPRETER_RULES += $$(interpreter_test_rule)
+  ART_TEST_HOST_OAT_INTERPRETER_$(1)_RULES += $$(interpreter_test_rule)
+
+  # Define a phony rule to run both the default and interpreter variants.
+  all_test_rule :=  test-art-host-oat-$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
+.PHONY: $$(all_test_rule)
+$$(all_test_rule): $$(default_test_rule) $$(interpreter_test_rule) $$(optimizing_test_rule)
+	$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+  ART_TEST_HOST_OAT$$($(2)ART_PHONY_TEST_HOST_SUFFIX)_RULES += $$(all_test_rule)
+  ART_TEST_HOST_OAT_RULES += $$(all_test_rule)
+  ART_TEST_HOST_OAT_$(1)_RULES += $$(all_test_rule)
+
+  # Clear locally defined variables.
+  default_test_rule :=
+  optimizing_test_rule :=
+  interpreter_test_rule :=
+  all_test_rule :=
+endef  # define-test-art-oat-rules-host
+
+# For a given test create all the combinations of host/target, compiler and suffix such as:
+# test-art-host-oat-HelloWord or test-art-target-oat-interpreter-HelloWorld64
+# $(1): test name, e.g. HelloWorld
+# $(2): host or target
+# $(3): HOST or TARGET
+# $(4): undefined, -default, -optimizing or -interpreter
+# $(5): undefined, _DEFAULT, _OPTIMIZING or _INTERPRETER
+define define-test-art-oat-combination-for-test
+  ifeq ($(2),host)
+    ifneq ($(3),HOST)
+      $$(error argument mismatch $(2) and ($3))
+    endif
+  else
+    ifneq ($(2),target)
+      $$(error found $(2) expected host or target)
+    endif
+    ifneq ($(3),TARGET)
+      $$(error argument mismatch $(2) and ($3))
+    endif
+  endif
+
+  rule_name := test-art-$(2)-oat$(4)-$(1)
+  dependencies := $$(ART_TEST_$(3)_OAT$(5)_$(1)_RULES)
+
+  ifeq ($$(dependencies),)
+    ifneq ($(4),-optimizing)
+      $$(error $$(rule_name) has no dependencies)
+    endif
+  endif
+
+.PHONY: $$(rule_name)
+$$(rule_name): $$(dependencies)
+	$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+  # Clear locally defined variables.
+  rule_name :=
+  dependencies :=
+endef  # define-test-art-oat-combination
+
+# Define target and host oat test rules for the differing multilib flavors and default vs
+# interpreter runs. The format of the generated rules (for running an individual test) is:
+#   test-art-(host|target)-oat-(default|interpreter)-${directory}(32|64)
+# The rules are appended to various lists to enable shorter phony build rules to be built.
+# $(1): directory
+define define-test-art-oat-rules
+  # Define target tests.
+  ART_TEST_TARGET_OAT_DEFAULT_$(1)_RULES :=
+  ART_TEST_TARGET_OAT_OPTIMIZING_$(1)_RULES :=
+  ART_TEST_TARGET_OAT_INTERPRETER_$(1)_RULES :=
+  ART_TEST_TARGET_OAT_$(1)_RULES :=
+  $(call define-test-art-oat-rules-target,$(1),)
+  ifdef TARGET_2ND_ARCH
+    $(call define-test-art-oat-rules-target,$(1),2ND_)
+  endif
+  $(call define-test-art-oat-combination-for-test,$(1),target,TARGET,,))
+  $(call define-test-art-oat-combination-for-test,$(1),target,TARGET,-default,_DEFAULT))
+  $(call define-test-art-oat-combination-for-test,$(1),target,TARGET,-optimizing,_OPTIMIZING))
+  $(call define-test-art-oat-combination-for-test,$(1),target,TARGET,-interpreter,_INTERPRETER))
+
+  # Define host tests.
+  ART_TEST_HOST_OAT_DEFAULT_$(1)_RULES :=
+  ART_TEST_HOST_OAT_OPTIMIZING_$(1)_RULES :=
+  ART_TEST_HOST_OAT_INTERPRETER_$(1)_RULES :=
+  ART_TEST_HOST_OAT_$(1)_RULES :=
+  $(call define-test-art-oat-rules-host,$(1),)
+  ifneq ($(HOST_PREFER_32_BIT),true)
+    $(call define-test-art-oat-rules-host,$(1),2ND_)
+  endif
+  $(call define-test-art-oat-combination-for-test,$(1),host,HOST,,)
+  $(call define-test-art-oat-combination-for-test,$(1),host,HOST,-default,_DEFAULT)
+  $(call define-test-art-oat-combination-for-test,$(1),host,HOST,-optimizing,_OPTIMIZING)
+  $(call define-test-art-oat-combination-for-test,$(1),host,HOST,-interpreter,_INTERPRETER)
+
+  # Clear locally defined variables.
+  ART_TEST_TARGET_OAT_DEFAULT_$(1)_RULES :=
+  ART_TEST_TARGET_OAT_OPTIMIZING_$(1)_RULES :=
+  ART_TEST_TARGET_OAT_INTERPRETER_$(1)_RULES :=
+  ART_TEST_TARGET_OAT_$(1)_RULES :=
+  ART_TEST_HOST_OAT_DEFAULT_$(1)_RULES :=
+  ART_TEST_HOST_OAT_OPTIMIZING_$(1)_RULES :=
+  ART_TEST_HOST_OAT_INTERPRETER_$(1)_RULES :=
+  ART_TEST_HOST_OAT_$(1)_RULES :=
+endef  # define-test-art-oat-rules
+$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call define-test-art-oat-rules,$(dir))))
+
+# Define all the combinations of host/target, compiler and suffix such as:
+# test-art-host-oat or test-art-target-oat-interpreter64
+# $(1): host or target
+# $(2): HOST or TARGET
+# $(3): undefined, -default, -optimizing or -interpreter
+# $(4): undefined, _DEFAULT, _OPTIMIZING or _INTERPRETER
+# $(5): undefined, 32 or 64
+define define-test-art-oat-combination
+  ifeq ($(1),host)
+    ifneq ($(2),HOST)
+      $$(error argument mismatch $(1) and ($2))
+    endif
+  else
+    ifneq ($(1),target)
+      $$(error found $(1) expected host or target)
+    endif
+    ifneq ($(2),TARGET)
+      $$(error argument mismatch $(1) and ($2))
+    endif
+  endif
+
+  rule_name := test-art-$(1)-oat$(3)$(5)
+  dependencies := $$(ART_TEST_$(2)_OAT$(4)$(5)_RULES)
+
+  ifeq ($$(dependencies),)
+    ifneq ($(3),-optimizing)
+      $$(error $$(rule_name) has no dependencies)
+    endif
+  endif
+
+.PHONY: $$(rule_name)
+$$(rule_name): $$(dependencies)
+	$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+  # Clear locally defined variables.
+  rule_name :=
+  dependencies :=
+
+endef  # define-test-art-oat-combination
+
+$(eval $(call define-test-art-oat-combination,target,TARGET,,,))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-default,_DEFAULT,))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-optimizing,_OPTIMIZING,))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-interpreter,_INTERPRETER,))
+$(eval $(call define-test-art-oat-combination,target,TARGET,,,$(ART_PHONY_TEST_TARGET_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-default,_DEFAULT,$(ART_PHONY_TEST_TARGET_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-optimizing,_OPTIMIZING,$(ART_PHONY_TEST_TARGET_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-interpreter,_INTERPRETER,$(ART_PHONY_TEST_TARGET_SUFFIX)))
+ifdef TARGET_2ND_ARCH
+$(eval $(call define-test-art-oat-combination,target,TARGET,,,$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-default,_DEFAULT,$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-optimizing,_OPTIMIZING,$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,target,TARGET,-interpreter,_INTERPRETER,$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)))
+endif
+
+$(eval $(call define-test-art-oat-combination,host,HOST,,,))
+$(eval $(call define-test-art-oat-combination,host,HOST,-default,_DEFAULT,))
+$(eval $(call define-test-art-oat-combination,host,HOST,-optimizing,_OPTIMIZING,))
+$(eval $(call define-test-art-oat-combination,host,HOST,-interpreter,_INTERPRETER,))
+$(eval $(call define-test-art-oat-combination,host,HOST,,,$(ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,host,HOST,-default,_DEFAULT,$(ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,host,HOST,-optimizing,_OPTIMIZING,$(ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,host,HOST,-interpreter,_INTERPRETER,$(ART_PHONY_TEST_HOST_SUFFIX)))
+ifneq ($(HOST_PREFER_32_BIT),true)
+$(eval $(call define-test-art-oat-combination,host,HOST,,,$(2ND_ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,host,HOST,-default,_DEFAULT,$(2ND_ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,host,HOST,-optimizing,_OPTIMIZING,$(2ND_ART_PHONY_TEST_HOST_SUFFIX)))
+$(eval $(call define-test-art-oat-combination,host,HOST,-interpreter,_INTERPRETER,$(2ND_ART_PHONY_TEST_HOST_SUFFIX)))
+endif
+
+# Clear locally defined variables.
+define-test-art-oat-rule-target :=
+define-test-art-oat-rules-target :=
+define-test-art-oat-rule-host :=
+define-test-art-oat-rules-host :=
+define-test-art-oat-combination-for-test :=
+define-test-art-oat-combination :=
+ART_TEST_TARGET_OAT_DEFAULT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_DEFAULT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_DEFAULT_RULES :=
+ART_TEST_TARGET_OAT_OPTIMIZING$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_OPTIMIZING$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_OPTIMIZING_RULES :=
+ART_TEST_TARGET_OAT_INTERPRETER$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_INTERPRETER$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_INTERPRETER_RULES :=
+ART_TEST_TARGET_OAT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_OAT_RULES :=
+ART_TEST_HOST_OAT_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_DEFAULT_RULES :=
+ART_TEST_HOST_OAT_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_OPTIMIZING_RULES :=
+ART_TEST_HOST_OAT_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_INTERPRETER_RULES :=
+ART_TEST_HOST_OAT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_OAT_RULES :=
+ART_TEST_HOST_OAT_DEPENDENCIES :=
+$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval ART_OAT_TEST_$(dir)_DEX :=))
+TEST_OAT_DIRECTORIES :=
+LOCAL_PID :=
+LOCAL_PATH :=
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
new file mode 100644
index 0000000..add97be
--- /dev/null
+++ b/test/Android.run-test.mk
@@ -0,0 +1,341 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include art/build/Android.common_test.mk
+
+# List of all tests of the form 003-omnibus-opcodes.
+TEST_ART_RUN_TESTS := $(wildcard $(LOCAL_PATH)/[0-9]*)
+TEST_ART_RUN_TESTS := $(subst $(LOCAL_PATH)/,, $(TEST_ART_RUN_TESTS))
+
+# Tests that are timing sensitive and flaky on heavily loaded systems.
+TEST_ART_TIMING_SENSITIVE_RUN_TESTS := \
+  test-art-host-default-053-wait-some32 \
+  test-art-host-default-053-wait-some64 \
+  test-art-host-interpreter-053-wait-some32 \
+  test-art-host-interpreter-053-wait-some64 \
+  test-art-host-optimizing-053-wait-some32 \
+  test-art-host-optimizing-053-wait-some64 \
+  test-art-host-default-055-enum-performance32 \
+  test-art-host-default-055-enum-performance64 \
+  test-art-host-interpreter-055-enum-performance32 \
+  test-art-host-interpreter-055-enum-performance64 \
+  test-art-host-optimizing-055-enum-performance32 \
+  test-art-host-optimizing-055-enum-performance64
+
+ # disable timing sensitive tests on "dist" builds.
+ifdef dist_goal
+  ART_TEST_KNOWN_BROKEN += $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS)
+endif
+
+# The path where build only targets will be output, e.g.
+# out/target/product/generic_x86_64/obj/PACKAGING/art-run-tests_intermediates/DATA
+art_run_tests_dir := $(call intermediates-dir-for,PACKAGING,art-run-tests)/DATA
+
+# A generated list of prerequisites that call 'run-test --build-only', the actual prerequisite is
+# an empty file touched in the intermediate directory.
+TEST_ART_RUN_TEST_BUILD_RULES :=
+
+# Helper to create individual build targets for tests. Must be called with $(eval).
+# $(1): the test number
+define define-build-art-run-test
+  dmart_target := $(art_run_tests_dir)/art-run-tests/$(1)/touch
+$$(dmart_target): $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
+	$(hide) rm -rf $$(dir $$@) && mkdir -p $$(dir $$@)
+	$(hide) DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) \
+	  $(LOCAL_PATH)/run-test --build-only --output-path $$(abspath $$(dir $$@)) $(1)
+	$(hide) touch $$@
+
+  TEST_ART_RUN_TEST_BUILD_RULES += $$(dmart_target)
+  dmart_target :=
+endef
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := art-run-tests
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TEST_ART_RUN_TEST_BUILD_RULES)
+# The build system use this flag to pick up files generated by declare-make-art-run-test.
+LOCAL_PICKUP_FILES := $(art_run_tests_dir)
+
+include $(BUILD_PHONY_PACKAGE)
+
+# Clear temp vars.
+TEST_ART_RUN_TEST_BUILD_RULES :=
+art_run_tests_dir :=
+define-build-art-run-test :=
+
+########################################################################
+
+ART_TEST_TARGET_RUN_TEST_ALL_RULES :=
+ART_TEST_TARGET_RUN_TEST_DEFAULT_RULES :=
+ART_TEST_TARGET_RUN_TEST_INTERPRETER_RULES :=
+ART_TEST_TARGET_RUN_TEST_OPTIMIZING_RULES :=
+ART_TEST_TARGET_RUN_TEST_ALL$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_DEFAULT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_ALL$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_ALL_RULES :=
+ART_TEST_HOST_RUN_TEST_DEFAULT_RULES :=
+ART_TEST_HOST_RUN_TEST_INTERPRETER_RULES :=
+ART_TEST_HOST_RUN_TEST_OPTIMIZING_RULES :=
+ART_TEST_HOST_RUN_TEST_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+
+# We need dex2oat and dalvikvm on the target as well as the core image.
+TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_EXECUTABLES) $(TARGET_CORE_IMG_OUT) $(2ND_TARGET_CORE_IMG_OUT)
+
+# All tests require the host executables and the core images.
+ART_TEST_HOST_RUN_TEST_DEPENDENCIES := \
+  $(ART_HOST_EXECUTABLES) \
+  $(HOST_CORE_IMG_OUT) \
+  $(2ND_HOST_CORE_IMG_OUT)
+
+# For a given test create all the combinations of host/target, compiler and suffix such as:
+# test-art-host-run-test-optimizing-003-omnibus-opcodes32
+# $(1): test name, e.g. 003-omnibus-opcodes
+# $(2): host or target
+# $(3): default, optimizing or interpreter
+# $(4): 32 or 64
+define define-test-art-run-test
+  run_test_options := $(addprefix --runtime-option ,$(DALVIKVM_FLAGS))
+  uc_host_or_target :=
+  prereq_rule :=
+  ifeq ($(2),host)
+    uc_host_or_target := HOST
+    run_test_options += --host
+    prereq_rule := $(ART_TEST_HOST_RUN_TEST_DEPENDENCIES)
+  else
+    ifeq ($(2),target)
+      uc_host_or_target := TARGET
+      prereq_rule := test-art-target-sync
+    else
+      $$(error found $(2) expected host or target)
+    endif
+  endif
+  uc_compiler :=
+  ifeq ($(3),optimizing)
+    uc_compiler := OPTIMIZING
+    run_test_options += -Xcompiler-option --compiler-backend=Optimizing
+  else
+    ifeq ($(3),interpreter)
+      uc_compiler := INTERPRETER
+      run_test_options += --interpreter
+    else
+      ifeq ($(3),default)
+        uc_compiler := DEFAULT
+      else
+        $$(error found $(3) expected optimizing, interpreter or default)
+      endif
+    endif
+  endif
+  ifeq ($(4),64)
+    run_test_options += --64
+  else
+    ifneq ($(4),32)
+      $$(error found $(4) expected 32 or 64)
+    endif
+  endif
+  run_test_rule_name := test-art-$(2)-run-test-$(3)-$(1)$(4)
+  run_test_options := --output-path $(ART_HOST_TEST_DIR)/run-test-output/$$(run_test_rule_name) \
+    $$(run_test_options)
+$$(run_test_rule_name): PRIVATE_RUN_TEST_OPTIONS := $$(run_test_options)
+.PHONY: $$(run_test_rule_name)
+$$(run_test_rule_name): $(DX) $(HOST_OUT_EXECUTABLES)/jasmin $$(prereq_rule)
+	$(hide) $$(call ART_TEST_SKIP,$$@) && \
+	  DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) \
+	    art/test/run-test $$(PRIVATE_RUN_TEST_OPTIONS) $(1) \
+	      && $$(call ART_TEST_PASSED,$$@) || $$(call ART_TEST_FAILED,$$@)
+	$$(hide) (echo $(MAKECMDGOALS) | grep -q $$@ && \
+	  echo "run-test run as top-level target, removing test directory $(ART_HOST_TEST_DIR)" && \
+	  rm -r $(ART_HOST_TEST_DIR)) || true
+
+  # Mark all tests with the optimizing compiler broken. TODO: fix.
+  ifeq ($(3),optimizing)
+    ART_TEST_KNOWN_BROKEN += $$(run_test_rule_name)
+  endif
+
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_$$(uc_compiler)$(4)_RULES += $$(run_test_rule_name)
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_$$(uc_compiler)_RULES += $$(run_test_rule_name)
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_$$(uc_compiler)_$(1)_RULES += $$(run_test_rule_name)
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_$$(uc_compiler)_RULES += $$(run_test_rule_name)
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_$(1)_RULES += $$(run_test_rule_name)
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_ALL_RULES += $$(run_test_rule_name)
+  ART_TEST_$$(uc_host_or_target)_RUN_TEST_ALL$(4)_RULES += $$(run_test_rule_name)
+
+  # Clear locally defined variables.
+  run_test_options :=
+  run_test_rule_name :=
+  uc_host_or_target :=
+  prereq_rule :=
+  uc_compiler :=
+endef  # define-test-art-run-test
+
+# Define a phony rule whose purpose is to test its prerequisites.
+# $(1): rule name, e.g. test-art-host-run-test32
+# $(2): list of prerequisites
+define define-test-art-run-test-group-rule
+.PHONY: $(1)
+$(1): $(2)
+	$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
+
+endef  # define-test-art-run-test-group-rule
+
+# Create rules for a group of run tests.
+# $(1): test name, e.g. 003-omnibus-opcodes
+# $(2): host or target
+define define-test-art-run-test-group
+  group_uc_host_or_target :=
+  ifeq ($(2),host)
+    group_uc_host_or_target := HOST
+  else
+    ifeq ($(2),target)
+      group_uc_host_or_target := TARGET
+    else
+      $$(error found $(2) expected host or target)
+    endif
+  endif
+
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_DEFAULT_$(1)_RULES :=
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_INTERPRETER_$(1)_RULES :=
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_OPTIMIZING_$(1)_RULES :=
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_$(1)_RULES :=
+  $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+  $$(eval $$(call define-test-art-run-test,$(1),$(2),interpreter,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+  $$(eval $$(call define-test-art-run-test,$(1),$(2),optimizing,$$(ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+  do_second := false
+  ifeq ($(2),host)
+    ifneq ($$(HOST_PREFER_32_BIT),true)
+      do_second := true
+    endif
+  else
+    ifdef TARGET_2ND_ARCH
+      do_second := true
+    endif
+  endif
+  ifeq (true,$$(do_second))
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),default,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),interpreter,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+    $$(eval $$(call define-test-art-run-test,$(1),$(2),optimizing,$$(2ND_ART_PHONY_TEST_$$(group_uc_host_or_target)_SUFFIX)))
+  endif
+
+  $$(eval $$(call define-test-art-run-test-group-rule,test-art-$(2)-run-test-default-$(1), \
+    $$(ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_DEFAULT_$(1)_RULES)))
+  $$(eval $$(call define-test-art-run-test-group-rule,test-art-$(2)-run-test-interpreter-$(1), \
+    $$(ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_INTERPRETER_$(1)_RULES)))
+  $$(eval $$(call define-test-art-run-test-group-rule,test-art-$(2)-run-test-optimizing-$(1), \
+    $$(ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_OPTIMIZING_$(1)_RULES)))
+  $$(eval $$(call define-test-art-run-test-group-rule,test-art-$(2)-run-test-$(1), \
+    $$(ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_$(1)_RULES)))
+
+  # Clear locally defined variables.
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_DEFAULT_$(1)_RULES :=
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_INTERPRETER_$(1)_RULES :=
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_OPTIMIZING_$(1)_RULES :=
+  ART_TEST_$$(group_uc_host_or_target)_RUN_TEST_$(1)_RULES :=
+  group_uc_host_or_target :=
+  do_second :=
+endef  # define-test-art-run-test-group
+
+$(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call define-test-art-run-test-group,$(test),target)))
+$(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call define-test-art-run-test-group,$(test),host)))
+
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test, \
+  $(ART_TEST_TARGET_RUN_TEST_ALL_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-default, \
+  $(ART_TEST_TARGET_RUN_TEST_DEFAULT_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-interpreter, \
+  $(ART_TEST_TARGET_RUN_TEST_INTERPRETER_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-optimizing, \
+  $(ART_TEST_TARGET_RUN_TEST_OPTIMIZING_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test$(ART_PHONY_TEST_TARGET_SUFFIX), \
+  $(ART_TEST_TARGET_RUN_TEST_ALL$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-default$(ART_PHONY_TEST_TARGET_SUFFIX), \
+  $(ART_TEST_TARGET_RUN_TEST_DEFAULT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-interpreter$(ART_PHONY_TEST_TARGET_SUFFIX), \
+  $(ART_TEST_TARGET_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-optimizing$(ART_PHONY_TEST_TARGET_SUFFIX), \
+  $(ART_TEST_TARGET_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+ifdef TARGET_2ND_ARCH
+  $(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test$(2ND_ART_PHONY_TEST_TARGET_SUFFIX), \
+    $(ART_TEST_TARGET_RUN_TEST_ALL$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+  $(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-default$(2ND_ART_PHONY_TEST_TARGET_SUFFIX), \
+    $(ART_TEST_TARGET_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+  $(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-interpreter$(2ND_ART_PHONY_TEST_TARGET_SUFFIX), \
+    $(ART_TEST_TARGET_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+  $(eval $(call define-test-art-run-test-group-rule,test-art-target-run-test-optimizing$(2ND_ART_PHONY_TEST_TARGET_SUFFIX), \
+    $(ART_TEST_TARGET_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES)))
+endif
+
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test, \
+  $(ART_TEST_HOST_RUN_TEST_ALL_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-default, \
+  $(ART_TEST_HOST_RUN_TEST_DEFAULT_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-interpreter, \
+  $(ART_TEST_HOST_RUN_TEST_INTERPRETER_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-optimizing, \
+  $(ART_TEST_HOST_RUN_TEST_OPTIMIZING_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test$(ART_PHONY_TEST_HOST_SUFFIX), \
+  $(ART_TEST_HOST_RUN_TEST_ALL$(ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-default$(ART_PHONY_TEST_HOST_SUFFIX), \
+  $(ART_TEST_HOST_RUN_TEST_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-interpreter$(ART_PHONY_TEST_HOST_SUFFIX), \
+  $(ART_TEST_HOST_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+$(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-optimizing$(ART_PHONY_TEST_HOST_SUFFIX), \
+  $(ART_TEST_HOST_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+ifneq ($(HOST_PREFER_32_BIT),true)
+  $(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test$(2ND_ART_PHONY_TEST_HOST_SUFFIX), \
+    $(ART_TEST_HOST_RUN_TEST_ALL$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+  $(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-default$(2ND_ART_PHONY_TEST_HOST_SUFFIX), \
+    $(ART_TEST_HOST_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+  $(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-interpreter$(2ND_ART_PHONY_TEST_HOST_SUFFIX), \
+    $(ART_TEST_HOST_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+  $(eval $(call define-test-art-run-test-group-rule,test-art-host-run-test-optimizing$(2ND_ART_PHONY_TEST_HOST_SUFFIX), \
+    $(ART_TEST_HOST_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES)))
+endif
+
+define-test-art-run-test :=
+define-test-art-run-test-group-rule :=
+define-test-art-run-test-group :=
+ART_TEST_TARGET_RUN_TEST_ALL_RULES :=
+ART_TEST_TARGET_RUN_TEST_DEFAULT_RULES :=
+ART_TEST_TARGET_RUN_TEST_INTERPRETER_RULES :=
+ART_TEST_TARGET_RUN_TEST_OPTIMIZING_RULES :=
+ART_TEST_TARGET_RUN_TEST_ALL$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_DEFAULT$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_ALL$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_TARGET_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_ALL_RULES :=
+ART_TEST_HOST_RUN_TEST_DEFAULT_RULES :=
+ART_TEST_HOST_RUN_TEST_INTERPRETER_RULES :=
+ART_TEST_HOST_RUN_TEST_OPTIMIZING_RULES :=
+ART_TEST_HOST_RUN_TEST_DEFAULT$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_INTERPRETER$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_OPTIMIZING$(ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_DEFAULT$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_INTERPRETER$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
+ART_TEST_HOST_RUN_TEST_OPTIMIZING$(2ND_ART_PHONY_TEST_HOST_SUFFIX)_RULES :=
diff --git a/test/etc/host-run-test-jar b/test/etc/host-run-test-jar
index f672974..4265f1c 100755
--- a/test/etc/host-run-test-jar
+++ b/test/etc/host-run-test-jar
@@ -18,6 +18,7 @@
 DEV_MODE="n"
 QUIET="n"
 FLAGS=""
+exe="${ANDROID_HOST_OUT}/bin/dalvikvm32"
 
 while true; do
     if [ "x$1" = "x--quiet" ]; then
@@ -63,6 +64,9 @@
     elif [ "x$1" = "x--interpreter" ]; then
         INTERPRETER="y"
         shift
+    elif [ "x$1" = "x--64" ]; then
+        exe="${ANDROID_HOST_OUT}/bin/dalvikvm64"
+        shift
     elif [ "x$1" = "x--no-verify" ]; then
         VERIFY="n"
         shift
@@ -103,8 +107,6 @@
 export LD_LIBRARY_PATH="${ANDROID_ROOT}/lib"
 export DYLD_LIBRARY_PATH="${ANDROID_ROOT}/lib"
 
-exe="${ANDROID_ROOT}/bin/dalvikvm"
-
 if [ "$DEBUGGER" = "y" ]; then
     PORT=8000
     msg "Waiting for jdb to connect:"