| #!/usr/bin/env python |
| # Copyright 2020 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Minimize Fuchsia GCC toolchains. |
| Usage: |
| python preprocess_gcc.py --src=SRC_PATH --dst=DST_PATH --platforms=linux_amd64 --platforms=mac_amd64 |
| """ |
| |
| import argparse |
| import os |
| import sys |
| import shutil |
| |
| GCC_TARGETS = ('aarch64-elf', 'x86_64-elf') |
| |
| |
| def preprocess_gcc(src_dir, dst_dir): |
| versions = set() |
| for target in GCC_TARGETS: |
| versions |= set(os.listdir(os.path.join(src_dir, 'lib', 'gcc', target))) |
| [gcc_version] = versions |
| |
| prefixes = set() |
| |
| def prefix_match(file): |
| return any( |
| os.path.commonprefix([file, prefix]) == prefix for prefix in prefixes) |
| |
| files = set([os.path.join('share', 'man', 'man7', 'gpl.7')]) |
| for target in GCC_TARGETS: |
| files |= set([ |
| os.path.join('bin', target + '-gcc'), |
| os.path.join('bin', target + '-g++'), |
| os.path.join(target, 'bin', 'as'), |
| os.path.join('libexec', 'gcc', target, gcc_version, 'cc1'), |
| os.path.join('libexec', 'gcc', target, gcc_version, 'cc1plus'), |
| ]) |
| prefixes |= set( |
| os.path.join('lib', 'gcc', target, gcc_version, dir) + os.sep |
| for dir in ('include', 'include-fixed')) |
| |
| def dirs_of(filelist): |
| return set(os.path.dirname(file) for file in filelist) |
| |
| dirs = dirs_of(files | prefixes) |
| while True: |
| more_dirs = dirs_of(dirs) |
| if more_dirs <= dirs: |
| break |
| dirs |= more_dirs |
| |
| def ignore_unnecessary(dir, contents): |
| dir = os.path.relpath(dir, src_dir) |
| |
| def want(name): |
| file = os.path.normpath(os.path.join(dir, name)) |
| return file in files or file in dirs or prefix_match(file) |
| |
| return [name for name in contents if not want(name)] |
| |
| shutil.copytree(src_dir, dst_dir, symlinks=True, ignore=ignore_unnecessary) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument('src', help='source toolchain path') |
| parser.add_argument('dst', help='target toolchain path') |
| parser.add_argument( |
| '--platform', action='append', help='target platform name') |
| args = parser.parse_args() |
| for platform in args.platform: |
| preprocess_gcc( |
| os.path.join(args.src, platform), os.path.join(args.dst, platform)) |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |