97 lines · plain
1#!/usr/bin/env python32 3import argparse4import os5import pathlib6import subprocess7import sys8import tempfile9 10PARENT_DIR = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))11 12LIT_CONFIG_FILE = """13#14# This testing configuration handles running the test suite against a version15# of libc++ installed at the given path.16#17 18lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg')19 20config.substitutions.append(('%{{flags}}',21 '-pthread' + (' -isysroot {{}}'.format('@CMAKE_OSX_SYSROOT@') if '@CMAKE_OSX_SYSROOT@' else '')22))23config.substitutions.append(('%{{compile_flags}}', '-nostdinc++ -I {INSTALL_ROOT}/include/c++/v1 -I %{{libcxx-dir}}/test/support'))24config.substitutions.append(('%{{link_flags}}', '-nostdlib++ -L {INSTALL_ROOT}/lib -Wl,-rpath,{INSTALL_ROOT}/lib -lc++'))25config.substitutions.append(('%{{exec}}', '%{{executor}} --execdir %{{temp}} -- '))26 27import os, site28site.addsitedir(os.path.join('@LIBCXX_SOURCE_DIR@', 'utils'))29import libcxx.test.params, libcxx.test.config30libcxx.test.config.configure(31 libcxx.test.params.DEFAULT_PARAMETERS,32 libcxx.test.features.DEFAULT_FEATURES,33 config,34 lit_config35)36"""37 38def directory_path(string):39 if os.path.isdir(string):40 return pathlib.Path(string)41 else:42 raise NotADirectoryError(string)43 44def main(argv):45 parser = argparse.ArgumentParser(46 prog='test-at-commit',47 description='Build libc++ at the specified commit and test it against the version of the test suite '48 'currently checked out in the specified Git repository. '49 'This makes it easier to perform historical analyses of libc++ behavior, gather historical '50 'performance data, bisect issues, and so on. '51 'A current limitation of this script is that it assumes the arguments passed to CMake when '52 'building the library.')53 parser.add_argument('--build', '-B', type=pathlib.Path, required=True,54 help='Path to create the build directory for running the test suite at.')55 parser.add_argument('--commit', type=str, required=True,56 help='Commit to build libc++ at.')57 parser.add_argument('lit_options', nargs=argparse.REMAINDER,58 help='Optional arguments passed to lit when running the tests. Should be provided last and '59 'separated from other arguments with a `--`.')60 parser.add_argument('--git-repo', type=directory_path, default=pathlib.Path(os.getcwd()),61 help='Optional path to the Git repository to use. By default, the current working directory is used.')62 args = parser.parse_args(argv)63 64 # Gather lit options65 lit_options = []66 if args.lit_options is not None:67 if args.lit_options[0] != '--':68 raise ArgumentError('For clarity, Lit options must be separated from other options by --')69 lit_options = args.lit_options[1:]70 71 with tempfile.TemporaryDirectory() as install_dir:72 # Build the library at the baseline73 build_cmd = [PARENT_DIR / 'build-at-commit', '--git-repo', args.git_repo,74 '--install-dir', install_dir,75 '--commit', args.commit]76 build_cmd += ['--', '-DCMAKE_BUILD_TYPE=RelWithDebInfo']77 subprocess.check_call(build_cmd)78 79 # Configure the test suite in the specified build directory80 args.build.mkdir(parents=True, exist_ok=True)81 lit_cfg = (args.build / 'temp_lit_cfg.cfg.in').absolute()82 with open(lit_cfg, 'w') as f:83 f.write(LIT_CONFIG_FILE.format(INSTALL_ROOT=install_dir))84 85 test_suite_cmd = ['cmake', '-B', args.build, '-S', args.git_repo / 'runtimes', '-G', 'Ninja']86 test_suite_cmd += ['-D', 'LLVM_ENABLE_RUNTIMES=libcxx;libcxxabi']87 test_suite_cmd += ['-D', 'LIBCXXABI_USE_LLVM_UNWINDER=OFF']88 test_suite_cmd += ['-D', f'LIBCXX_TEST_CONFIG={lit_cfg}']89 subprocess.check_call(test_suite_cmd)90 91 # Run the specified tests against the produced baseline installation92 lit_cmd = [PARENT_DIR / 'libcxx-lit', args.build] + lit_options93 subprocess.check_call(lit_cmd)94 95if __name__ == '__main__':96 main(sys.argv[1:])97