| #!/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()) |