diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index 4c7e98445..5d1e2ae4c 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -1566,6 +1566,28 @@ class LibProperties(object): return root + '-properties' + ext +#------------------------------------------------------------------------------ +# Public Libraries +#------------------------------------------------------------------------------ + +class PublicLibSet(object): + def __init__(self): + self._lib_names = set() + + + def load_from_public_libraries_txt(self, config_path): + with open(config_path, 'r') as config_file: + for line in config_file: + line = line.strip() + if line and not line.startswith('#'): + self._lib_names.add(line) + + + def is_public_lib(self, path): + lib_name = os.path.basename(path) + return lib_name in self._lib_names + + #------------------------------------------------------------------------------ # ELF Linker #------------------------------------------------------------------------------ @@ -4126,8 +4148,19 @@ class CheckDepCommand(CheckDepCommandBase): help='Do not check ordering of DT_NEEDED entries') + def _load_public_lib_names(self, system_dirs, vendor_dirs): + names = PublicLibSet() + for base in itertools.chain(system_dirs, vendor_dirs): + config_path = os.path.join(base, 'etc', 'public.libraries.txt') + try: + names.load_from_public_libraries_txt(config_path) + except FileNotFoundError: + pass + return names + + def _check_vendor_dep(self, graph, tagged_libs, lib_properties, - module_info): + module_info, public_libs): """Check whether vendor libs are depending on non-eligible libs.""" num_errors = 0 @@ -4137,6 +4170,17 @@ class CheckDepCommand(CheckDepCommandBase): eligible_libs = (tagged_libs.ll_ndk | tagged_libs.vndk_sp | tagged_libs.vndk_sp_private | tagged_libs.vndk) + def _is_app_lib(lib): + app_dirs = [ + '/product/app', + '/product/priv-app', + '/product_services/app', + '/product_services/priv-app', + '/vendor/app', + '/vendor/priv-app', + ] + return any(_is_under_dir(d, lib.path) for d in app_dirs) + for lib in sorted(vendor_libs): bad_deps = set() @@ -4154,6 +4198,12 @@ class CheckDepCommand(CheckDepCommandBase): # Check whether vendor modules depend on ineligible libs. for dep in lib.deps_all: if dep not in vendor_libs and dep not in eligible_libs: + if _is_app_lib(lib) and public_libs.is_public_lib(dep.path): + # It is fine for APK files to depend on public + # libraries (including NDK or other explicitly exposed + # libs). + continue + num_errors += 1 bad_deps.add(dep) @@ -4256,8 +4306,10 @@ class CheckDepCommand(CheckDepCommandBase): lib_properties = \ LibProperties.load_from_path_or_default(lib_properties_path) + public_libs = self._load_public_lib_names(args.system, args.vendor) + num_errors = self._check_vendor_dep(graph, tagged_libs, lib_properties, - module_info) + module_info, public_libs) if args.check_dt_needed_ordering: num_errors += self._check_dt_needed_ordering(graph)