Build from source or prebuilt

With this change, you can easily switch between building from source
code and prebuilt.
Set LOCAL_PREBUILT_MODULE_FILE to the path of the prebuilt file,
relative to the top of the source tree, in the usual module definition.
The prebuilt will be used unless any of the followings satisfied:
1) ANDROID_BUILD_FROM_SOURCE is "true", which disable prebuilt globally;
2) The module name is in ANDROID_NO_PREBUILT_MODULES;
3) The LOCAL_PATH is prefixed by any of ANDROID_NO_PREBUILT_PATHS.
A developer can set ANDROID_NO_PREBUILT_MODULES or
ANDROID_NO_PREBUILT_PATHS to build only his own module(s) from source,
while build other modules from prebuilts.
You can set ANDROID_BUILD_FROM_SOURCE to true to build everything from
source.
Those variables can be set with shell environmental variable or in your
buildspec.mk.

Sometimes module B is able to be built from source only if module A is
also
built from source, for example, if B is the test apk of A.
In that case, you can use the macro include-if-build-from-source to
include B's Android.mk only if A is built from source too, or
if-build-from-source to conditionally include the definition of module
B,
if their module definitions are in the same Android.mk.

Support host-executable-hook and host-shared-library-hook.

Change-Id: Icab7cf028c87eaba0dd7efc2a7749fd6f32b44e4
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index a566768..91b5df6 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -130,6 +130,7 @@
 # Don't delete the META_INF dir when merging static Java libraries.
 LOCAL_DONT_DELETE_JAR_META_INF:=
 LOCAL_ADDITIONAL_CERTIFICATES:=
+LOCAL_PREBUILT_MODULE_FILE:=
 
 # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
 # iterate over thousands of entries every time.
diff --git a/core/definitions.mk b/core/definitions.mk
index 96cc0cc..4bce0a7 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2110,6 +2110,30 @@
 $(6): $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp
 endef
 
+## Whether to build from source if prebuilt alternative exists
+###########################################################
+# $(1): module name
+# $(2): LOCAL_PATH
+# Expands to empty string if not from source.
+ifeq (true,$(ANDROID_BUILD_FROM_SOURCE))
+define if-build-from-source
+true
+endef
+else
+define if-build-from-source
+$(if $(filter $(ANDROID_NO_PREBUILT_MODULES),$(1))$(filter \
+    $(addsuffix %,$(ANDROID_NO_PREBUILT_PATHS)),$(2)),true)
+endef
+endif
+
+# Include makefile $(1) if build from source for module $(2)
+# $(1): the makefile to include
+# $(2): module name
+# $(3): LOCAL_PATH
+define include-if-build-from-source
+$(if $(call if-build-from-source,$(2),$(3)),$(eval include $(1)))
+endef
+
 ###########################################################
 ## Other includes
 ###########################################################
diff --git a/core/host_executable.mk b/core/host_executable.mk
index 93d3f10..ab0f8f3 100644
--- a/core/host_executable.mk
+++ b/core/host_executable.mk
@@ -13,7 +13,21 @@
 LOCAL_MODULE_SUFFIX := $(HOST_EXECUTABLE_SUFFIX)
 endif
 
+$(call host-executable-hook)
+
+skip_build_from_source :=
+ifdef LOCAL_PREBUILT_MODULE_FILE
+ifeq (,$(call if-build-from-source,$(LOCAL_MODULE),$(LOCAL_PATH)))
+include $(BUILD_PREBUILT)
+skip_build_from_source := true
+endif
+endif
+
+ifndef skip_build_from_source
+
 include $(BUILD_SYSTEM)/binary.mk
 
 $(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries)
 	$(transform-host-o-to-executable)
+
+endif  # skip_build_from_source
diff --git a/core/host_shared_library.mk b/core/host_shared_library.mk
index 65e8258..a29e14c 100644
--- a/core/host_shared_library.mk
+++ b/core/host_shared_library.mk
@@ -22,6 +22,18 @@
 $(error $(LOCAL_PATH): Cannot set module stem for a library)
 endif
 
+$(call host-shared-library-hook)
+
+skip_build_from_source :=
+ifdef LOCAL_PREBUILT_MODULE_FILE
+ifeq (,$(call if-build-from-source,$(LOCAL_MODULE),$(LOCAL_PATH)))
+include $(BUILD_PREBUILT)
+skip_build_from_source := true
+endif
+endif
+
+ifndef skip_build_from_source
+
 # Put the built modules of all shared libraries in a common directory
 # to simplify the link line.
 OVERRIDE_BUILT_MODULE_PATH := $(HOST_OUT_INTERMEDIATE_LIBRARIES)
@@ -30,3 +42,5 @@
 
 $(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-o-to-shared-lib)
+
+endif  # skip_build_from_source
diff --git a/core/main.mk b/core/main.mk
index 771b9b3..61c041f 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -84,6 +84,24 @@
 # be generated correctly
 include $(BUILD_SYSTEM)/cleanbuild.mk
 
+# These targets are going to delete stuff, don't bother including
+# the whole directory tree if that's all we're going to do
+ifeq ($(MAKECMDGOALS),clean)
+dont_bother := true
+endif
+ifeq ($(MAKECMDGOALS),clobber)
+dont_bother := true
+endif
+ifeq ($(MAKECMDGOALS),dataclean)
+dont_bother := true
+endif
+ifeq ($(MAKECMDGOALS),installclean)
+dont_bother := true
+endif
+
+# Include the google-specific config
+-include vendor/google/build/config.mk
+
 VERSION_CHECK_SEQUENCE_NUMBER := 3
 -include $(OUT_DIR)/versions_checked.mk
 ifneq ($(VERSION_CHECK_SEQUENCE_NUMBER),$(VERSIONS_CHECKED))
@@ -387,21 +405,6 @@
 $(INTERNAL_MODIFIER_TARGETS): $(DEFAULT_GOAL)
 endif
 
-# These targets are going to delete stuff, don't bother including
-# the whole directory tree if that's all we're going to do
-ifeq ($(MAKECMDGOALS),clean)
-dont_bother := true
-endif
-ifeq ($(MAKECMDGOALS),clobber)
-dont_bother := true
-endif
-ifeq ($(MAKECMDGOALS),dataclean)
-dont_bother := true
-endif
-ifeq ($(MAKECMDGOALS),installclean)
-dont_bother := true
-endif
-
 # Bring in all modules that need to be built.
 ifneq ($(dont_bother),true)
 
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index aa04ebd..c9e07ef 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -16,6 +16,12 @@
 $(error dont use LOCAL_PREBUILT_JAVA_LIBRARIES anymore LOCAL_PATH=$(LOCAL_PATH))
 endif
 
+ifdef LOCAL_PREBUILT_MODULE_FILE
+my_prebuilt_src_file := $(LOCAL_PREBUILT_MODULE_FILE)
+else
+my_prebuilt_src_file := $(LOCAL_PATH)/$(LOCAL_SRC_FILES)
+endif
+
 ifdef LOCAL_IS_HOST_MODULE
   my_prefix := HOST_
 else
@@ -73,7 +79,7 @@
 endif
 
 $(LOCAL_BUILT_MODULE) : | $(intermediates)/export_includes
-endif
+endif  # prebuilt_module_is_a_library
 endif
 
 PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
@@ -95,7 +101,7 @@
   ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
     # It is now a build error to add a prebuilt .apk without
     # specifying a key for it.
-    $(error No LOCAL_CERTIFICATE specified for prebuilt "$(LOCAL_SRC_FILES)")
+    $(error No LOCAL_CERTIFICATE specified for prebuilt "$(my_prebuilt_src_file)")
   endif
 else ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
   # The magic string "PRESIGNED" means this package is already checked
@@ -123,21 +129,21 @@
 ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
 ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
 # Ensure that presigned .apks have been aligned.
-$(built_module) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ZIPALIGN)
+$(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN)
 	$(transform-prebuilt-to-target-with-zipalign)
 else
 # Sign and align non-presigned .apks.
-$(built_module) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)
+$(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)
 	$(transform-prebuilt-to-target)
 	$(sign-package)
 	$(align-package)
 endif
 else
 ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
-$(built_module) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES)
+$(built_module) : $(my_prebuilt_src_file)
 	$(transform-prebuilt-to-target-strip-comments)
 else
-$(built_module) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ACP)
+$(built_module) : $(my_prebuilt_src_file) | $(ACP)
 	$(transform-prebuilt-to-target)
 ifneq ($(prebuilt_module_is_a_library),)
   ifneq ($(LOCAL_IS_HOST_MODULE),)
@@ -157,7 +163,7 @@
 common_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),,COMMON)/classes.jar
 common_javalib_jar := $(dir $(common_classes_jar))javalib.jar
 
-$(common_classes_jar) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ACP)
+$(common_classes_jar) : $(my_prebuilt_src_file) | $(ACP)
 	$(transform-prebuilt-to-target)
 
 $(common_javalib_jar) : $(common_classes_jar) | $(ACP)