Merge "Remove string substitution from ABI dump scripts" am: d5a53111c1 am: 1c8d200661 am: 3b9c7009c7
Original change: https://android-review.googlesource.com/c/platform/development/+/1358242 Change-Id: I95cb4e99c17c015c498a25051bb4c4c0e4bc5695
This commit is contained in:
@@ -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))
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user