Merge changes I6eb07d50,I15cc1568,I70b7132f

* changes:
  def-tool: Do not emit errors on public.libraries.txt
  def-tool: Support product and product_services partition
  def-tool: Remove a dead argument (cont)
This commit is contained in:
Logan Chien
2019-06-03 18:33:45 +00:00
committed by Gerrit Code Review
3 changed files with 309 additions and 83 deletions

View File

@@ -22,6 +22,8 @@ _TEST_DATA = '''Path,Tag
/vendor/lib/lib_sp_hal.so,sp-hal
/vendor/lib/lib_sp_hal_dep.so,sp-hal-dep
/vendor/lib/lib_vendor_only.so,vendor-only
/product/lib/lib_product_only.so,product-only
/product_services/lib/lib_product_services_only.so,product_services-only
/system/lib/lib_remove.so,remove
/system/lib/lib_hl_ndk.so,hl-ndk
/system/lib/lib_vndk_private.so,vndk-private
@@ -58,6 +60,8 @@ class TaggedDictTest(unittest.TestCase):
def _check_tag_visibility(self, d, from_tag, visible_tags):
for to_tag in visible_tags:
self.assertTrue(d.is_tag_visible(from_tag, to_tag))
for to_tag in TaggedDict.TAGS:
self.assertEqual(d.is_tag_visible(from_tag, to_tag),
to_tag in visible_tags)
@@ -72,24 +76,30 @@ class TaggedDictTest(unittest.TestCase):
self._check_tag_visibility(d, 'll_ndk_private', visible_tags)
# VNDK-SP
visible_tags = {'ll_ndk', 'vndk_sp', 'vndk_sp_private',
'system_only_rs'}
visible_tags = {
'll_ndk', 'vndk_sp', 'vndk_sp_private', 'system_only_rs',
}
self._check_tag_visibility(d, 'vndk_sp', visible_tags)
self._check_tag_visibility(d, 'vndk_sp_private', visible_tags)
# VNDK
visible_tags = {'ll_ndk', 'vndk_sp', 'vndk_sp_private',
'vndk', 'vndk_private'}
visible_tags = {
'll_ndk', 'vndk_sp', 'vndk_sp_private', 'vndk', 'vndk_private',
}
self._check_tag_visibility(d, 'vndk', visible_tags)
# SYSTEM-ONLY
visible_tags = {'ll_ndk', 'll_ndk_private',
'vndk_sp', 'vndk_sp_private',
'vndk', 'vndk_private',
'system_only', 'system_only_rs',
'sp_hal'}
# SYSTEM-ONLY and PRODUCT_SERVICES-ONLY
visible_tags = {
'll_ndk', 'll_ndk_private',
'vndk_sp', 'vndk_sp_private',
'vndk', 'vndk_private',
'system_only', 'system_only_rs',
'product_services_only',
'sp_hal'
}
self._check_tag_visibility(d, 'system_only', visible_tags)
self._check_tag_visibility(d, 'system_only_rs', visible_tags)
self._check_tag_visibility(d, 'product_services_only', visible_tags)
# SP-HAL
visible_tags = {'ll_ndk', 'vndk_sp', 'sp_hal', 'sp_hal_dep'}
@@ -97,8 +107,17 @@ class TaggedDictTest(unittest.TestCase):
self._check_tag_visibility(d, 'sp_hal_dep', visible_tags)
# VENDOR-ONLY
visible_tags = {'ll_ndk', 'vndk_sp', 'vndk', 'sp_hal', 'sp_hal_dep',
'vendor_only'}
visible_tags = {
'll_ndk', 'vndk_sp', 'vndk', 'sp_hal', 'sp_hal_dep', 'vendor_only',
}
self._check_tag_visibility(d, 'vendor_only', visible_tags)
# PRODUCT-ONLY
visible_tags = {
'll_ndk', 'vndk_sp', 'vndk', 'sp_hal',
# Remove the following after VNDK-ext can be checked separately.
'sp_hal_dep', 'vendor_only',
}
self._check_tag_visibility(d, 'vendor_only', visible_tags)
# Remove
@@ -182,6 +201,9 @@ class TaggedPathDictTest(unittest.TestCase):
self.assertIn('/vendor/lib/lib_sp_hal.so', d.sp_hal)
self.assertIn('/vendor/lib/lib_sp_hal_dep.so', d.sp_hal_dep)
self.assertIn('/vendor/lib/lib_vendor_only.so', d.vendor_only)
self.assertIn('/product_services/lib/lib_product_services_only.so',
d.product_services_only)
self.assertIn('/product/lib/lib_product_only.so', d.product_only)
self.assertIn('/system/lib/lib_remove.so', d.remove)
# Aliases
@@ -339,6 +361,7 @@ class TaggedPathDictTest(unittest.TestCase):
'/system/lib/lib_system_only.so',
'/system/lib/lib_system_only_rs.so',
'/vendor/lib/lib_sp_hal.so',
'/product_services/lib/lib_product_services_only.so',
}
self._check_path_visibility(d, all_paths, from_paths, visible_paths)

View File

@@ -108,7 +108,7 @@ class VNDKLibDirTest(unittest.TestCase):
VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-sp-28/liba.so'))
def test_create_vndk_search_paths(self):
def test_get_vndk_lib_dirs(self):
for version in ('current', '28'):
for lib_dir in ('lib', 'lib64'):
vndk_sp_name = VNDKLibDir.create_vndk_sp_dir_name(version)
@@ -124,7 +124,7 @@ class VNDKLibDirTest(unittest.TestCase):
]
vndk_sp_dirs, vndk_dirs = \
VNDKLibDir.create_vndk_search_paths(lib_dir, version)
VNDKLibDir.get_vndk_lib_dirs(lib_dir, version)
self.assertEqual(expected_vndk_sp, vndk_sp_dirs)
self.assertEqual(expected_vndk, vndk_dirs)

View File

@@ -1190,6 +1190,16 @@ class DexFileReader(object):
return None
#------------------------------------------------------------------------------
# Path Functions
#------------------------------------------------------------------------------
def _is_under_dir(dir_path, path):
dir_path = os.path.abspath(dir_path)
path = os.path.abspath(path)
return path == dir_path or path.startswith(dir_path + os.path.sep)
#------------------------------------------------------------------------------
# TaggedDict
#------------------------------------------------------------------------------
@@ -1203,6 +1213,8 @@ class TaggedDict(object):
'system_only', 'system_only_rs',
'sp_hal', 'sp_hal_dep',
'vendor_only',
'product_services_only',
'product_only',
'remove',
]
assert len(tag_list) < 32
@@ -1243,17 +1255,38 @@ class TaggedDict(object):
return tag
_LL_NDK_VIS = {'ll_ndk', 'll_ndk_private'}
_LL_NDK_VIS = {
'll_ndk', 'll_ndk_private',
}
_VNDK_SP_VIS = {'ll_ndk', 'vndk_sp', 'vndk_sp_private', 'system_only_rs'}
_VNDK_SP_VIS = {
'll_ndk', 'vndk_sp', 'vndk_sp_private', 'system_only_rs',
}
_VNDK_VIS = {'ll_ndk', 'vndk_sp', 'vndk_sp_private', 'vndk', 'vndk_private'}
_VNDK_VIS = {
'll_ndk', 'vndk_sp', 'vndk_sp_private', 'vndk', 'vndk_private',
}
_SYSTEM_ONLY_VIS = {'ll_ndk', 'll_ndk_private',
'vndk_sp', 'vndk_sp_private',
'vndk', 'vndk_private',
'system_only', 'system_only_rs',
'sp_hal'}
_SYSTEM_ONLY_VIS = {
'll_ndk', 'll_ndk_private',
'vndk_sp', 'vndk_sp_private',
'vndk', 'vndk_private',
'system_only', 'system_only_rs',
'product_services_only',
'sp_hal',
}
_PRODUCT_ONLY_VIS = {
'll_ndk', 'vndk_sp', 'vndk', 'sp_hal',
# Remove the following after VNDK-ext can be checked separately.
'sp_hal_dep', 'vendor_only',
}
_VENDOR_ONLY_VIS = {
'll_ndk', 'vndk_sp', 'vndk', 'sp_hal', 'sp_hal_dep',
'vendor_only',
}
_SP_HAL_VIS = {'ll_ndk', 'vndk_sp', 'sp_hal', 'sp_hal_dep'}
@@ -1269,17 +1302,19 @@ class TaggedDict(object):
'system_only': _SYSTEM_ONLY_VIS,
'system_only_rs': _SYSTEM_ONLY_VIS,
'product_services_only': _SYSTEM_ONLY_VIS,
'sp_hal': _SP_HAL_VIS,
'sp_hal_dep': _SP_HAL_VIS,
'vendor_only': {'ll_ndk', 'vndk_sp', 'vndk', 'sp_hal', 'sp_hal_dep',
'vendor_only'},
'vendor_only': _VENDOR_ONLY_VIS,
'product_only': _PRODUCT_ONLY_VIS,
'remove': set(),
}
del _LL_NDK_VIS, _VNDK_SP_VIS, _VNDK_VIS, _SYSTEM_ONLY_VIS, _SP_HAL_VIS
del _LL_NDK_VIS, _VNDK_SP_VIS, _VNDK_VIS, _SYSTEM_ONLY_VIS, \
_PRODUCT_ONLY_VIS, _VENDOR_ONLY_VIS, _SP_HAL_VIS
@classmethod
@@ -1426,8 +1461,12 @@ class TaggedPathDict(TaggedDict):
@staticmethod
def get_path_tag_default(path):
if path.startswith('/vendor/'):
if _is_under_dir('/vendor', path):
return 'vendor_only'
if _is_under_dir('/product', path):
return 'product_only'
if _is_under_dir('/product_services', path):
return 'product_services_only'
return 'system_only'
@@ -1459,6 +1498,13 @@ class TaggedLibDict(object):
d.add('sp_hal_dep', lib)
else:
d.add('vendor_only', lib)
for lib in graph.lib_pt[PT_PRODUCT].values():
d.add('vendor_only', lib)
for lib in graph.lib_pt[PT_PRODUCT_SERVICES].values():
d.add('vendor_only', lib)
return d
@@ -1520,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
#------------------------------------------------------------------------------
@@ -1679,7 +1747,9 @@ def scan_elf_files(root, mount_point=None, unzip_files=True):
PT_SYSTEM = 0
PT_VENDOR = 1
NUM_PARTITIONS = 2
PT_PRODUCT = 2
PT_PRODUCT_SERVICES = 3
NUM_PARTITIONS = 4
SPLibResult = collections.namedtuple(
@@ -1771,7 +1841,7 @@ class VNDKLibDir(list):
@classmethod
def create_vndk_search_paths(cls, lib_dir, version):
def get_vndk_lib_dirs(cls, lib_dir, version):
"""Create VNDK/VNDK-SP search paths from lib_dir and version."""
vndk_sp_name = cls.create_vndk_sp_dir_name(version)
vndk_name = cls.create_vndk_dir_name(version)
@@ -2305,7 +2375,7 @@ class ELFLinker(object):
def add_executables_in_dir(self, partition_name, partition, root,
alter_partition, alter_subdirs, ignored_subdirs,
scan_elf_files, unzip_files):
unzip_files):
root = os.path.abspath(root)
prefix_len = len(root) + 1
@@ -2407,35 +2477,88 @@ class ELFLinker(object):
self._resolve_lib_deps(lib, resolver, generic_refs)
def _get_apex_bionic_search_paths(self, lib_dir):
def _get_apex_bionic_lib_dirs(self, lib_dir):
return ['/apex/com.android.runtime/' + lib_dir + '/bionic']
def _get_apex_search_paths(self, lib_dir):
def _get_apex_lib_dirs(self, lib_dir):
return ['/apex/' + name + '/' + lib_dir
for name in sorted(self.apex_module_names)]
def _get_system_search_paths(self, lib_dir):
apex_lib_dirs = (self._get_apex_search_paths(lib_dir) +
self._get_apex_bionic_search_paths(lib_dir))
system_lib_dirs = ['/system/' + lib_dir, '/system/product/' + lib_dir]
vendor_lib_dirs = ['/vendor/' + lib_dir]
return apex_lib_dirs + system_lib_dirs + vendor_lib_dirs
def _get_system_lib_dirs(self, lib_dir):
return ['/system/' + lib_dir]
def _get_vendor_search_paths(self, lib_dir, vndk_sp_dirs, vndk_dirs):
vendor_lib_dirs = [
def _get_product_services_lib_dirs(self, lib_dir):
return [
'/product_services/' + lib_dir,
'/system/product_services/' + lib_dir,
]
def _get_vendor_lib_dirs(self, lib_dir):
return [
'/vendor/' + lib_dir + '/hw',
'/vendor/' + lib_dir + '/egl',
'/vendor/' + lib_dir,
]
# For degenerated VNDK libs.
apex_lib_dirs = (self._get_apex_search_paths(lib_dir) +
self._get_apex_bionic_search_paths(lib_dir))
system_lib_dirs = ['/system/' + lib_dir]
return (vendor_lib_dirs + vndk_sp_dirs + vndk_dirs + apex_lib_dirs +
system_lib_dirs)
def _get_product_lib_dirs(self, lib_dir):
return [
'/product/' + lib_dir,
'/system/product/' + lib_dir,
]
def _get_system_search_paths(self, lib_dir):
return (
self._get_apex_bionic_lib_dirs(lib_dir) +
self._get_apex_lib_dirs(lib_dir) +
self._get_product_services_lib_dirs(lib_dir) +
self._get_system_lib_dirs(lib_dir) +
# Search '/vendor/${LIB}' and '/product/${LIB}' to detect
# violations.
self._get_product_lib_dirs(lib_dir) +
self._get_vendor_lib_dirs(lib_dir)
)
def _get_vendor_search_paths(self, lib_dir, vndk_sp_dirs, vndk_dirs):
return (
self._get_vendor_lib_dirs(lib_dir) +
vndk_sp_dirs +
vndk_dirs +
# Search '/apex/*/${LIB}' and '/system/${LIB}' for degenerated VNDK
# and LL-NDK or to detect violations.
self._get_apex_bionic_lib_dirs(lib_dir) +
self._get_apex_lib_dirs(lib_dir) +
self._get_system_lib_dirs(lib_dir)
)
def _get_product_search_paths(self, lib_dir, vndk_sp_dirs, vndk_dirs):
return (
self._get_product_lib_dirs(lib_dir) +
vndk_sp_dirs +
vndk_dirs +
# Search '/vendor/${LIB}', '/system/${LIB}', and '/apex/*/${LIB}'
# for degenerated VNDK and LL-NDK or to detect violations.
self._get_vendor_lib_dirs(lib_dir) +
self._get_apex_bionic_lib_dirs(lib_dir) +
self._get_apex_lib_dirs(lib_dir) +
self._get_system_lib_dirs(lib_dir)
)
def _get_product_services_search_paths(self, lib_dir):
# Delegate to _get_system_search_paths() because there is no ABI
# boundary between system and product_services partition.
return self._get_system_search_paths(lib_dir)
def _get_vndk_sp_search_paths(self, lib_dir, vndk_sp_dirs):
@@ -2444,16 +2567,21 @@ class ELFLinker(object):
'/vendor/' + lib_dir,
'/system/' + lib_dir,
]
fallback_lib_dirs += self._get_apex_search_paths(lib_dir)
fallback_lib_dirs += self._get_apex_bionic_search_paths(lib_dir)
fallback_lib_dirs += self._get_apex_bionic_lib_dirs(lib_dir)
fallback_lib_dirs += self._get_apex_lib_dirs(lib_dir)
return vndk_sp_dirs + fallback_lib_dirs
def _get_vndk_search_paths(self, lib_dir, vndk_sp_dirs, vndk_dirs):
# To find missing dependencies or LL-NDK.
fallback_lib_dirs = ['/system/' + lib_dir]
fallback_lib_dirs += self._get_apex_search_paths(lib_dir)
fallback_lib_dirs += self._get_apex_bionic_search_paths(lib_dir)
fallback_lib_dirs = [
'/vendor/' + lib_dir,
'/system/' + lib_dir,
]
fallback_lib_dirs += self._get_apex_bionic_lib_dirs(lib_dir)
fallback_lib_dirs += self._get_apex_lib_dirs(lib_dir)
return vndk_sp_dirs + vndk_dirs + fallback_lib_dirs
@@ -2478,7 +2606,7 @@ class ELFLinker(object):
# Resolve vndk-sp libs
for version in vndk_lib_dirs:
vndk_sp_dirs, vndk_dirs = \
vndk_lib_dirs.create_vndk_search_paths(lib_dir, version)
vndk_lib_dirs.get_vndk_lib_dirs(lib_dir, version)
vndk_sp_libs = \
system_vndk_sp_libs[version] | vendor_vndk_sp_libs[version]
search_paths = self._get_vndk_sp_search_paths(
@@ -2489,7 +2617,7 @@ class ELFLinker(object):
# Resolve vndk libs
for version in vndk_lib_dirs:
vndk_sp_dirs, vndk_dirs = \
vndk_lib_dirs.create_vndk_search_paths(lib_dir, version)
vndk_lib_dirs.get_vndk_lib_dirs(lib_dir, version)
vndk_libs = system_vndk_libs[version] | vendor_vndk_libs[version]
search_paths = self._get_vndk_search_paths(
lib_dir, vndk_sp_dirs, vndk_dirs)
@@ -2497,13 +2625,30 @@ class ELFLinker(object):
self._resolve_lib_set_deps(vndk_libs, resolver, generic_refs)
# Resolve vendor libs.
vndk_sp_dirs, vndk_dirs = vndk_lib_dirs.create_vndk_search_paths(
vndk_sp_dirs, vndk_dirs = vndk_lib_dirs.get_vndk_lib_dirs(
lib_dir, self.ro_vndk_version)
search_paths = self._get_vendor_search_paths(
lib_dir, vndk_sp_dirs, vndk_dirs)
resolver = ELFResolver(lib_dict, search_paths)
self._resolve_lib_set_deps(vendor_libs, resolver, generic_refs)
# Resolve product libs
product_lib_dict = self.lib_pt[PT_PRODUCT].get_lib_dict(elf_class)
product_libs = set(product_lib_dict.values())
search_paths = self._get_product_search_paths(
lib_dir, vndk_sp_dirs, vndk_dirs)
resolver = ELFResolver(lib_dict, search_paths)
self._resolve_lib_set_deps(product_libs, resolver, generic_refs)
# Resolve product_services libs
product_services_lib_dict = \
self.lib_pt[PT_PRODUCT_SERVICES].get_lib_dict(elf_class)
product_services_libs = set(product_services_lib_dict.values())
search_paths = self._get_product_services_search_paths(lib_dir)
resolver = ELFResolver(lib_dict, search_paths)
self._resolve_lib_set_deps(
product_services_libs, resolver, generic_refs)
def resolve_deps(self, generic_refs=None):
self._resolve_elf_class_deps('lib', ELF.ELFCLASS32, generic_refs)
@@ -2911,11 +3056,12 @@ class ELFLinker(object):
@staticmethod
def _create_internal(system_dirs, system_dirs_as_vendor,
system_dirs_ignored, vendor_dirs,
vendor_dirs_as_system, vendor_dirs_ignored,
extra_deps, generic_refs, tagged_paths,
vndk_lib_dirs, unzip_files):
def create(system_dirs=None, system_dirs_as_vendor=None,
system_dirs_ignored=None, vendor_dirs=None,
vendor_dirs_as_system=None, vendor_dirs_ignored=None,
product_dirs=None, product_services_dirs=None,
extra_deps=None, generic_refs=None, tagged_paths=None,
vndk_lib_dirs=None, unzip_files=True):
if vndk_lib_dirs is None:
vndk_lib_dirs = VNDKLibDir.create_from_dirs(
system_dirs, vendor_dirs)
@@ -2936,6 +3082,18 @@ class ELFLinker(object):
vendor_dirs_as_system, vendor_dirs_ignored,
unzip_files)
if product_dirs:
for path in product_dirs:
graph.add_executables_in_dir(
'product', PT_PRODUCT, path, None, None, None,
unzip_files)
if product_services_dirs:
for path in product_services_dirs:
graph.add_executables_in_dir(
'product_services', PT_PRODUCT_SERVICES, path, None,
None, None, unzip_files)
if extra_deps:
for path in extra_deps:
graph.add_dlopen_deps(path)
@@ -2946,19 +3104,6 @@ class ELFLinker(object):
return graph
@staticmethod
def create(system_dirs=None, system_dirs_as_vendor=None,
system_dirs_ignored=None, vendor_dirs=None,
vendor_dirs_as_system=None, vendor_dirs_ignored=None,
extra_deps=None, generic_refs=None, tagged_paths=None,
vndk_lib_dirs=None, unzip_files=True):
return ELFLinker._create_internal(
system_dirs, system_dirs_as_vendor,
system_dirs_ignored, vendor_dirs, vendor_dirs_as_system,
vendor_dirs_ignored, extra_deps, generic_refs, tagged_paths,
vndk_lib_dirs, unzip_files)
#------------------------------------------------------------------------------
# Generic Reference
#------------------------------------------------------------------------------
@@ -3074,16 +3219,24 @@ def _enumerate_partition_paths(partition, root):
yield (android_path, path)
def _enumerate_paths(system_dirs, vendor_dirs):
def _enumerate_paths(system_dirs, vendor_dirs, product_dirs,
product_services_dirs):
for root in system_dirs:
for ap, path in _enumerate_partition_paths('system', root):
yield (ap, path)
for root in vendor_dirs:
for ap, path in _enumerate_partition_paths('vendor', root):
yield (ap, path)
for root in product_dirs:
for ap, path in _enumerate_partition_paths('product', root):
yield (ap, path)
for root in product_services_dirs:
for ap, path in _enumerate_partition_paths('product_services', root):
yield (ap, path)
def scan_apk_dep(graph, system_dirs, vendor_dirs):
def scan_apk_dep(graph, system_dirs, vendor_dirs, product_dirs,
product_services_dirs):
libnames = _build_lib_names_dict(graph)
results = []
@@ -3094,7 +3247,8 @@ def scan_apk_dep(graph, system_dirs, vendor_dirs):
def decode(string): # PY3
return string.decode('mutf-8')
for ap, path in _enumerate_paths(system_dirs, vendor_dirs):
for ap, path in _enumerate_paths(system_dirs, vendor_dirs,
product_dirs, product_services_dirs):
# Read the dex file from various file formats
try:
dex_string_iter = DexFileReader.enumerate_dex_strings(path)
@@ -3254,13 +3408,22 @@ class ELFGraphCommand(Command):
help='load extra module dependencies')
parser.add_argument(
'--system', action='append',
'--system', action='append', default=[],
help='path to system partition contents')
parser.add_argument(
'--vendor', action='append',
'--vendor', action='append', default=[],
help='path to vendor partition contents')
parser.add_argument(
'--product', action='append', default=[],
help='path to product partition contents')
parser.add_argument(
'--product-services', action='append', default=[],
help='path to product_services partition contents')
# XXX: BEGIN: Remove these options
parser.add_argument(
'--system-dir-as-vendor', action='append',
help='sub directory of system partition that has vendor files')
@@ -3276,6 +3439,7 @@ class ELFGraphCommand(Command):
parser.add_argument(
'--vendor-dir-ignored', action='append',
help='sub directory of vendor partition that must be ignored')
# XXX: END: Remove these options
parser.add_argument(
'--load-generic-refs',
@@ -3322,6 +3486,8 @@ class ELFGraphCommand(Command):
def check_dirs_from_args(self, args):
self._check_arg_dir_exists('--system', args.system)
self._check_arg_dir_exists('--vendor', args.vendor)
self._check_arg_dir_exists('--product', args.product)
self._check_arg_dir_exists('--product-services', args.product_services)
def create_from_args(self, args):
@@ -3341,6 +3507,8 @@ class ELFGraphCommand(Command):
args.system_dir_ignored,
args.vendor, args.vendor_dir_as_system,
args.vendor_dir_ignored,
args.product,
args.product_services,
args.load_extra_deps,
generic_refs=generic_refs,
tagged_paths=tagged_paths,
@@ -3899,7 +4067,8 @@ class ApkDepsCommand(ELFGraphCommand):
def main(self, args):
_, graph, _, _ = self.create_from_args(args)
apk_deps = scan_apk_dep(graph, args.system, args.vendor)
apk_deps = scan_apk_dep(graph, args.system, args.vendor, args.product,
args.product_services)
for apk_path, dep_paths in apk_deps:
print(apk_path)
@@ -3979,16 +4148,39 @@ 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
vendor_libs = set(graph.lib_pt[PT_VENDOR].values())
vendor_libs.update(graph.lib_pt[PT_PRODUCT].values())
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()
@@ -4006,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)
@@ -4064,7 +4262,8 @@ class CheckDepCommand(CheckDepCommandBase):
return num_errors
def _check_apk_dep(self, graph, system_dirs, vendor_dirs, module_info):
def _check_apk_dep(self, graph, system_dirs, vendor_dirs, product_dirs,
product_services_dirs, module_info):
num_errors = 0
def is_in_system_partition(path):
@@ -4072,7 +4271,8 @@ class CheckDepCommand(CheckDepCommandBase):
path.startswith('/product/') or \
path.startswith('/oem/')
apk_deps = scan_apk_dep(graph, system_dirs, vendor_dirs)
apk_deps = scan_apk_dep(graph, system_dirs, vendor_dirs, product_dirs,
product_services_dirs)
for apk_path, dep_paths in apk_deps:
apk_in_system = is_in_system_partition(apk_path)
@@ -4106,15 +4306,18 @@ 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)
if args.check_apk:
num_errors += self._check_apk_dep(graph, args.system, args.vendor,
module_info)
num_errors += self._check_apk_dep(
graph, args.system, args.vendor, args.product,
args.product_services, module_info)
return 0 if num_errors == 0 else 1