am e69d4350: Merge "Support to add JNI of both archs in multilib build."

* commit 'e69d4350cd4af04349b703ba169ba516a96913ba':
  Support to add JNI of both archs in multilib build.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index c6a09d8..84aaa57 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -167,6 +167,7 @@
 LOCAL_GENERATED_SOURCES_$(TARGET_ARCH):=
 LOCAL_REQUIRED_MODULES_$(TARGET_ARCH):=
 LOCAL_CLANG_$(TARGET_ARCH):=
+LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH):=
 ifdef TARGET_2ND_ARCH
 LOCAL_SRC_FILES_$(TARGET_2ND_ARCH):=
 LOCAL_CFLAGS_$(TARGET_2ND_ARCH):=
@@ -181,6 +182,7 @@
 LOCAL_GENERATED_SOURCES_$(TARGET_2ND_ARCH):=
 LOCAL_REQUIRED_MODULES_$(TARGET_2ND_ARCH):=
 LOCAL_CLANG_$(TARGET_2ND_ARCH):=
+LOCAL_PREBUILT_JNI_LIBS_$(TARGET_2ND_ARCH):=
 endif
 LOCAL_SRC_FILES_$(HOST_ARCH):=
 LOCAL_CFLAGS_$(HOST_ARCH):=
diff --git a/core/definitions.mk b/core/definitions.mk
index c2c8823..441c186 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1723,10 +1723,20 @@
     -F $@
 endef
 
+# We need the extra blank line, so that the command will be on a separate line.
+# $(1): the ABI name
+# $(2): the list of shared libraies
+define _add-jni-shared-libs-to-package-per-abi
+$(hide) cp $(2) $(dir $@)lib/$(1)
+
+endef
+
 define add-jni-shared-libs-to-package
 $(hide) rm -rf $(dir $@)lib
-$(hide) mkdir -p $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)
-$(hide) cp $(PRIVATE_JNI_SHARED_LIBRARIES) $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)
+$(hide) mkdir -p $(addprefix $(dir $@)lib/,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI))
+$(foreach abi,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI),\
+  $(call _add-jni-shared-libs-to-package-per-abi,$(abi),\
+    $(patsubst $(abi):%,%,$(filter $(abi):%,$(PRIVATE_JNI_SHARED_LIBRARIES)))))
 $(hide) (cd $(dir $@) && zip -r $(notdir $@) lib)
 $(hide) rm -rf $(dir $@)lib
 endef
diff --git a/core/install_jni_libs.mk b/core/install_jni_libs.mk
index 700d106..918a839 100644
--- a/core/install_jni_libs.mk
+++ b/core/install_jni_libs.mk
@@ -1,28 +1,16 @@
 # Decides how to install the jni libraries needed by an apk.
 # Input variables:
-#   LOCAL_JNI_SHARED_LIBRARIES
-#   LOCAL_INSTALLED_MODULE
+#   my_module_multilib, LOCAL_2ND_ARCH_VAR_PREFIX (from package.mk or prebuilt.mk)
 #   rs_compatibility_jni_libs (from java.mk)
 #   my_module_path (from base_rules.mk)
 #   partition_tag (from base_rules.mk)
 #   my_prebuilt_src_file (from prebuilt_internal.mk)
 #
 # Output variables:
-#   jni_shared_libraries, jni_shared_libraries_abi, if we are going to embed the libraries into the apk;
-#   my_extracted_jni_libs, if we extract jni libs from prebuilt apk.
+#   jni_shared_libraries, jni_shared_libraries_abi, jni_shared_libraries_with_abis if we are going to embed the libraries into the apk;
+#   extracted_jni_libs, if we extract jni libs from prebuilt apk.
 #
 
-jni_shared_libraries := \
-    $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/, \
-      $(addsuffix .so, \
-          $(LOCAL_JNI_SHARED_LIBRARIES)))
-
-# Include RS dynamically-generated libraries as well
-# Keep this ifneq, as the += otherwise adds spaces that need to be stripped.
-ifneq ($(rs_compatibility_jni_libs),)
-jni_shared_libraries += $(rs_compatibility_jni_libs)
-endif
-
 my_embed_jni :=
 ifneq ($(TARGET_BUILD_APPS),)
 my_embed_jni := true
@@ -35,87 +23,69 @@
 my_embed_jni := true
 endif
 
-# App-specific lib path.
-my_app_lib_path :=  $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET$(partition_tag)_OUT_SHARED_LIBRARIES)/$(basename $(my_installed_module_stem))
-my_extracted_jni_libs :=
+jni_shared_libraries :=
+jni_shared_libraries_abis :=
+# jni_shared_libraries_with_abis is a list of <abi>:<path-to-the-built-jni-lib>
+jni_shared_libraries_with_abis :=
+extracted_jni_libs :=
 
-ifdef my_embed_jni
-# App explicitly requires the prebuilt NDK stl shared libraies.
-# The NDK stl shared libraries should never go to the system image.
-ifneq ($(filter $(LOCAL_NDK_STL_VARIANT), stlport_shared c++_shared),)
-ifndef LOCAL_SDK_VERSION
-$(error LOCAL_SDK_VERSION must be defined with LOCAL_NDK_STL_VARIANT, \
-    LOCAL_PACKAGE_NAME=$(LOCAL_PACKAGE_NAME))
+#######################################
+# For TARGET_ARCH
+my_2nd_arch_prefix :=
+my_add_jni :=
+# The module is built for TARGET_ARCH
+ifeq ($(my_2nd_arch_prefix),$(LOCAL_2ND_ARCH_VAR_PREFIX))
+my_add_jni := true
 endif
+# Or it explicitly requires both
+ifeq ($(my_module_multilib),both)
+my_add_jni := true
 endif
-ifeq (stlport_shared,$(LOCAL_NDK_STL_VARIANT))
-jni_shared_libraries += \
-    $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources/cxx-stl/stlport/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libstlport_shared.so
-else ifeq (c++_shared,$(LOCAL_NDK_STL_VARIANT))
-jni_shared_libraries += \
-    $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libc++_shared.so
+ifeq ($(my_add_jni),true)
+my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH))
+ifndef my_prebuilt_jni_libs
+my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS)
 endif
+include $(BUILD_SYSTEM)/install_jni_libs_internal.mk
+jni_shared_libraries += $(my_jni_shared_libraries)
+jni_shared_libraries_abis += $(my_jni_shared_libraries_abi)
+jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
+    $(my_jni_shared_libraries))
+extracted_jni_libs += $(my_extracted_jni_libs)
 
-# Set the abi directory used by the local JNI shared libraries.
-# (Doesn't change how the local shared libraries are compiled, just
-# sets where they are stored in the apk.)
-ifeq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI),)
-    jni_shared_libraries_abi := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)
-else
-    jni_shared_libraries_abi := $(LOCAL_JNI_SHARED_LIBRARIES_ABI)
-endif
+# Include RS dynamically-generated libraries as well
+# TODO: Add multilib support once RS supports generating multilib libraries.
+jni_shared_libraries += $(rs_compatibility_jni_libs)
+endif  # my_add_jni
 
-else  # not my_embed_jni
+#######################################
+# For TARGET_2ND_ARCH
+ifdef TARGET_2ND_ARCH
+my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
+my_add_jni :=
+# The module is built for TARGET_2ND_ARCH
+ifeq ($(my_2nd_arch_prefix),$(LOCAL_2ND_ARCH_VAR_PREFIX))
+my_add_jni := true
+endif
+# Or it explicitly requires both
+ifeq ($(my_module_multilib),both)
+my_add_jni := true
+endif
+ifeq ($(my_add_jni),true)
+my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS_$(TARGET_2ND_ARCH))
+ifndef my_prebuilt_jni_libs
+my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS)
+endif
+include $(BUILD_SYSTEM)/install_jni_libs_internal.mk
+jni_shared_libraries += $(my_jni_shared_libraries)
+jni_shared_libraries_abis += $(my_jni_shared_libraries_abi)
+jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
+    $(my_jni_shared_libraries))
+extracted_jni_libs += $(my_extracted_jni_libs)
+endif  # my_add_jni
+endif  # TARGET_2ND_ARCH
 
 jni_shared_libraries := $(strip $(jni_shared_libraries))
-ifneq ($(jni_shared_libraries),)
-# The jni libaries will be installed to the system.img.
-my_jni_filenames := $(notdir $(jni_shared_libraries))
-# Make sure the JNI libraries get installed
-$(LOCAL_INSTALLED_MODULE) : | $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET$(partition_tag)_OUT_SHARED_LIBRARIES)/, $(my_jni_filenames))
-
-# Create symlink in the app specific lib path
-ifdef LOCAL_POST_INSTALL_CMD
-my_leading_separator := ;
-else
-my_leading_separator :=
-endif
-$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD += \
-  $(my_leading_separator)mkdir -p $(my_app_lib_path) \
-  $(foreach lib, $(my_jni_filenames), ;ln -sf ../$(lib) $(my_app_lib_path)/$(lib))
-
-# Clear jni_shared_libraries to not embed it into the apk.
-jni_shared_libraries :=
-endif  # $(jni_shared_libraries) not empty
-endif  # my_embed_jni
-
-ifdef LOCAL_PREBUILT_JNI_LIBS
-# Install prebuilt JNI libs to the app specific lib path.
-# Files like @path/to/libfoo.so (path inside the apk) are JNI libs extracted from the prebuilt apk;
-# Files like path/to/libfoo.so (path relative to LOCAL_PATH) are prebuilts in the source tree.
-my_extracted_jni_libs := $(patsubst @%,%, \
-    $(filter @%, $(LOCAL_PREBUILT_JNI_LIBS)))
-ifdef my_extracted_jni_libs
-ifndef my_prebuilt_src_file
-$(error No prebuilt apk to extract prebuilt jni libraries $(my_extracted_jni_libs))
-endif
-# We use the first jni lib file as dependency.
-my_installed_prebuilt_jni := $(my_app_lib_path)/$(notdir $(firstword $(my_extracted_jni_libs)))
-$(my_installed_prebuilt_jni): PRIVATE_JNI_LIBS := $(my_extracted_jni_libs)
-$(my_installed_prebuilt_jni): $(my_prebuilt_src_file)
-	@echo "Extract JNI libs ($@ <- $<)"
-	@mkdir -p $(dir $@)
-	$(hide) unzip -j -o -d $(dir $@) $< $(PRIVATE_JNI_LIBS) && touch $@
-
-$(LOCAL_INSTALLED_MODULE) : | $(my_installed_prebuilt_jni)
-endif
-
-my_prebulit_jni_libs := $(addprefix $(LOCAL_PATH)/, \
-    $(filter-out @%, $(LOCAL_PREBUILT_JNI_LIBS)))
-ifdef my_prebulit_jni_libs
-$(foreach lib, $(my_prebulit_jni_libs), \
-    $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
-
-$(LOCAL_INSTALLED_MODULE) : | $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebulit_jni_libs)))
-endif
-endif  # LOCAL_PREBULT_JNI_LIBS
+jni_shared_libraries_abis := $(sort $(jni_shared_libraries_abis))
+jni_shared_libraries_with_abis := $(strip $(jni_shared_libraries_with_abis))
+extracted_jni_libs := $(strip $(extracted_jni_libs))
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
new file mode 100644
index 0000000..b50c21e
--- /dev/null
+++ b/core/install_jni_libs_internal.mk
@@ -0,0 +1,104 @@
+# Install jni libraries for one arch.
+# Input variables:
+#   my_2nd_arch_prefix: indicate if this is for TARGET_2ND_ARCH.
+#   my_embed_jni: indicate if we want to embed the jni libs in the apk.
+#   my_prebuilt_jni_libs
+#   my_installed_module_stem (from configure_module_stem.mk)
+#   partition_tag (from base_rules.mk)
+#   my_prebuilt_src_file (from prebuilt_internal.mk)
+#
+# Output variables:
+#   my_jni_shared_libraries, my_jni_shared_libraries_abi, if we are going to embed the libraries into the apk;
+#   my_extracted_jni_libs, if we extract jni libs from prebuilt apk.
+#
+
+my_jni_shared_libraries := \
+    $(addprefix $($(my_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/, \
+      $(addsuffix .so, \
+          $(LOCAL_JNI_SHARED_LIBRARIES)))
+
+# App-specific lib path.
+my_app_lib_path :=  $($(my_2nd_arch_prefix)TARGET$(partition_tag)_OUT_SHARED_LIBRARIES)/$(basename $(my_installed_module_stem))
+my_extracted_jni_libs :=
+
+ifdef my_embed_jni
+# App explicitly requires the prebuilt NDK stl shared libraies.
+# The NDK stl shared libraries should never go to the system image.
+ifneq ($(filter $(LOCAL_NDK_STL_VARIANT), stlport_shared c++_shared),)
+ifndef LOCAL_SDK_VERSION
+$(error LOCAL_SDK_VERSION must be defined with LOCAL_NDK_STL_VARIANT, \
+    LOCAL_PACKAGE_NAME=$(LOCAL_PACKAGE_NAME))
+endif
+endif
+ifeq (stlport_shared,$(LOCAL_NDK_STL_VARIANT))
+my_jni_shared_libraries += \
+    $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources/cxx-stl/stlport/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libstlport_shared.so
+else ifeq (c++_shared,$(LOCAL_NDK_STL_VARIANT))
+my_jni_shared_libraries += \
+    $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libc++_shared.so
+endif
+
+# Set the abi directory used by the local JNI shared libraries.
+# (Doesn't change how the local shared libraries are compiled, just
+# sets where they are stored in the apk.)
+ifeq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI),)
+    my_jni_shared_libraries_abi := $(TARGET_$(my_2nd_arch_prefix)CPU_ABI)
+else
+    my_jni_shared_libraries_abi := $(LOCAL_JNI_SHARED_LIBRARIES_ABI)
+endif
+
+else  # not my_embed_jni
+
+my_jni_shared_libraries := $(strip $(my_jni_shared_libraries))
+ifneq ($(my_jni_shared_libraries),)
+# The jni libaries will be installed to the system.img.
+my_jni_filenames := $(notdir $(my_jni_shared_libraries))
+# Make sure the JNI libraries get installed
+$(LOCAL_INSTALLED_MODULE) : | $(addprefix $($(my_2nd_arch_prefix)TARGET$(partition_tag)_OUT_SHARED_LIBRARIES)/, $(my_jni_filenames))
+
+# Create symlink in the app specific lib path
+ifdef LOCAL_POST_INSTALL_CMD
+# Add a shell command separator
+LOCAL_POST_INSTALL_CMD += ;
+endif
+LOCAL_POST_INSTALL_CMD += \
+  mkdir -p $(my_app_lib_path) \
+  $(foreach lib, $(my_jni_filenames), ;ln -sf ../$(lib) $(my_app_lib_path)/$(lib))
+$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
+
+# Clear jni_shared_libraries to not embed it into the apk.
+my_jni_shared_libraries :=
+endif  # $(my_jni_shared_libraries) not empty
+endif  # my_embed_jni
+
+ifdef my_prebuilt_jni_libs
+# Install prebuilt JNI libs to the app specific lib path.
+# Files like @path/to/libfoo.so (path inside the apk) are JNI libs extracted from the prebuilt apk;
+# Files like path/to/libfoo.so (path relative to LOCAL_PATH) are prebuilts in the source tree.
+my_extracted_jni_libs := $(patsubst @%,%, \
+    $(filter @%, $(my_prebuilt_jni_libs)))
+ifdef my_extracted_jni_libs
+ifndef my_prebuilt_src_file
+$(error No prebuilt apk to extract prebuilt jni libraries $(my_extracted_jni_libs))
+endif
+# We use the first jni lib file as dependency.
+my_installed_prebuilt_jni := $(my_app_lib_path)/$(notdir $(firstword $(my_extracted_jni_libs)))
+$(my_installed_prebuilt_jni): PRIVATE_JNI_LIBS := $(my_extracted_jni_libs)
+$(my_installed_prebuilt_jni): $(my_prebuilt_src_file)
+	@echo "Extract JNI libs ($@ <- $<)"
+	@mkdir -p $(dir $@)
+	$(hide) unzip -j -o -d $(dir $@) $< $(PRIVATE_JNI_LIBS) && touch $@
+
+$(LOCAL_INSTALLED_MODULE) : | $(my_installed_prebuilt_jni)
+endif
+
+# prebuilt JNI exsiting as separate source files.
+my_prebuilt_jni_libs := $(addprefix $(LOCAL_PATH)/, \
+    $(filter-out @%, $(my_prebuilt_jni_libs)))
+ifdef my_prebuilt_jni_libs
+$(foreach lib, $(my_prebuilt_jni_libs), \
+    $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
+
+$(LOCAL_INSTALLED_MODULE) : | $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
+endif  # inner my_prebuilt_jni_libs
+endif  # outer my_prebuilt_jni_libs
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 5285616..d97ce2a 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -336,8 +336,10 @@
 
 # Define the rule to build the actual package.
 $(LOCAL_BUILT_MODULE): $(AAPT) | $(ZIPALIGN)
-$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries)
-$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abi)
+# PRIVATE_JNI_SHARED_LIBRARIES is a list of <abi>:<path_of_built_lib>.
+$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
+# PRIVATE_JNI_SHARED_LIBRARIES_ABI is a list of ABI names.
+$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
 ifneq ($(TARGET_BUILD_APPS),)
     # Include all resources for unbundled apps.
     LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 4bcd70a..b5e5189 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -165,7 +165,7 @@
 # Sign and align non-presigned .apks.
 $(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)
 	$(transform-prebuilt-to-target)
-ifdef my_extracted_jni_libs
+ifdef extracted_jni_libs
 	$(hide) zip -d $@ 'lib/*.so'  # strip embedded JNI libraries.
 endif
 ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)