Merge "Remove string substitution from ABI dump scripts" am: d5a53111c1 am: 1c8d200661 am: 3b9c7009c7 am: 25fa0cc3f9

Original change: https://android-review.googlesource.com/c/platform/development/+/1358242

Change-Id: I9a6eb9d0998688b0d1865a2a8f7c8a3d074f6e6e
This commit is contained in:
Treehugger Robot
2020-07-10 11:01:32 +00:00
committed by Automerger Merge Worker
4 changed files with 61 additions and 66 deletions

View File

@@ -12,6 +12,7 @@ from utils import run_header_abi_dumper
from module import Module from module import Module
from test import INPUT_DIR from test import INPUT_DIR
from test import EXPECTED_DIR from test import EXPECTED_DIR
from test import EXPORTED_HEADER_DIRS
from test import make_and_copy_reference_dumps from test import make_and_copy_reference_dumps
FILE_EXTENSIONS = ['h', 'hpp', 'hxx', 'cpp', 'cc', 'c'] FILE_EXTENSIONS = ['h', 'hpp', 'hxx', 'cpp', 'cc', 'c']
@@ -34,11 +35,10 @@ def main():
output_path = os.path.join(EXPECTED_DIR, input_rel_path) output_path = os.path.join(EXPECTED_DIR, input_rel_path)
print('generating', output_path, '...') print('generating', output_path, '...')
output_content = run_header_abi_dumper(input_path)
os.makedirs(os.path.dirname(output_path), exist_ok=True) os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'w') as f: run_header_abi_dumper(input_path, output_path,
f.write(output_content) export_include_dirs=EXPORTED_HEADER_DIRS)
modules = Module.get_test_modules() modules = Module.get_test_modules()
for module in modules: for module in modules:
print('Created abi dump at', make_and_copy_reference_dumps(module)) print('Created abi dump at', make_and_copy_reference_dumps(module))

View File

@@ -49,8 +49,8 @@ class Module(object):
"""Returns the module name followed by file extension.""" """Returns the module name followed by file extension."""
raise NotImplementedError() raise NotImplementedError()
def make_dump(self): def make_dump(self, output_path):
"""Returns the dump content as a string.""" """Create a dump file."""
raise NotImplementedError() raise NotImplementedError()
def mutate_for_arch(self, target_arch): def mutate_for_arch(self, target_arch):
@@ -88,9 +88,9 @@ class SdumpModule(Module):
def get_dump_name(self): def get_dump_name(self):
return self.name + '.sdump' return self.name + '.sdump'
def make_dump(self): def make_dump(self, output_path):
return run_header_abi_dumper( return run_header_abi_dumper(
self.src, cflags=self.cflags, self.src, output_path, cflags=self.cflags,
export_include_dirs=self.export_include_dirs, export_include_dirs=self.export_include_dirs,
flags=self.dumper_flags) flags=self.dumper_flags)
@@ -114,25 +114,29 @@ class LsdumpModule(Module):
def get_dump_name(self): def get_dump_name(self):
return self.name + SOURCE_ABI_DUMP_EXT return self.name + SOURCE_ABI_DUMP_EXT
def make_dump(self): def make_dump(self, output_path):
"""For each source file, produce a .sdump file, and link them to form """For each source file, produce a .sdump file, and link them to form
an lsump file.""" an lsump file."""
dumps_to_link = [] dumps_to_link = []
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp:
output_lsdump = os.path.join(tmp, self.get_dump_name())
for src in self.srcs: for src in self.srcs:
output_path = os.path.join(tmp, sdump_path = os.path.join(tmp,
os.path.basename(src) + '.sdump') os.path.basename(src) + '.sdump')
dumps_to_link.append(output_path) dumps_to_link.append(sdump_path)
content = run_header_abi_dumper( run_header_abi_dumper(
src, self.cflags + self.arch_cflags, src, sdump_path, self.cflags + self.arch_cflags,
self.export_include_dirs, self.dumper_flags) self.export_include_dirs, self.dumper_flags)
with open(output_path, 'w') as dump_file:
dump_file.write(content) lsdump_path = os.path.join(tmp, self.get_dump_name())
return run_header_abi_linker(output_lsdump, dumps_to_link, run_header_abi_linker(dumps_to_link, lsdump_path,
self.version_script, self.api, self.version_script, self.api, self.arch,
self.arch, self.linker_flags, self.linker_flags)
input_dir=tmp) # Replace the absolute tmp paths in the type ID.
with open(lsdump_path, 'r') as lsdump_file:
content = lsdump_file.read().replace(tmp, '')
with open(output_path, 'w') as output_file:
output_file.write(content)
def mutate_for_arch(self, target_arch): def mutate_for_arch(self, target_arch):
return LsdumpModule(self.name, self.srcs, self.version_script, return LsdumpModule(self.name, self.srcs, self.version_script,

View File

@@ -11,30 +11,30 @@ import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
import_path = os.path.abspath(os.path.join(import_path, 'utils')) import_path = os.path.abspath(os.path.join(import_path, 'utils'))
sys.path.insert(1, import_path) sys.path.insert(1, import_path)
from utils import (AOSP_DIR, read_output_content, run_abi_diff, from utils import run_abi_diff, run_header_abi_dumper
run_header_abi_dumper)
from module import Module from module import Module
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
INPUT_DIR = os.path.join(SCRIPT_DIR, 'input') INPUT_DIR = os.path.join(SCRIPT_DIR, 'input')
EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'expected') EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'expected')
EXPORTED_HEADER_DIRS = (INPUT_DIR,)
REF_DUMP_DIR = os.path.join(SCRIPT_DIR, 'reference_dumps') REF_DUMP_DIR = os.path.join(SCRIPT_DIR, 'reference_dumps')
def make_and_copy_reference_dumps(module, reference_dump_dir=REF_DUMP_DIR): def make_and_copy_reference_dumps(module, reference_dump_dir=REF_DUMP_DIR):
output_content = module.make_dump()
dump_dir = os.path.join(reference_dump_dir, module.arch) dump_dir = os.path.join(reference_dump_dir, module.arch)
os.makedirs(dump_dir, exist_ok=True) os.makedirs(dump_dir, exist_ok=True)
dump_path = os.path.join(dump_dir, module.get_dump_name()) dump_path = os.path.join(dump_dir, module.get_dump_name())
with open(dump_path, 'w') as f: module.make_dump(dump_path)
f.write(output_content)
return dump_path return dump_path
def _read_output_content(dump_path):
with open(dump_path, 'r') as f:
return f.read()
class HeaderCheckerTest(unittest.TestCase): class HeaderCheckerTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@@ -56,7 +56,12 @@ class HeaderCheckerTest(unittest.TestCase):
def run_and_compare(self, input_path, expected_path, cflags=[]): def run_and_compare(self, input_path, expected_path, cflags=[]):
with open(expected_path, 'r') as f: with open(expected_path, 'r') as f:
expected_output = f.read() expected_output = f.read()
actual_output = run_header_abi_dumper(input_path, cflags) with tempfile.NamedTemporaryFile(dir=self.get_tmp_dir(),
delete=False) as f:
output_path = f.name
run_header_abi_dumper(input_path, output_path, cflags,
EXPORTED_HEADER_DIRS)
actual_output = _read_output_content(output_path)
self.assertEqual(actual_output, expected_output) self.assertEqual(actual_output, expected_output)
def run_and_compare_name(self, name, cflags=[]): def run_and_compare_name(self, name, cflags=[]):
@@ -113,9 +118,8 @@ class HeaderCheckerTest(unittest.TestCase):
self.assertEqual(old_module.arch, new_module.arch) self.assertEqual(old_module.arch, new_module.arch)
old_ref_dump_path = self.get_or_create_ref_dump(old_module, False) old_ref_dump_path = self.get_or_create_ref_dump(old_module, False)
new_ref_dump_path = self.get_or_create_ref_dump(new_module, True) new_ref_dump_path = self.get_or_create_ref_dump(new_module, True)
self.assertEqual( self.assertEqual(_read_output_content(old_ref_dump_path),
read_output_content(old_ref_dump_path, AOSP_DIR), _read_output_content(new_ref_dump_path))
read_output_content(new_ref_dump_path, AOSP_DIR))
def test_example1_cpp(self): def test_example1_cpp(self):
self.run_and_compare_name_cpp('example1.cpp') self.run_and_compare_name_cpp('example1.cpp')

View File

@@ -2,6 +2,7 @@
import gzip import gzip
import os import os
import shutil
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
@@ -24,11 +25,6 @@ BUILTIN_HEADERS_DIR = (
'clang-headers'), 'clang-headers'),
) )
EXPORTED_HEADERS_DIR = (
os.path.join(AOSP_DIR, 'development', 'vndk', 'tools', 'header-checker',
'tests'),
)
SO_EXT = '.so' SO_EXT = '.so'
SOURCE_ABI_DUMP_EXT_END = '.lsdump' SOURCE_ABI_DUMP_EXT_END = '.lsdump'
SOURCE_ABI_DUMP_EXT = SO_EXT + SOURCE_ABI_DUMP_EXT_END SOURCE_ABI_DUMP_EXT = SO_EXT + SOURCE_ABI_DUMP_EXT_END
@@ -80,43 +76,33 @@ class Target(object):
return self.get_arch_str() + cpu_variant return self.get_arch_str() + cpu_variant
def _validate_dump_content(dump_path):
"""Make sure that the dump contains relative source paths."""
with open(dump_path, 'r') as f:
if AOSP_DIR in f.read():
raise ValueError(
dump_path + ' contains absolute path to $ANDROID_BUILD_TOP.')
def copy_reference_dump(lib_path, reference_dump_dir, compress): def copy_reference_dump(lib_path, reference_dump_dir, compress):
reference_dump_path = os.path.join( reference_dump_path = os.path.join(
reference_dump_dir, os.path.basename(lib_path)) reference_dump_dir, os.path.basename(lib_path))
if compress: if compress:
reference_dump_path += '.gz' reference_dump_path += '.gz'
os.makedirs(os.path.dirname(reference_dump_path), exist_ok=True) os.makedirs(os.path.dirname(reference_dump_path), exist_ok=True)
output_content = read_output_content(lib_path, AOSP_DIR) _validate_dump_content(lib_path)
if compress: if compress:
with gzip.open(reference_dump_path, 'wb') as f: with open(lib_path, 'rb') as src_file:
f.write(bytes(output_content, 'utf-8')) with gzip.open(reference_dump_path, 'wb') as dst_file:
shutil.copyfileobj(src_file, dst_file)
else: else:
with open(reference_dump_path, 'wb') as f: shutil.copyfile(lib_path, reference_dump_path)
f.write(bytes(output_content, 'utf-8'))
print('Created abi dump at', reference_dump_path) print('Created abi dump at', reference_dump_path)
return reference_dump_path return reference_dump_path
def read_output_content(output_path, replace_str): def run_header_abi_dumper(input_path, output_path, cflags=tuple(),
with open(output_path, 'r') as f: export_include_dirs=tuple(), flags=tuple()):
return f.read().replace(replace_str, '')
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)
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 """Run header-abi-dumper to dump ABI from `input_path` and the output is
written to `output_path`.""" written to `output_path`."""
input_ext = os.path.splitext(input_path)[1] input_ext = os.path.splitext(input_path)[1]
@@ -141,10 +127,11 @@ def _run_header_abi_dumper_on_file(input_path, output_path,
for dir in export_include_dirs: for dir in export_include_dirs:
cmd += ['-I', dir] cmd += ['-I', dir]
subprocess.check_call(cmd, cwd=AOSP_DIR) subprocess.check_call(cmd, cwd=AOSP_DIR)
_validate_dump_content(output_path)
def run_header_abi_linker(output_path, inputs, version_script, api, arch, def run_header_abi_linker(inputs, output_path, version_script, api, arch,
flags=tuple(), input_dir=AOSP_DIR): flags=tuple()):
"""Link inputs, taking version_script into account""" """Link inputs, taking version_script into account"""
cmd = ['header-abi-linker', '-o', output_path, '-v', version_script, cmd = ['header-abi-linker', '-o', output_path, '-v', version_script,
'-api', api, '-arch', arch] '-api', api, '-arch', arch]
@@ -155,7 +142,7 @@ def run_header_abi_linker(output_path, inputs, version_script, api, arch,
cmd += ['-output-format', DEFAULT_FORMAT] cmd += ['-output-format', DEFAULT_FORMAT]
cmd += inputs cmd += inputs
subprocess.check_call(cmd, cwd=AOSP_DIR) subprocess.check_call(cmd, cwd=AOSP_DIR)
return read_output_content(output_path, input_dir) _validate_dump_content(output_path)
def make_targets(product, variant, targets): def make_targets(product, variant, targets):