fix: install linux sysroot in configure, not via gclient hook (#653)

* fix: install linux sysroot in configure, not via gclient hook

`gn gen` was failing on the arm64 leg with `Missing sysroot
(//build/linux/debian_bullseye_arm64-sysroot)`. The previous design
relied on `git_setup` writing `target_cpus` to `.gclient` so that
`gclient sync`'s DEPS hook would download the cross-arch sysroot. That
chain breaks for any chromium_src that was synced before cross-arch
support landed (the hook is gated on .gclient state at sync time) and
for partial pipeline runs that skip git_setup entirely. Nothing in
configure declared or verified its sysroot precondition.

Make configure self-healing: on Linux, invoke
`build/linux/sysroot_scripts/install-sysroot.py --arch=<target>`
directly before `gn gen`. install-sysroot.py is idempotent (stamp file
+ SHA check), fast when already installed, and decoupled from .gclient
— it's exactly what the failing assertion's error message recommends.
The script accepts our arch names directly: `x64` translates to `amd64`
internally via ARCH_TRANSLATIONS, and `arm64` is a valid pass-through.

Also temporarily pin release.linux.yaml to x64 only while we validate
the sysroot bootstrap end-to-end. Flip back to `[x64, arm64]` once
arm64 is green.

* chore: pin release.linux.yaml to arm64-only for sysroot bootstrap test

x64 already builds cleanly — the failing leg is arm64 cross-compile from
an x64 host. Pin the config to arm64 to exercise the new
install-sysroot.py path in configure without burning time on x64.
Flip back to [x64, arm64] once arm64 is green.
This commit is contained in:
Nikhil
2026-04-07 11:12:21 -07:00
committed by GitHub
parent dee3086a48
commit bb62213e84
2 changed files with 48 additions and 5 deletions

View File

@@ -1,8 +1,8 @@
# BrowserOS Linux Release Build Configuration
#
# Builds both x64 and arm64 in a single invocation on a Linux x64 host.
# The runner loops the entire pipeline once per architecture; depot_tools
# fetches the matching sysroots automatically (see git_setup module).
# Pinned to arm64-only to validate the cross-compile sysroot bootstrap
# end-to-end on a Linux x64 host. Flip back to `[x64, arm64]` once arm64
# is green.
#
# Run:
# browseros build --config build/config/release.linux.yaml
@@ -13,7 +13,7 @@
build:
type: release
architecture: [x64, arm64] # Builds both arches sequentially in one run
architecture: arm64
gn_flags:
file: build/config/gn/flags.linux.release.gn

View File

@@ -1,9 +1,19 @@
#!/usr/bin/env python3
"""Build configuration module for BrowserOS build system"""
import sys
from ...common.module import CommandModule, ValidationError
from ...common.context import Context
from ...common.utils import run_command, log_info, log_success, join_paths, IS_WINDOWS
from ...common.utils import (
run_command,
log_info,
log_warning,
log_success,
join_paths,
IS_LINUX,
IS_WINDOWS,
)
class ConfigureModule(CommandModule):
@@ -25,6 +35,16 @@ class ConfigureModule(CommandModule):
def execute(self, ctx: Context) -> None:
log_info(f"\n⚙️ Configuring {ctx.build_type} build for {ctx.architecture}...")
# Linux: ensure the target-arch Debian sysroot is installed before
# `gn gen`. sysroot.gni asserts on missing sysroots, and relying on
# `gclient sync` DEPS hooks is fragile — the hook only fires when
# .gclient declared the right `target_cpus` *before* sync, which
# isn't guaranteed for chromium_src checkouts that predate
# cross-arch support. install-sysroot.py is idempotent and fast,
# so call it unconditionally for the target arch.
if IS_LINUX():
self._ensure_linux_sysroot(ctx)
out_path = join_paths(ctx.chromium_src, ctx.out_dir)
out_path.mkdir(parents=True, exist_ok=True)
@@ -43,3 +63,26 @@ class ConfigureModule(CommandModule):
run_command(gn_args, cwd=ctx.chromium_src)
log_success("Build configured")
def _ensure_linux_sysroot(self, ctx: Context) -> None:
install_script = (
ctx.chromium_src / "build" / "linux" / "sysroot_scripts" / "install-sysroot.py"
)
if not install_script.exists():
log_warning(
f"⚠️ install-sysroot.py not found at {install_script}; "
f"skipping sysroot bootstrap. gn gen will fail if the "
f"{ctx.architecture} sysroot is missing."
)
return
# install-sysroot.py accepts our arch names directly: it translates
# `x64`→`amd64` internally via ARCH_TRANSLATIONS, and `arm64` is a
# valid pass-through value.
log_info(
f"📦 Ensuring Linux sysroot for {ctx.architecture} (idempotent)..."
)
run_command(
[sys.executable, str(install_script), f"--arch={ctx.architecture}"],
cwd=ctx.chromium_src,
)