summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-06-11 07:33:59 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-06-11 07:33:59 +0000
commita3e61930c3b8a88bf31f12f0e0e6de2204ce8df6 (patch)
treecf7c0616a16d879b6c0e8518ee5a78046e7cb03f
parentfeff1fb6596150491e46168e94f98d9a98df2bd1 (diff)
parentfe60f6c8922a9563bb238ab38ca50d8eb8e38b7d (diff)
downloadandroid_development-a3e61930c3b8a88bf31f12f0e0e6de2204ce8df6.tar.gz
android_development-a3e61930c3b8a88bf31f12f0e0e6de2204ce8df6.tar.bz2
android_development-a3e61930c3b8a88bf31f12f0e0e6de2204ce8df6.zip
release-request-f326290a-f111-4b0c-bfd0-2a38565f6bf2-for-git_oc-dr1-release-4090242 snap-temp-L86400000073092233
Change-Id: I3055bf573768f31d5b9638c7d7abe308d96420dd
-rw-r--r--vndk/tools/definition-tool/README.md58
-rw-r--r--vndk/tools/definition-tool/templates/extra_vndk_sp_indirect.txt39
-rw-r--r--vndk/tools/definition-tool/templates/vndk.txt69
-rw-r--r--vndk/tools/definition-tool/templates/vndk_ext.txt37
-rwxr-xr-xvndk/tools/definition-tool/tests/test_elf_linker.py1
-rwxr-xr-xvndk/tools/definition-tool/tests/test_ndk_libs.py18
-rwxr-xr-xvndk/tools/definition-tool/vndk_definition_tool.py383
7 files changed, 394 insertions, 211 deletions
diff --git a/vndk/tools/definition-tool/README.md b/vndk/tools/definition-tool/README.md
index acf582464..c9afd8eab 100644
--- a/vndk/tools/definition-tool/README.md
+++ b/vndk/tools/definition-tool/README.md
@@ -23,42 +23,48 @@ The high-level overview of the command line usage is:
This command will print several lines such as:
- extra_vndk_sp_indirect: libexample1.so
- extra_vndk_sp_indirect: libexample2.so
- vndk_ext: libexample3.so
- vndk_ext: libexample4.so
+ vndk-sp: libexample1.so
+ vndk-sp-ext: libexample2.so
+ extra-vendor-libs: libexample3.so
-This output implies:
+The output implies:
-1. `libexample1.so` and `libexample2.so` should be copied into
- `/vendor/lib[64]/vndk-sp`.
+1. `libexample1.so` should be copied to `/system/lib[64]/vndk-sp`.
+2. `libexample2.so` should be copied to `/vendor/lib[64]/vndk-sp`.
+3. `libexample3.so` should be copied to `/vendor/lib[64]`.
-2. `libexample3.so` and `libexample4.so` should be copied into
- `/vendor/lib[64]`.
-
-# Boilerplates
+# Makefile Boilerplates
There are some boilerplates in `templates` directory that can automate the
-process to copy shared libraries.
+process to copy shared libraries. Please copy a boilerplate, rename it as
+`Android.mk`, and replace the placeholders with corresponding values:
+
+* `##_VNDK_SP_##` should be replaced by library names tagged with `vndk_sp`.
+
+* `##_VNDK_SP_EXT_##` should be replaced by library names tagged with
+ `vndk_sp_ext`.
+
+* `##_EXTRA_VENDOR_LIBS_##` should be replaced by library names tagged with
+ `extra_vendor_libs`.
+
+* `$(YOUR_DEVICE_NAME)` has to be replaced by your own device product name.
-If the output tagged some shared libraries with `extra_vndk_sp_indirect`, then
-copy `templates/extra_vndk_sp_indirect.txt` to an Android.mk and substitute
-`##_EXTRA_VNDK_SP_INDIRECT_##` with library names (without `.so`).
+VNDK definition tool can fill in the library names and generate an `Android.mk`
+when the `--output-format=make` is specified:
-If the output tagged some shared libraries with `vndk_ext`, then copy
-`templates/vndk_ext.txt` to an Android.mk and substitute `##_VNDK_EXT_##` with
-library names (without `.so`).
+ $ python3 ./vndk_definition_tool.py vndk \
+ --system "/path/to/your/product_out/system" \
+ --vendor "/path/to/your/product_out/vendor" \
+ --aosp-system "/path/to/aosp/generic/system" \
+ --tag-file "eligible-list-v3.0.csv" \
+ --output-format=make
These boilerplates only define the modules to copy shared libraries.
-Developers have to add those modules to the `PRODUCT_PACKAGES` variable in
-their `device.mk`. For example, in the example mentioned above, following
-`PRODUCT_PACKAGES` changes are necessary for that target:
-
- PRODUCT_PACKAGES += libexample1.vndk-sp-ext
- PRODUCT_PACKAGES += libexample2.vndk-sp-ext
- PRODUCT_PACKAGES += libexample3.vndk-ext
- PRODUCT_PACKAGES += libexample4.vndk-ext
+Developers have to add the phony package name to `PRODUCT_PACKAGES` variable in
+the `device.mk` for their devices.
+
+ PRODUCT_PACKAGES += $(YOUR_DEVICE_NAME)-vndk
## Ignore Subdirectories
diff --git a/vndk/tools/definition-tool/templates/extra_vndk_sp_indirect.txt b/vndk/tools/definition-tool/templates/extra_vndk_sp_indirect.txt
deleted file mode 100644
index 58e9b5110..000000000
--- a/vndk/tools/definition-tool/templates/extra_vndk_sp_indirect.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-EXTRA_VNDK_SP_INDIRECT_LIBRARIES := ##_EXTRA_VNDK_SP_INDIRECT_##
-
-define define-vndk-sp-indirect-ext-lib
-include $$(CLEAR_VARS)
-LOCAL_MODULE := $1.vndk-sp-ext
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_PREBUILT_MODULE_FILE := $$(call intermediates-dir-for,SHARED_LIBRARIES,$1,,,,)/PACKED/$1.so
-LOCAL_MULTILIB := first
-LOCAL_MODULE_TAGS := optional
-LOCAL_INSTALLED_MODULE_STEM := $1.so
-LOCAL_MODULE_SUFFIX := .so
-LOCAL_MODULE_RELATIVE_PATH := vndk-sp
-LOCAL_VENDOR_MODULE := true
-include $$(BUILD_PREBUILT)
-
-ifneq ($$(TARGET_2ND_ARCH),)
-ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
-include $$(CLEAR_VARS)
-LOCAL_MODULE := $1.vndk-sp-ext
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_PREBUILT_MODULE_FILE := $$(call intermediates-dir-for,SHARED_LIBRARIES,$1,,,$$(TARGET_2ND_ARCH_VAR_PREFIX),)/PACKED/$1.so
-LOCAL_MULTILIB := 32
-LOCAL_MODULE_TAGS := optional
-LOCAL_INSTALLED_MODULE_STEM := $1.so
-LOCAL_MODULE_SUFFIX := .so
-LOCAL_MODULE_RELATIVE_PATH := vndk-sp
-LOCAL_VENDOR_MODULE := true
-include $$(BUILD_PREBUILT)
-endif # TARGET_TRANSLATE_2ND_ARCH is not true
-endif # TARGET_2ND_ARCH is not empty
-endef
-
-$(foreach lib,$(VNDK_SP_LIBRARIES),\
- $(eval $(call define-vndk-sp-indirect-ext-lib,$(lib))))
-
-# Add following module names to PRODUCT_PACKAGES:
-# PRODUCT_PACKAGES += $(addsuffix .vndk-sp-ext,$(EXTRA_VNDK_SP_INDIRECT_LIBRARIES))
diff --git a/vndk/tools/definition-tool/templates/vndk.txt b/vndk/tools/definition-tool/templates/vndk.txt
new file mode 100644
index 000000000..889b6ea07
--- /dev/null
+++ b/vndk/tools/definition-tool/templates/vndk.txt
@@ -0,0 +1,69 @@
+ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
+
+
+VNDK_SP_LIBRARIES := ##_VNDK_SP_##
+
+VNDK_SP_EXT_LIBRARIES := ##_VNDK_SP_EXT_##
+
+EXTRA_VENDOR_LIBRARIES := ##_EXTRA_VENDOR_LIBS_##
+
+
+#-------------------------------------------------------------------------------
+# VNDK Modules
+#-------------------------------------------------------------------------------
+LOCAL_PATH := $(call my-dir)
+
+define define-vndk-lib
+include $$(CLEAR_VARS)
+LOCAL_MODULE := $1.$2
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
+LOCAL_STRIP_MODULE := false
+LOCAL_MULTILIB := first
+LOCAL_MODULE_TAGS := optional
+LOCAL_INSTALLED_MODULE_STEM := $1.so
+LOCAL_MODULE_SUFFIX := .so
+LOCAL_MODULE_RELATIVE_PATH := $3
+LOCAL_VENDOR_MODULE := $4
+include $$(BUILD_PREBUILT)
+
+ifneq ($$(TARGET_2ND_ARCH),)
+ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
+include $$(CLEAR_VARS)
+LOCAL_MODULE := $1.$2
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_PREBUILT_MODULE_FILE := $$($$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
+LOCAL_STRIP_MODULE := false
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_TAGS := optional
+LOCAL_INSTALLED_MODULE_STEM := $1.so
+LOCAL_MODULE_SUFFIX := .so
+LOCAL_MODULE_RELATIVE_PATH := $3
+LOCAL_VENDOR_MODULE := $4
+include $$(BUILD_PREBUILT)
+endif # TARGET_TRANSLATE_2ND_ARCH is not true
+endif # TARGET_2ND_ARCH is not empty
+endef
+
+$(foreach lib,$(VNDK_SP_LIBRARIES),\
+ $(eval $(call define-vndk-lib,$(lib),vndk-sp-gen,vndk-sp,)))
+$(foreach lib,$(VNDK_SP_EXT_LIBRARIES),\
+ $(eval $(call define-vndk-lib,$(lib),vndk-sp-ext-gen,vndk-sp,true)))
+$(foreach lib,$(EXTRA_VENDOR_LIBRARIES),\
+ $(eval $(call define-vndk-lib,$(lib),vndk-ext-gen,,true)))
+
+
+#-------------------------------------------------------------------------------
+# Phony Package
+#-------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(YOUR_DEVICE_NAME)-vndk
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := \
+ $(addsuffix .vndk-sp-gen,$(VNDK_SP_LIBRARIES)) \
+ $(addsuffix .vndk-sp-ext-gen,$(VNDK_SP_EXT_LIBRARIES)) \
+ $(addsuffix .vndk-ext-gen,$(VNDK_EXT_LIBRARIES))
+include $(BUILD_PHONY_PACKAGE)
+
+endif # ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
diff --git a/vndk/tools/definition-tool/templates/vndk_ext.txt b/vndk/tools/definition-tool/templates/vndk_ext.txt
deleted file mode 100644
index 307128056..000000000
--- a/vndk/tools/definition-tool/templates/vndk_ext.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-VNDK_EXT_LIBRARIES := ##_VNDK_EXT_##
-
-define define-vndk-ext-lib
-include $$(CLEAR_VARS)
-LOCAL_MODULE := $1.vndk-ext
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_PREBUILT_MODULE_FILE := $$(call intermediates-dir-for,SHARED_LIBRARIES,$1,,,,)/PACKED/$1.so
-LOCAL_MULTILIB := first
-LOCAL_MODULE_TAGS := optional
-LOCAL_INSTALLED_MODULE_STEM := $1.so
-LOCAL_MODULE_SUFFIX := .so
-LOCAL_VENDOR_MODULE := true
-include $$(BUILD_PREBUILT)
-
-ifneq ($$(TARGET_2ND_ARCH),)
-ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
-include $$(CLEAR_VARS)
-LOCAL_MODULE := $1.vndk-ext
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_PREBUILT_MODULE_FILE := $$(call intermediates-dir-for,SHARED_LIBRARIES,$1,,,$$(TARGET_2ND_ARCH_VAR_PREFIX),)/PACKED/$1.so
-LOCAL_MULTILIB := 32
-LOCAL_MODULE_TAGS := optional
-LOCAL_INSTALLED_MODULE_STEM := $1.so
-LOCAL_MODULE_SUFFIX := .so
-LOCAL_VENDOR_MODULE := true
-include $$(BUILD_PREBUILT)
-endif # TARGET_TRANSLATE_2ND_ARCH is not true
-endif # TARGET_2ND_ARCH is not empty
-endef
-
-$(foreach lib,$(VNDK_SP_LIBRARIES),\
- $(eval $(call define-vndk-ext-lib,$(lib))))
-
-# Add following module names to PRODUCT_PACKAGES:
-# PRODUCT_PACKAGES += $(addsuffix .vndk-ext,$(VNDK_EXT_LIBRARIES))
diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py
index 68109f26f..d3eecdd1e 100755
--- a/vndk/tools/definition-tool/tests/test_elf_linker.py
+++ b/vndk/tools/definition-tool/tests/test_elf_linker.py
@@ -273,7 +273,6 @@ class ELFLinkerTest(unittest.TestCase):
'libhidltransport',
'libhwbinder',
'libutils',
- 'libz',
)
# Add VNDK-SP libraries.
diff --git a/vndk/tools/definition-tool/tests/test_ndk_libs.py b/vndk/tools/definition-tool/tests/test_ndk_libs.py
index 976badccb..00a4c180c 100755
--- a/vndk/tools/definition-tool/tests/test_ndk_libs.py
+++ b/vndk/tools/definition-tool/tests/test_ndk_libs.py
@@ -19,6 +19,8 @@ class NDKLibDictTest(unittest.TestCase):
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib/libm.so'))
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib/libstdc++.so'))
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib/libvndksupport.so'))
+ self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib/libandroid_net.so'))
+ self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib/libz.so'))
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libc.so'))
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libdl.so'))
@@ -26,13 +28,11 @@ class NDKLibDictTest(unittest.TestCase):
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libm.so'))
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libstdc++.so'))
self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libvndksupport.so'))
+ self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libandroid_net.so'))
+ self.assertTrue(NDK_LIBS.is_ll_ndk('/system/lib64/libz.so'))
self.assertFalse(NDK_LIBS.is_ll_ndk('/system/lib/libm'))
- # libz.so is not LL-NDK anymore.
- self.assertFalse(NDK_LIBS.is_ll_ndk('/system/lib/libz.so'))
- self.assertFalse(NDK_LIBS.is_ll_ndk('/system/lib64/libz.so'))
-
def test_is_sp_ndk(self):
self.assertTrue(NDK_LIBS.is_sp_ndk('/system/lib/libEGL.so'))
self.assertTrue(NDK_LIBS.is_sp_ndk('/system/lib/libGLESv1_CM.so'))
@@ -104,12 +104,18 @@ class NDKLibDictTest(unittest.TestCase):
self.assertTrue(NDK_LIBS.is_ndk('/system/lib/liblog.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib/libm.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib/libstdc++.so'))
+ self.assertTrue(NDK_LIBS.is_ndk('/system/lib/libvndksupport.so'))
+ self.assertTrue(NDK_LIBS.is_ndk('/system/lib/libandroid_net.so'))
+ self.assertTrue(NDK_LIBS.is_ndk('/system/lib/libz.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libc.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libdl.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/liblog.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libm.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libstdc++.so'))
+ self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libvndksupport.so'))
+ self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libandroid_net.so'))
+ self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libz.so'))
# SP-NDK
self.assertTrue(NDK_LIBS.is_ndk('/system/lib/libEGL.so'))
@@ -139,10 +145,6 @@ class NDKLibDictTest(unittest.TestCase):
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libmediandk.so'))
self.assertTrue(NDK_LIBS.is_ndk('/system/lib64/libvulkan.so'))
- # libz.so is not NDK anymore.
- self.assertFalse(NDK_LIBS.is_ndk('/system/lib/libz.so'))
- self.assertFalse(NDK_LIBS.is_ndk('/system/lib64/libz.so'))
-
def test_classify(self):
self.assertEqual(NDK_LIBS.NOT_NDK,
NDK_LIBS.classify('/system/lib/libfoo.so'))
diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py
index aeefd2cbc..3830025f3 100755
--- a/vndk/tools/definition-tool/vndk_definition_tool.py
+++ b/vndk/tools/definition-tool/vndk_definition_tool.py
@@ -542,6 +542,8 @@ class NDKLibDict(object):
'libm.so',
'libstdc++.so',
'libvndksupport.so',
+ 'libandroid_net.so',
+ 'libz.so',
)
SP_NDK_LIB_NAMES = (
@@ -841,10 +843,16 @@ _VNDK_RESULT_FIELD_NAMES = (
'vndk_sp_indirect_unused', 'vndk_sp_indirect_private', 'vndk',
'vndk_indirect', 'fwk_only', 'fwk_only_rs', 'sp_hal', 'sp_hal_dep',
'vnd_only', 'vndk_ext', 'vndk_sp_ext', 'vndk_sp_indirect_ext',
- 'extra_vndk_sp_indirect')
+ 'extra_vendor_libs')
VNDKResult = defaultnamedtuple('VNDKResult', _VNDK_RESULT_FIELD_NAMES, set())
+_SIMPLE_VNDK_RESULT_FIELD_NAMES = (
+ 'vndk_sp', 'vndk_sp_ext', 'extra_vendor_libs')
+
+SimpleVNDKResult = defaultnamedtuple(
+ 'SimpleVNDKResult', _SIMPLE_VNDK_RESULT_FIELD_NAMES, set())
+
class ELFLibDict(defaultnamedtuple('ELFLibDict', ('lib32', 'lib64'), {})):
def get_lib_dict(self, elf_class):
@@ -1098,8 +1106,8 @@ class ELFLinker(object):
def compute_predefined_fwk_only_rs(self):
"""Find all fwk-only-rs libraries."""
path_patterns = (
- '^/system/lib(?:64)?/libft2\\.so$',
- '^/system/lib(?:64)?/libmediandk\\.so',
+ '^/system/lib(?:64)?/(?:vndk-sp/)?libft2\\.so$',
+ '^/system/lib(?:64)?/(?:vndk-sp/)?libmediandk\\.so',
)
return self.compute_path_matched_lib(path_patterns)
@@ -1124,7 +1132,6 @@ class ELFLinker(object):
'^.*/libhidltransport\\.so$',
'^.*/libhwbinder\\.so$',
'^.*/libutils\\.so$',
- '^.*/libz\\.so$',
# Only for o-release
'^.*/android\\.hidl\\.base@1\\.0\\.so$',
@@ -1261,27 +1268,28 @@ class ELFLinker(object):
new_path = lib.path.replace('/system/', '/vendor/')
self.rename_lib(lib, PT_VENDOR, new_path)
- def compute_degenerated_vndk(self, sp_lib, generic_refs,
- tagged_paths=None,
- action_ineligible_vndk_sp='follow,warn',
- action_ineligible_vndk='follow,warn'):
+ @staticmethod
+ def _parse_action_on_ineligible_lib(arg):
+ follow = False
+ warn = False
+ for flag in arg.split(','):
+ if flag == 'follow':
+ follow = True
+ elif flag == 'warn':
+ warn = True
+ elif flag == 'ignore':
+ continue
+ else:
+ raise ValueError('unknown action \"{}\"'.format(flag))
+ return (follow, warn)
+
+ def compute_degenerated_vndk(self, generic_refs, tagged_paths=None,
+ action_ineligible_vndk_sp='warn',
+ action_ineligible_vndk='warn'):
# Find LL-NDK and SP-NDK libs.
ll_ndk = set(lib for lib in self.all_libs() if lib.is_ll_ndk)
-
- def is_not_ll_ndk_indirect(lib):
- return lib.is_ll_ndk
-
- ll_ndk_indirect = self.compute_closure(ll_ndk, is_not_ll_ndk_indirect)
- ll_ndk_indirect -= ll_ndk
-
sp_ndk = set(lib for lib in self.all_libs() if lib.is_sp_ndk)
- def is_not_sp_ndk_indirect(lib):
- return lib.is_ll_ndk or lib.is_sp_ndk or lib in ll_ndk_indirect
-
- sp_ndk_indirect = self.compute_closure(sp_ndk, is_not_sp_ndk_indirect)
- sp_ndk_indirect -= sp_ndk
-
# Find SP-HAL libs.
sp_hal = self.compute_predefined_sp_hal()
@@ -1291,14 +1299,18 @@ class ELFLinker(object):
self.normalize_partition_tags(sp_hal, generic_refs)
# Find SP-HAL-Dep libs.
- def is_not_sp_hal_dep(lib):
- if lib.is_ll_ndk or lib.is_sp_ndk or lib in sp_hal:
- return True
+ def is_aosp_lib(lib):
if not generic_refs:
- # Use simple heuristic when generic reference is not available.
+ # If generic reference is not available, then assume all system
+ # libs are AOSP libs.
return lib.partition == PT_SYSTEM
return generic_refs.has_same_name_lib(lib)
+ def is_not_sp_hal_dep(lib):
+ if lib.is_ll_ndk or lib.is_sp_ndk or lib in sp_hal:
+ return True
+ return is_aosp_lib(lib)
+
sp_hal_dep = self.compute_closure(sp_hal, is_not_sp_hal_dep)
sp_hal_dep -= sp_hal
@@ -1310,7 +1322,8 @@ class ELFLinker(object):
return lib.is_ll_ndk or lib.is_sp_ndk or lib in sp_hal or \
lib in sp_hal_dep
- action_ineligible_vndk_sp = set(action_ineligible_vndk_sp.split(','))
+ follow_ineligible_vndk_sp, warn_ineligible_vndk_sp = \
+ self._parse_action_on_ineligible_lib(action_ineligible_vndk_sp)
predefined_vndk_sp = self.compute_predefined_vndk_sp()
vndk_sp = set()
for lib in itertools.chain(sp_hal, sp_hal_dep):
@@ -1320,18 +1333,13 @@ class ELFLinker(object):
if dep in predefined_vndk_sp:
vndk_sp.add(dep)
continue
- if 'warn' in action_ineligible_vndk_sp:
+ if warn_ineligible_vndk_sp:
print('error: SP-HAL {} depends on non vndk-sp '
'library {}.'.format(lib.path, dep.path),
file=sys.stderr)
- if 'follow' in action_ineligible_vndk_sp:
+ if follow_ineligible_vndk_sp:
vndk_sp.add(dep)
- # Add other predefined VNDK-SP even if they are not actually used by
- # SP-HAL libs.
- vndk_sp_unused = set(lib for lib in predefined_vndk_sp
- if self._is_in_vndk_sp_dir(lib.path)) - vndk_sp
-
# Find VNDK-SP-Indirect libs.
def is_not_vndk_sp_indirect(lib):
return lib.is_ll_ndk or lib.is_sp_ndk or lib in vndk_sp or \
@@ -1341,6 +1349,13 @@ class ELFLinker(object):
vndk_sp, is_not_vndk_sp_indirect)
vndk_sp_indirect -= vndk_sp
+ # Find unused predefined VNDK-SP libs.
+ vndk_sp_unused = set(lib for lib in predefined_vndk_sp
+ if self._is_in_vndk_sp_dir(lib.path))
+ vndk_sp_unused -= vndk_sp
+ vndk_sp_unused -= vndk_sp_indirect
+
+ # Find dependencies of unused predefined VNDK-SP libs.
def is_not_vndk_sp_indirect_unused(lib):
return is_not_vndk_sp_indirect(lib) or lib in vndk_sp_indirect
vndk_sp_indirect_unused = self.compute_closure(
@@ -1350,57 +1365,139 @@ class ELFLinker(object):
# TODO: Compute VNDK-SP-Indirect-Private.
vndk_sp_indirect_private = set()
- predefined_vndk_sp_indirect = self.compute_predefined_vndk_sp_indirect()
+ # Define helper functions for vndk_sp sets.
+ def is_vndk_sp_public(lib):
+ return lib in vndk_sp or lib in vndk_sp_unused or \
+ lib in vndk_sp_indirect or \
+ lib in vndk_sp_indirect_unused
- # TODO: Compute VNDK-SP-Ext and VNDK-SP-Indirect-Ext.
+ def is_vndk_sp(lib):
+ return is_vndk_sp_public(lib) or lib in vndk_sp_indirect_private
+
+ def is_vndk_sp_unused(lib):
+ return lib in vndk_sp_unused or lib in vndk_sp_indirect_unused
+
+ def relabel_vndk_sp_as_used(lib):
+ assert is_vndk_sp_unused(lib)
+
+ if lib in vndk_sp_unused:
+ vndk_sp_unused.remove(lib)
+ vndk_sp.add(lib)
+ else:
+ vndk_sp_indirect_unused.remove(lib)
+ vndk_sp_indirect.add(lib)
+
+ closure = self.compute_closure({lib}, is_not_vndk_sp_indirect)
+ closure -= vndk_sp
+ vndk_sp_indirect_unused.difference_update(closure)
+ vndk_sp_indirect.update(closure)
+
+ # Find VNDK-SP-Ext libs.
vndk_sp_ext = set()
+ def collect_vndk_ext(libs):
+ result = set()
+ for lib in libs:
+ for dep in lib.imported_ext_symbols:
+ if dep in vndk_sp and dep not in vndk_sp_ext:
+ result.add(dep)
+ return result
- def is_not_vndk_sp_indirect_ext(lib):
- return lib.is_ll_ndk or lib.is_sp_ndk or lib in vndk_sp_ext or \
- lib in predefined_vndk_sp or \
- lib in predefined_vndk_sp_indirect
+ candidates = collect_vndk_ext(self.lib_pt[PT_VENDOR].values())
+ while candidates:
+ vndk_sp_ext |= candidates
+ candidates = collect_vndk_ext(candidates)
- vndk_sp_indirect_ext = self.compute_closure(
- vndk_sp_ext, is_not_vndk_sp_indirect_ext)
- vndk_sp_indirect_ext -= vndk_sp_ext
+ # Find VNDK-SP-Indirect-Ext libs.
+ predefined_vndk_sp_indirect = self.compute_predefined_vndk_sp_indirect()
+ vndk_sp_indirect_ext = set()
+ def collect_vndk_sp_indirect_ext(libs):
+ result = set()
+ for lib in libs:
+ exts = set(lib.imported_ext_symbols.keys())
+ for dep in lib.deps:
+ if not is_vndk_sp_public(dep):
+ continue
+ if dep in vndk_sp_ext or dep in vndk_sp_indirect_ext:
+ continue
+ # If lib is using extended definition from deps, then we
+ # have to make a copy of dep.
+ if dep in exts:
+ result.add(dep)
+ continue
+ # If lib is using non-predefined VNDK-SP-Indirect, then we
+ # have to make a copy of dep.
+ if dep not in predefined_vndk_sp and \
+ dep not in predefined_vndk_sp_indirect:
+ result.add(dep)
+ continue
+ return result
- extra_vndk_sp_indirect = vndk_sp - predefined_vndk_sp - \
- predefined_vndk_sp_indirect
+ def is_not_vndk_sp_indirect(lib):
+ return lib.is_ll_ndk or lib.is_sp_ndk or lib in vndk_sp or \
+ lib in fwk_only_rs
+
+ candidates = collect_vndk_sp_indirect_ext(vndk_sp_ext)
+ while candidates:
+ vndk_sp_indirect_ext |= candidates
+ candidates = collect_vndk_sp_indirect_ext(candidates)
# Find VNDK libs (a.k.a. system shared libs directly used by vendor
# partition.)
def is_not_vndk(lib):
- if lib.is_ll_ndk or lib.is_sp_ndk or lib in vndk_sp:
- return True
- if lib.partition != PT_SYSTEM:
+ if lib.is_ll_ndk or lib.is_sp_ndk or is_vndk_sp_public(lib) or \
+ lib in fwk_only_rs:
return True
- if not generic_refs:
- # If generic reference is not available, we assume all system
- # libs are eligible vndk.
- return False
- return not generic_refs.has_same_name_lib(lib)
+ return lib.partition != PT_SYSTEM
- action_ineligible_vndk = set(action_ineligible_vndk.split(','))
+ def is_eligible_lib_access(lib, dep):
+ return not tagged_paths or \
+ tagged_paths.is_path_visible(lib.path, dep.path)
+
+ follow_ineligible_vndk, warn_ineligible_vndk = \
+ self._parse_action_on_ineligible_lib(action_ineligible_vndk)
vndk = set()
- for lib in self.lib_pt[PT_VENDOR].values():
- for dep in lib.deps:
- if is_not_vndk(dep):
- continue
- if not tagged_paths or \
- tagged_paths.is_path_visible(lib.path, dep.path):
- vndk.add(dep)
- continue
- if 'warn' in action_ineligible_vndk:
- print('warning: vendor lib/exe {} depends on ineligible '
- 'framework shared lib {}.'
- .format(lib.path, dep.path), file=sys.stderr)
- if 'follow' in action_ineligible_vndk:
- vndk.add(dep)
+ extra_vendor_libs = set()
+ def collect_vndk(vendor_libs):
+ next_vendor_libs = set()
+ for lib in vendor_libs:
+ for dep in lib.deps:
+ if is_vndk_sp_unused(dep):
+ relabel_vndk_sp_as_used(dep)
+ continue
+ if is_not_vndk(dep):
+ continue
+ if not is_aosp_lib(dep):
+ # The dependency should be copied into vendor partition
+ # as an extra vendor lib.
+ if dep not in extra_vendor_libs:
+ next_vendor_libs.add(dep)
+ extra_vendor_libs.add(dep)
+ continue
+ if is_eligible_lib_access(lib, dep):
+ vndk.add(dep)
+ continue
+ if warn_ineligible_vndk:
+ print('warning: vendor lib/exe {} depends on '
+ 'ineligible framework shared lib {}.'
+ .format(lib.path, dep.path), file=sys.stderr)
+ if follow_ineligible_vndk:
+ vndk.add(dep)
+ return next_vendor_libs
+
+ candidates = collect_vndk(self.lib_pt[PT_VENDOR].values())
+ while candidates:
+ candidates = collect_vndk(candidates)
vndk_indirect = self.compute_closure(vndk, is_not_vndk)
- vndk_indirect -= vndk_indirect
+ vndk_indirect -= vndk
+
+ def is_vndk(lib):
+ return lib in vndk or lib in vndk_indirect
+
+ # Find VNDK-EXT libs (VNDK libs with extended definitions and the
+ # extended definitions are used by the vendor modules (including
+ # extra_vendor_libs).
- # Compute the extended usages from vendor partition.
# FIXME: DAUX libraries won't be found by the following algorithm.
vndk_ext = set()
@@ -1413,11 +1510,27 @@ class ELFLinker(object):
return result
candidates = collect_vndk_ext(self.lib_pt[PT_VENDOR].values())
+ candidates |= collect_vndk_ext(extra_vendor_libs)
while candidates:
vndk_ext |= candidates
candidates = collect_vndk_ext(candidates)
+ # Compute LL-NDK-Indirect and SP-NDK-Indirect.
+ def is_not_ll_ndk_indirect(lib):
+ return lib.is_ll_ndk or is_vndk_sp(lib) or is_vndk(lib)
+
+ ll_ndk_indirect = self.compute_closure(ll_ndk, is_not_ll_ndk_indirect)
+ ll_ndk_indirect -= ll_ndk
+
+ def is_not_sp_ndk_indirect(lib):
+ return lib.is_ll_ndk or lib.is_sp_ndk or lib in ll_ndk_indirect or \
+ is_vndk_sp(lib) or is_vndk(lib)
+
+ sp_ndk_indirect = self.compute_closure(sp_ndk, is_not_sp_ndk_indirect)
+ sp_ndk_indirect -= sp_ndk
+
+ # Return the VNDK classifications.
return VNDKResult(
ll_ndk=ll_ndk,
ll_ndk_indirect=ll_ndk_indirect,
@@ -1436,9 +1549,9 @@ class ELFLinker(object):
sp_hal_dep=sp_hal_dep,
# vnd_only=vnd_only,
vndk_ext=vndk_ext,
- # vndk_sp_ext=vndk_sp_ext,
- # vndk_sp_indirect_ext=vndk_sp_indirect_ext,
- extra_vndk_sp_indirect=extra_vndk_sp_indirect)
+ vndk_sp_ext=vndk_sp_ext,
+ vndk_sp_indirect_ext=vndk_sp_indirect_ext,
+ extra_vendor_libs=extra_vendor_libs)
def compute_vndk_cap(self, banned_libs):
# ELF files on vendor partitions are banned unconditionally. ELF files
@@ -1748,6 +1861,18 @@ class VNDKCommandBase(ELFGraphCommand):
parser.add_argument('--no-default-dlopen-deps', action='store_true',
help='do not add default dlopen dependencies')
+ parser.add_argument('--tag-file', help='lib tag file')
+
+ parser.add_argument(
+ '--action-ineligible-vndk-sp', default='warn',
+ help='action when a sp-hal uses non-vndk-sp libs '
+ '(option: follow,warn,ignore)')
+
+ parser.add_argument(
+ '--action-ineligible-vndk', default='warn',
+ help='action when a vendor lib/exe uses fwk-only libs '
+ '(option: follow,warn,ignore)')
+
def create_from_args(self, args):
"""Create all essential data structures for VNDK computation."""
@@ -1760,7 +1885,12 @@ class VNDKCommandBase(ELFGraphCommand):
'minimum_dlopen_deps.txt')
graph.load_extra_deps(minimum_dlopen_deps)
- return (generic_refs, graph)
+ if args.tag_file:
+ tagged_paths = TaggedPathDict.create_from_csv_path(args.tag_file)
+ else:
+ tagged_paths = None
+
+ return (generic_refs, graph, tagged_paths)
class VNDKCommand(VNDKCommandBase):
@@ -1779,15 +1909,9 @@ class VNDKCommand(VNDKCommandBase):
'--full', action='store_true',
help='print all classification')
- parser.add_argument('--tag-file', help='lib tag file')
-
- parser.add_argument(
- '--action-ineligible-vndk-sp', default='warn,follow',
- help='action when a sp-hal uses non-vndk-sp libs')
-
parser.add_argument(
- '--action-ineligible-vndk', default='warn,follow',
- help='action when a vendor lib/exe uses fwk-only libs')
+ '--output-format', default='tag',
+ help='output format for vndk classification')
def _warn_incorrect_partition_lib_set(self, lib_set, partition, error_msg):
for lib in lib_set.values():
@@ -1814,8 +1938,74 @@ class VNDKCommand(VNDKCommandBase):
print('warning: {}: NDK library should not be extended.'
.format(lib.path), file=sys.stderr)
+ @staticmethod
+ def _extract_simple_vndk_result(vndk_result):
+ field_name_tags = [
+ ('vndk_sp', 'vndk_sp'),
+ ('vndk_sp_unused', 'vndk_sp'),
+ ('vndk_sp_indirect', 'vndk_sp'),
+ ('vndk_sp_indirect_unused', 'vndk_sp'),
+ ('vndk_sp_indirect_private', 'vndk_sp'),
+
+ ('vndk_sp_ext', 'vndk_sp_ext'),
+ ('vndk_sp_indirect_ext', 'vndk_sp_ext'),
+
+ ('vndk_ext', 'extra_vendor_libs'),
+ ('extra_vendor_libs', 'extra_vendor_libs'),
+ ]
+ results = SimpleVNDKResult()
+ for field_name, tag in field_name_tags:
+ getattr(results, tag).update(getattr(vndk_result, field_name))
+ return results
+
+ def _print_tags(self, vndk_lib, full, file=sys.stdout):
+ if full:
+ result_tags = _VNDK_RESULT_FIELD_NAMES
+ results = vndk_lib
+ else:
+ # Simplified VNDK output with only three sets.
+ result_tags = _SIMPLE_VNDK_RESULT_FIELD_NAMES
+ results = self._extract_simple_vndk_result(vndk_lib)
+
+ for tag in result_tags:
+ libs = getattr(results, tag)
+ tag += ':'
+ for lib in sorted_lib_path_list(libs):
+ print(tag, lib, file=file)
+
+ def _print_make(self, vndk_lib, file=sys.stdout):
+ def get_module_name(path):
+ name = os.path.basename(path)
+ root, ext = os.path.splitext(name)
+ return root
+
+ def get_module_names(lib_set):
+ return sorted({ get_module_name(lib.path) for lib in lib_set })
+
+ results = self._extract_simple_vndk_result(vndk_lib)
+ vndk_sp = get_module_names(results.vndk_sp)
+ vndk_sp_ext = get_module_names(results.vndk_sp_ext)
+ extra_vendor_libs= get_module_names(results.extra_vendor_libs)
+
+ def format_module_names(module_names):
+ return '\\\n ' + ' \\\n '.join(module_names)
+
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ template_path = os.path.join(script_dir, 'templates', 'vndk.txt')
+ with open(template_path, 'r') as f:
+ template = f.read()
+
+ template = template.replace('##_VNDK_SP_##',
+ format_module_names(vndk_sp))
+ template = template.replace('##_VNDK_SP_EXT_##',
+ format_module_names(vndk_sp_ext))
+ template = template.replace('##_EXTRA_VENDOR_LIBS_##',
+ format_module_names(extra_vendor_libs))
+
+ file.write(template)
+
def main(self, args):
- generic_refs, graph = self.create_from_args(args)
+ generic_refs, graph, tagged_paths = self.create_from_args(args)
# Check the API extensions to NDK libraries.
if generic_refs:
@@ -1824,25 +2014,17 @@ class VNDKCommand(VNDKCommandBase):
if args.warn_incorrect_partition:
self._warn_incorrect_partition(graph)
- if args.tag_file:
- tagged_paths = TaggedPathDict.create_from_csv_path(args.tag_file)
- else:
- tagged_paths = None
-
# Compute vndk heuristics.
- sp_lib = graph.compute_sp_lib(generic_refs)
vndk_lib = graph.compute_degenerated_vndk(
- sp_lib, generic_refs, tagged_paths,
- args.action_ineligible_vndk_sp, args.action_ineligible_vndk)
+ generic_refs, tagged_paths, args.action_ineligible_vndk_sp,
+ args.action_ineligible_vndk)
# Print results.
- field_names = ['extra_vndk_sp_indirect', 'vndk_ext']
- if args.full:
- field_names = _VNDK_RESULT_FIELD_NAMES
- for field_name in field_names:
- tag = field_name + ':'
- for lib in sorted_lib_path_list(getattr(vndk_lib, field_name)):
- print(tag, lib)
+ if args.output_format == 'make':
+ self._print_make(vndk_lib)
+ else:
+ self._print_tags(vndk_lib, args.full)
+
return 0
@@ -1858,11 +2040,12 @@ class DepsInsightCommand(VNDKCommandBase):
'--output', '-o', help='output directory')
def main(self, args):
- generic_refs, graph = self.create_from_args(args)
+ generic_refs, graph, tagged_paths = self.create_from_args(args)
# Compute vndk heuristics.
- sp_lib = graph.compute_sp_lib(generic_refs)
- vndk_lib = graph.compute_degenerated_vndk(sp_lib, generic_refs)
+ vndk_lib = graph.compute_degenerated_vndk(
+ generic_refs, tagged_paths, args.action_ineligible_vndk_sp,
+ args.action_ineligible_vndk)
# Serialize data.
strs = []