From 51512c558cb0f9ae414dd20cb2591d679aea1f02 Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Mon, 12 Nov 2018 20:16:26 -0800 Subject: [PATCH] Add support for no-vendor-variant VNDK When TARGET_VNDK_USE_CORE_VARIANT is set to true, the vendor variant of VNDK libraries are by default not installed. Instead, the core variant will be used by vendor binaries at runtime. To ensure the core variant of VNDK libraries are installed, we also add a flag LOCAL_VNDK_DEPEND_ON_CORE_VARIANT to indicate that the vendor variant module depends on the core variant module. This flag should be set by Soong for all VNDK libraries without the vendor variant installed. When the flag is set, the vendor variant binary is also compared against the core variant binary to ensure they are functionally identical. As we are merging the two variants for some libraries, we need a new link type to denote a module is usable as both native:vndk and native:platform. We add native:platform_vndk for this. Bug: 119423884 Test: With the corresponding Soong change, build with TARGET_VNDK_USE_CORE_VARIANT set to true. Test: Add a dummy VNDK library and a dummy vendor binary that depends on it. Build with no-vendor-variant VNDK and check the core variant is installed. Test: Add conditional compilation based on __ANDROID_VNDK__ in the dummy VNDK library and check build fails. Change-Id: I40000f2728e8193212113c1ee950e9d697f2d40d --- core/binary.mk | 6 +-- core/clear_vars.mk | 1 + core/definitions.mk | 16 ++++++++ core/install_jni_libs_internal.mk | 4 +- core/main.mk | 4 ++ core/soong_cc_prebuilt.mk | 62 ++++++++++++++++++++++--------- core/soong_config.mk | 2 + tools/check_identical_lib.sh | 30 +++++++++++++++ 8 files changed, 103 insertions(+), 22 deletions(-) create mode 100755 tools/check_identical_lib.sh diff --git a/core/binary.mk b/core/binary.mk index ad3d76bc26..da188aeccd 100644 --- a/core/binary.mk +++ b/core/binary.mk @@ -1214,17 +1214,17 @@ else ifdef LOCAL_USE_VNDK # with vendor_available: false my_link_type := native:vendor my_warn_types := - my_allowed_types := native:vendor native:vndk + my_allowed_types := native:vendor native:vndk native:platform_vndk endif else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(call get_non_asan_path,$(LOCAL_MODULE_PATH))),) my_link_type := native:recovery my_warn_types := # TODO(b/113303515) remove native:platform and my_allowed_ndk_types -my_allowed_types := native:recovery native:platform $(my_allowed_ndk_types) +my_allowed_types := native:recovery native:platform native:platform_vndk $(my_allowed_ndk_types) else my_link_type := native:platform my_warn_types := $(my_warn_ndk_types) -my_allowed_types := $(my_allowed_ndk_types) native:platform +my_allowed_types := $(my_allowed_ndk_types) native:platform native:platform_vndk endif my_link_deps := $(addprefix STATIC_LIBRARIES:,$(my_whole_static_libraries) $(my_static_libraries)) diff --git a/core/clear_vars.mk b/core/clear_vars.mk index 1883743258..444612fc90 100644 --- a/core/clear_vars.mk +++ b/core/clear_vars.mk @@ -296,6 +296,7 @@ LOCAL_USE_VNDK:= LOCAL_USES_LIBRARIES:= LOCAL_VENDOR_MODULE:= LOCAL_VINTF_FRAGMENTS:= +LOCAL_VNDK_DEPEND_ON_CORE_VARIANT:= LOCAL_VTSC_FLAGS:= LOCAL_VTS_INCLUDES:= LOCAL_VTS_MODE:= diff --git a/core/definitions.mk b/core/definitions.mk index 2764401351..02b737cd65 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -3398,3 +3398,19 @@ $(KATI_obsolete_var \ initialize-package-file \ add-jni-shared-libs-to-package,\ These functions have been removed) + +########################################################### +## Verify the variants of a VNDK library are identical +## +## $(1): Path to the core variant shared library file. +## $(2): Path to the vendor variant shared library file. +## $(3): TOOLS_PREFIX +########################################################### +LIBRARY_IDENTITY_CHECK_SCRIPT := build/make/tools/check_identical_lib.sh +define verify-vndk-libs-identical +@echo "Checking VNDK vendor variant: $(2)" +$(hide) CLANG_BIN="$(LLVM_PREBUILTS_PATH)" \ + CROSS_COMPILE="$(strip $(3))" \ + XZ="$(XZ)" \ + $(LIBRARY_IDENTITY_CHECK_SCRIPT) $(SOONG_STRIP_PATH) $(1) $(2) +endef diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk index e0f1ad4b80..a79a49a7f0 100644 --- a/core/install_jni_libs_internal.mk +++ b/core/install_jni_libs_internal.mk @@ -113,12 +113,12 @@ my_link_type := app:sdk my_warn_types := native:platform $(my_warn_ndk_types) my_allowed_types := $(my_allowed_ndk_types) ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_PROPRIETARY_MODULE))) - my_allowed_types += native:vendor native:vndk + my_allowed_types += native:vendor native:vndk native:platform_vndk endif else my_link_type := app:platform my_warn_types := $(my_warn_ndk_types) -my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private +my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private native:platform_vndk endif my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES)) diff --git a/core/main.mk b/core/main.mk index bbe6b38fbe..43c80ee1ba 100644 --- a/core/main.mk +++ b/core/main.mk @@ -501,6 +501,10 @@ ifndef subdir_makefiles_total subdir_makefiles_total := $(words init post finish) endif +droid_targets: no_vendor_variant_vndk_check +.PHONY: no_vendor_variant_vndk_check +no_vendor_variant_vndk_check: + $(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] finishing build rules ...) # ------------------------------------------------------------------- diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk index 8d248af339..679d5b8bb1 100644 --- a/core/soong_cc_prebuilt.mk +++ b/core/soong_cc_prebuilt.mk @@ -86,11 +86,13 @@ ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODUL endif ifdef LOCAL_USE_VNDK - name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE)) - ifneq ($(name_without_suffix),$(LOCAL_MODULE) - SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1 + ifneq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true) + name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE)) + ifneq ($(name_without_suffix),$(LOCAL_MODULE) + SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1 + endif + name_without_suffix := endif - name_without_suffix := endif # Check prebuilt ELF binaries. @@ -113,27 +115,52 @@ ifdef LOCAL_INSTALLED_MODULE endif endif +ifeq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true) + # Add $(LOCAL_BUILT_MODULE) as a dependency to no_vendor_variant_vndk_check so + # that the vendor variant will be built and checked against the core variant. + no_vendor_variant_vndk_check: $(LOCAL_BUILT_MODULE) + + my_core_register_name := $(subst .vendor,,$(my_register_name)) + my_core_variant_files := $(call module-target-built-files,$(my_core_register_name)) + my_core_shared_lib := $(sort $(filter %.so,$(my_core_variant_files))) + $(LOCAL_BUILT_MODULE): PRIVATE_CORE_VARIANT := $(my_core_shared_lib) + + # The built vendor variant library needs to depend on the built core variant + # so that we can perform identity check against the core variant. + $(LOCAL_BUILT_MODULE): $(my_core_shared_lib) +endif + +ifeq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true) +$(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE) $(LIBRARY_IDENTITY_CHECK_SCRIPT) + $(call verify-vndk-libs-identical,\ + $(PRIVATE_CORE_VARIANT),\ + $<,\ + $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)TOOLS_PREFIX)) + $(copy-file-to-target) +else $(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE) $(transform-prebuilt-to-target) +endif ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),) $(hide) chmod +x $@ endif ifndef LOCAL_IS_HOST_MODULE ifdef LOCAL_SOONG_UNSTRIPPED_BINARY - my_symbol_path := $(if $(LOCAL_SOONG_SYMBOL_PATH),$(LOCAL_SOONG_SYMBOL_PATH),$(my_module_path)) - # Store a copy with symbols for symbolic debugging - my_unstripped_path := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path)) - # drop /root as /root is mounted as / - my_unstripped_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/root/%,$(TARGET_OUT_UNSTRIPPED)/%, $(my_unstripped_path)) - symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem) - $(eval $(call copy-one-file,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output))) - $(call add-dependency,$(LOCAL_BUILT_MODULE),$(symbolic_output)) + ifneq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true) + my_symbol_path := $(if $(LOCAL_SOONG_SYMBOL_PATH),$(LOCAL_SOONG_SYMBOL_PATH),$(my_module_path)) + # Store a copy with symbols for symbolic debugging + my_unstripped_path := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path)) + # drop /root as /root is mounted as / + my_unstripped_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/root/%,$(TARGET_OUT_UNSTRIPPED)/%, $(my_unstripped_path)) + symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem) + $(eval $(call copy-one-file,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output))) + $(call add-dependency,$(LOCAL_BUILT_MODULE),$(symbolic_output)) - ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true) - my_breakpad_path := $(TARGET_OUT_BREAKPAD)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path)) - breakpad_output := $(my_breakpad_path)/$(my_installed_module_stem).sym - $(breakpad_output) : $(LOCAL_SOONG_UNSTRIPPED_BINARY) | $(BREAKPAD_DUMP_SYMS) $(PRIVATE_READELF) + ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true) + my_breakpad_path := $(TARGET_OUT_BREAKPAD)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path)) + breakpad_output := $(my_breakpad_path)/$(my_installed_module_stem).sym + $(breakpad_output) : $(LOCAL_SOONG_UNSTRIPPED_BINARY) | $(BREAKPAD_DUMP_SYMS) $(PRIVATE_READELF) @echo "target breakpad: $(PRIVATE_MODULE) ($@)" @mkdir -p $(dir $@) $(hide) if $(PRIVATE_READELF) -S $< > /dev/null 2>&1 ; then \ @@ -142,7 +169,8 @@ ifndef LOCAL_IS_HOST_MODULE echo "skipped for non-elf file."; \ touch $@; \ fi - $(call add-dependency,$(LOCAL_BUILT_MODULE),$(breakpad_output)) + $(call add-dependency,$(LOCAL_BUILT_MODULE),$(breakpad_output)) + endif endif endif endif diff --git a/core/soong_config.mk b/core/soong_config.mk index 3c82e88241..995fc11249 100644 --- a/core/soong_config.mk +++ b/core/soong_config.mk @@ -115,6 +115,8 @@ $(call add_json_list, ModulesLoadedByPrivilegedModules, $(PRODUCT_LOADED_BY_PRI $(call add_json_list, BootJars, $(PRODUCT_BOOT_JARS)) +$(call add_json_bool, VndkUseCoreVariant, $(TARGET_VNDK_USE_CORE_VARIANT)) + $(call add_json_bool, Product_is_iot, $(filter true,$(PRODUCT_IOT))) $(call add_json_bool, Treble_linker_namespaces, $(filter true,$(PRODUCT_TREBLE_LINKER_NAMESPACES))) diff --git a/tools/check_identical_lib.sh b/tools/check_identical_lib.sh new file mode 100755 index 0000000000..01007c088b --- /dev/null +++ b/tools/check_identical_lib.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -e + +STRIP_PATH="${1}" +CORE="${2}" +VENDOR="${3}" + +stripped_core="${CORE}.vndk_lib_check.stripped" +stripped_vendor="${VENDOR}.vndk_lib_check.stripped" + +function cleanup() { + rm -f ${stripped_core} ${stripped_vendor} +} +trap cleanup EXIT + +function strip_lib() { + ${STRIP_PATH} \ + -i ${1} \ + -o ${2} \ + -d /dev/null \ + --remove-build-id +} + +strip_lib ${CORE} ${stripped_core} +strip_lib ${VENDOR} ${stripped_vendor} +if ! cmp -s ${stripped_core} ${stripped_vendor}; then + echo "VNDK library not in vndkMustUseVendorVariantList but has different core and vendor variant: $(basename ${CORE})" + echo "If the two variants need to have different runtime behavior, consider using libvndksupport." + exit 1 +fi