diff --git a/vndk/tools/header-checker/tests/gen_all.py b/vndk/tools/header-checker/tests/gen_all.py index 474b7228a..7b4f5d893 100755 --- a/vndk/tools/header-checker/tests/gen_all.py +++ b/vndk/tools/header-checker/tests/gen_all.py @@ -34,7 +34,7 @@ def main(): output_path = os.path.join(EXPECTED_DIR, input_rel_path) print('generating', output_path, '...') - output_content = run_header_abi_dumper(input_path, True) + output_content = run_header_abi_dumper(input_path) os.makedirs(os.path.dirname(output_path), exist_ok=True) with open(output_path, 'w') as f: diff --git a/vndk/tools/header-checker/tests/module.py b/vndk/tools/header-checker/tests/module.py index a3ae37946..a2236bf3a 100755 --- a/vndk/tools/header-checker/tests/module.py +++ b/vndk/tools/header-checker/tests/module.py @@ -91,7 +91,7 @@ class SdumpModule(Module): def make_dump(self): return run_header_abi_dumper( - self.src, remove_absolute_paths=True, cflags=self.cflags, + self.src, cflags=self.cflags, export_include_dirs=self.export_include_dirs, flags=self.dumper_flags) diff --git a/vndk/tools/header-checker/tests/test.py b/vndk/tools/header-checker/tests/test.py index 71d626087..cc86890ef 100755 --- a/vndk/tools/header-checker/tests/test.py +++ b/vndk/tools/header-checker/tests/test.py @@ -54,7 +54,7 @@ class HeaderCheckerTest(unittest.TestCase): def run_and_compare(self, input_path, expected_path, cflags=[]): with open(expected_path, 'r') as f: expected_output = f.read() - actual_output = run_header_abi_dumper(input_path, True, cflags) + actual_output = run_header_abi_dumper(input_path, cflags) self.assertEqual(actual_output, expected_output) def run_and_compare_name(self, name, cflags=[]): diff --git a/vndk/tools/header-checker/utils/create_reference_dumps.py b/vndk/tools/header-checker/utils/create_reference_dumps.py index f27c2b059..80e51d232 100755 --- a/vndk/tools/header-checker/utils/create_reference_dumps.py +++ b/vndk/tools/header-checker/utils/create_reference_dumps.py @@ -9,7 +9,8 @@ import time from utils import ( AOSP_DIR, COMPRESSED_SOURCE_ABI_DUMP_EXT, SOURCE_ABI_DUMP_EXT, SOURCE_ABI_DUMP_EXT_END, SO_EXT, copy_reference_dumps, find_lib_lsdumps, - get_build_vars_for_product, make_libraries, make_tree) + get_build_vars_for_product, get_module_variant_dir_name, make_libraries, + make_tree) PRODUCTS_DEFAULT = ['aosp_arm_ab', 'aosp_arm', 'aosp_arm64', 'aosp_x86_ab', @@ -64,13 +65,53 @@ def get_lib_arch_str(target): return target.arch + target_arch_variant_str +# FIXME (b/121986692): Before aosp/858259 is merged, apex mutator adds +# `_platform` suffix if the module is used by some apex modules. This +# workaround searches for lsdump with and without `_platform`. +_WORKAROUND_APEX_PLATFORM_LSDUMPS = True + +if _WORKAROUND_APEX_PLATFORM_LSDUMPS: + def _find_lib_lsdumps_workaround(dir_name, lsdump_paths, libs): + dir_name_platform = dir_name + '_platform' + + matched_lsdump_paths = set(find_lib_lsdumps( + dir_name, lsdump_paths, libs)) + + matched_lsdump_paths_platform = set(find_lib_lsdumps( + dir_name_platform, lsdump_paths, libs)) + + # Pick the lsdump file with latest modification time if both of them + # exist. + matched_lsdump_paths_replaced = set( + path.replace(dir_name, dir_name_platform) + for path in matched_lsdump_paths) + + both = matched_lsdump_paths_replaced & matched_lsdump_paths_platform + + for path_platform in both: + path = path_platform.replace(dir_name_platform, dir_name) + if os.stat(path).st_mtime >= os.stat(path_platform).st_mtime: + matched_lsdump_paths_platform.remove(path_platform) + else: + matched_lsdump_paths.remove(path) + + return sorted(matched_lsdump_paths | matched_lsdump_paths_platform) + + def find_and_copy_lib_lsdumps(target, ref_dump_dir_stem, ref_dump_dir_insertion, core_or_vendor_shared_str, libs, lsdump_paths, compress): - arch_lsdump_paths = find_lib_lsdumps(target.arch, target.arch_variant, - target.cpu_variant, lsdump_paths, - core_or_vendor_shared_str, - libs) + module_variant_dir_name = get_module_variant_dir_name( + target.arch, target.arch_variant, target.cpu_variant, + core_or_vendor_shared_str) + + if _WORKAROUND_APEX_PLATFORM_LSDUMPS: + arch_lsdump_paths = _find_lib_lsdumps_workaround( + module_variant_dir_name, lsdump_paths, libs) + else: + arch_lsdump_paths = find_lib_lsdumps( + module_variant_dir_name, lsdump_paths, libs) + # Copy the contents of the lsdump into their corresponding reference ABI # dumps directories. return copy_reference_dumps(arch_lsdump_paths, ref_dump_dir_stem, diff --git a/vndk/tools/header-checker/utils/utils.py b/vndk/tools/header-checker/utils/utils.py index 04cee115e..db08558e1 100644 --- a/vndk/tools/header-checker/utils/utils.py +++ b/vndk/tools/header-checker/utils/utils.py @@ -82,22 +82,23 @@ def read_output_content(output_path, replace_str): return f.read().replace(replace_str, '') -def run_header_abi_dumper(input_path, remove_absolute_paths, cflags=tuple(), +def run_header_abi_dumper(input_path, cflags=tuple(), export_include_dirs=EXPORTED_HEADERS_DIR, flags=tuple()): + """Run header-abi-dumper to dump ABI from `input_path` and return the + output.""" with tempfile.TemporaryDirectory() as tmp: output_path = os.path.join(tmp, os.path.basename(input_path)) + '.dump' run_header_abi_dumper_on_file(input_path, output_path, export_include_dirs, cflags, flags) - if remove_absolute_paths: - return read_output_content(output_path, AOSP_DIR) - with open(output_path, 'r') as f: - return f.read() + return read_output_content(output_path, AOSP_DIR) def run_header_abi_dumper_on_file(input_path, output_path, export_include_dirs=tuple(), cflags=tuple(), flags=tuple()): + """Run header-abi-dumper to dump ABI from `input_path` and the output is + written to `output_path`.""" input_ext = os.path.splitext(input_path)[1] cmd = ['header-abi-dumper', '-o', output_path, input_path] for dir in export_include_dirs: @@ -163,31 +164,36 @@ def make_libraries(libs, product, variant, llndk_mode): make_targets(lib_targets, product, variant) -def find_lib_lsdumps(target_arch, target_arch_variant, - target_cpu_variant, lsdump_paths, - core_or_vendor_shared_str, libs): - """ Find the lsdump corresponding to lib_name for the given arch parameters - if it exists""" - assert 'ANDROID_PRODUCT_OUT' in os.environ - cpu_variant = '_' + target_cpu_variant - arch_variant = '_' + target_arch_variant - arch_lsdump_paths = [] - if (target_cpu_variant == 'generic' or target_cpu_variant is None or - target_cpu_variant == ''): - cpu_variant = '' - if (target_arch_variant == target_arch or target_arch_variant is None or - target_arch_variant == ''): - arch_variant = '' +def get_module_variant_dir_name(arch, arch_variant, cpu_variant, + variant_suffix): + """Create module variant directory name from the target architecture, the + target architecture variant, the target CPU variant, and a variant suffix + (e.g. `_core_shared`, `_vendor_shared`, etc).""" - target_dir = ('android_' + target_arch + arch_variant + - cpu_variant + core_or_vendor_shared_str) - for key in lsdump_paths: - if libs and key not in libs: + if not arch_variant or arch_variant == arch: + arch_variant = '' + else: + arch_variant = '_' + arch_variant + + if not cpu_variant or cpu_variant == 'generic': + cpu_variant = '' + else: + cpu_variant = '_' + cpu_variant + + return 'android_' + arch + arch_variant + cpu_variant + variant_suffix + + +def find_lib_lsdumps(module_variant_dir_name, lsdump_paths, libs): + """Find the lsdump corresponding to lib_name for the given module variant + if it exists.""" + result = [] + for lib_name, paths in lsdump_paths.items(): + if libs and lib_name not in libs: continue - for path in lsdump_paths[key]: - if target_dir in path: - arch_lsdump_paths.append(os.path.join(AOSP_DIR, path.strip())) - return arch_lsdump_paths + for path in paths: + if module_variant_dir_name in path.split(os.path.sep): + result.append(os.path.join(AOSP_DIR, path.strip())) + return result def run_abi_diff(old_test_dump_path, new_test_dump_path, arch, lib_name,