blob: ae9ec3ce6e71ab087d3fa032a3d10ddda4bcedab [file] [edit]
#!/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())