| #!/usr/bin/env python3 |
| """Builds Fuchsia VIM3 firmware and creates CIPD package files. |
| |
| In case CIPD is not available it is expected that all necessary tools would be |
| in PATH. |
| |
| Clang and GCC from CIPD are used for repeatable build. |
| """ |
| |
| import argparse |
| import logging |
| import os |
| import shutil |
| import subprocess |
| import sys |
| import textwrap |
| from pathlib import Path |
| from typing import Optional |
| |
| _MY_DIR = Path(__file__).parent.resolve() |
| |
| _BUILD_SCRIPT_TARGET = [_MY_DIR / "mk", "kvim3_zircon"] |
| |
| _CIPD_DEPS_DIR = _MY_DIR / "cipd_deps" |
| |
| |
| def build(): |
| """Builds the CIPD package.""" |
| |
| # Pass compilers for u-boot host tools build |
| host_clang = _CIPD_DEPS_DIR / "clang" |
| build_env = dict( |
| os.environ, |
| # Build bootloader binaries and generate combined images (as part of the signing process). |
| CONFIG_AML_SIGNED_UBOOT="y", |
| # Clang target for host tools |
| TARGET="x86_64-unknown-linux-gnu", |
| HOST_CLANG=host_clang, |
| HOSTCC=host_clang / "bin" / "clang", |
| HOSTCXX=host_clang / "bin" / "clang++", |
| HOSTLD=host_clang / "bin" / "lld", |
| CROSS_COMPILE="aarch64-elf-", |
| ) |
| |
| subprocess.run( |
| _BUILD_SCRIPT_TARGET, |
| env=build_env, |
| check=True, |
| ) |
| |
| |
| def _parse_args() -> argparse.Namespace: |
| parser = argparse.ArgumentParser( |
| description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter |
| ) |
| |
| parser.add_argument( |
| "--cipd", default="cipd", help="Path to CIPD tool; looks on $PATH by default" |
| ) |
| parser.add_argument( |
| "--clean-cipd", |
| action="store_true", |
| help="Clear CIPD dependencies dir before start", |
| ) |
| |
| return parser.parse_args() |
| |
| |
| # list_of_packages are in format: |
| # [(dir name in cipd_deps, CIPD package path, package version, dir to add to PATH),...] |
| def ensure_deps(cipd_tool: str, list_of_packages): |
| """Ensures that build deps have been downloaded. |
| We should rely on as few host dependencies as possible, instead fetching |
| what we need from CIPD to ensure a hermetic and reproducible build env. |
| """ |
| |
| try: |
| for (name, cipd_package, cipd_version, path_dir) in list_of_packages: |
| dep_dir = _CIPD_DEPS_DIR / name |
| subprocess.run( |
| [cipd_tool, "ensure", "-root", dep_dir, "-ensure-file", "-"], |
| check=True, |
| text=True, |
| input=f"{cipd_package} {cipd_version}", |
| ) |
| _add_path_prefix(dep_dir / path_dir) |
| except FileNotFoundError as err: |
| print(f"WARNING: CIPD tool was likely not found: {err}.") |
| print("WARNING: Relying on system tools for the build.") |
| |
| |
| def _add_path_prefix(path): |
| """Adds |path| to the beginning of $PATH.""" |
| os.environ["PATH"] = str(path) + os.pathsep + os.environ["PATH"] |
| |
| |
| def cipd_dep_dir_clean(): |
| logging.info(f"Removing CIPD deps dir: {_CIPD_DEPS_DIR}") |
| shutil.rmtree(_CIPD_DEPS_DIR, ignore_errors=True) |
| |
| |
| def fuchsia_build(cipd, clean_cipd): |
| if clean_cipd: |
| cipd_dep_dir_clean() |
| |
| # Versions are pinned to current integration version in most cases. |
| # It is done to prevent unexpected breaking when integration moves forward. |
| # It is required to do manual testing before bumping the versions. |
| list_of_packages = [ |
| ("make", "fuchsia/third_party/make/linux-amd64", "version:4.3", "bin"), |
| # gcc version is 15.2.1,2.46.50 |
| ( |
| "gcc", |
| "fuchsia/third_party/gcc/linux-amd64", |
| "git_revision:26e4f8ad7220f692cd8010f9cf7620d690f1b094,1daba1c5ceb27d25265ba2801f5be307d21a6abd", |
| "bin", |
| ), |
| ( |
| "gcc-arm-none-eabi", |
| "pigweed/third_party/gcc-arm-none-eabi/linux-amd64", |
| "version:10-2020-q4-major", |
| "bin", |
| ), |
| # For host u-boot tools |
| ( |
| "clang", |
| "fuchsia/third_party/clang/linux-amd64", |
| "git_revision:80743bd43fd5b38fedc503308e7a652e23d3ec93", |
| "bin", |
| ), |
| # Host zip tool for signing |
| ( |
| "zip", |
| "skia/bots/zip_linux-amd64", |
| "version:0", |
| "", |
| ), |
| # Host xxd tool for signing |
| ( |
| "xxd", |
| "fuchsia/third_party/xxd/linux-amd64", |
| "version:2@9.1.1061", |
| "", |
| ), |
| ] |
| ensure_deps(cipd, list_of_packages) |
| |
| build() |
| |
| |
| def _main() -> int: |
| logging.basicConfig(level=logging.INFO) |
| args = _parse_args() |
| |
| fuchsia_build( |
| cipd=args.cipd, |
| clean_cipd=args.clean_cipd, |
| ) |
| |
| |
| if __name__ == "__main__": |
| sys.exit(_main()) |