From b0e10f52e71fca919eab8b3e3ca0fa4202d2f254 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Fri, 14 Aug 2026 14:34:42 +0000 Subject: [PATCH] Build Linux x64 against an isolated sysroot. --- .../install-linux-build-dependencies.sh | 27 +++++++++-------- .gitea/workflows/release.yml | 5 ++-- crates/bds-ui/tests/packaging_assets.rs | 30 +++++++++++-------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/.gitea/scripts/install-linux-build-dependencies.sh b/.gitea/scripts/install-linux-build-dependencies.sh index 98e4b42..0a45570 100644 --- a/.gitea/scripts/install-linux-build-dependencies.sh +++ b/.gitea/scripts/install-linux-build-dependencies.sh @@ -43,11 +43,7 @@ case "$target" in "$native_sources" sudo apt-get update - # The full runner image includes these Architecture: all Python tools. - # They are unrelated to the build, but make apt replace native Python - # while resolving foreign-architecture development packages. - sudo env DEBIAN_FRONTEND=noninteractive apt-get remove -y mercurial python3-importlib-metadata python3-jwt - install_packages python3 python3-typing-extensions + install_packages build-essential cmake gcc-x86-64-linux-gnu g++-x86-64-linux-gnu pkg-config sudo dpkg --add-architecture amd64 { @@ -67,15 +63,22 @@ case "$target" in 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' } | sudo tee /etc/apt/sources.list.d/ruds-amd64.sources >/dev/null sudo apt-get update - install_packages \ - build-essential \ - cmake \ - gcc-x86-64-linux-gnu \ - g++-x86-64-linux-gnu \ + + # Foreign development packages contain architecture-specific helper + # programs whose maintainer scripts cannot run on the arm64 host. + # Download them without installing and extract a link-only sysroot. + sysroot=/opt/ruds-x64-sysroot + archives=/tmp/ruds-x64-archives + sudo mkdir -p "$archives/partial" "$sysroot" + sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + --download-only \ + -o Dir::Cache::archives="$archives" \ libgtk-3-dev:amd64 \ libwebkit2gtk-4.1-dev:amd64 \ - libxdo-dev:amd64 \ - pkg-config + libxdo-dev:amd64 + for package in "$archives"/*.deb; do + sudo dpkg-deb --extract "$package" "$sysroot" + done ;; *) echo "unsupported Linux build target: $target" >&2 diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 22c2d0f..591c53c 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -139,9 +139,10 @@ jobs: CC_x86_64_unknown_linux_gnu: x86_64-linux-gnu-gcc CXX_x86_64_unknown_linux_gnu: x86_64-linux-gnu-g++ CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: x86_64-linux-gnu-gcc - CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-arg=-Wl,-rpath,$ORIGIN -L native=/usr/lib/x86_64-linux-gnu + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: -C link-arg=-Wl,-rpath,$ORIGIN -L native=/opt/ruds-x64-sysroot/usr/lib/x86_64-linux-gnu -L native=/opt/ruds-x64-sysroot/lib/x86_64-linux-gnu PKG_CONFIG_ALLOW_CROSS: "1" - PKG_CONFIG_LIBDIR: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig + PKG_CONFIG_LIBDIR: /opt/ruds-x64-sysroot/usr/lib/x86_64-linux-gnu/pkgconfig:/opt/ruds-x64-sysroot/usr/lib/pkgconfig:/opt/ruds-x64-sysroot/usr/share/pkgconfig + PKG_CONFIG_SYSROOT_DIR: /opt/ruds-x64-sysroot steps: - name: Check out the tag uses: actions/checkout@v4 diff --git a/crates/bds-ui/tests/packaging_assets.rs b/crates/bds-ui/tests/packaging_assets.rs index ad26c4f..cc0d787 100644 --- a/crates/bds-ui/tests/packaging_assets.rs +++ b/crates/bds-ui/tests/packaging_assets.rs @@ -193,38 +193,42 @@ fn tagged_releases_are_built_and_packaged_with_rust_tools() { "libwebkit2gtk-4.1-dev:amd64", "gcc-x86-64-linux-gnu", "Architectures: arm64", - "remove -y mercurial python3-importlib-metadata python3-jwt", - "install_packages python3 python3-typing-extensions", + "--download-only", + "dpkg-deb --extract", + "/opt/ruds-x64-sysroot", ] { assert!( linux_dependencies.contains(required), "Linux dependency setup is missing {required}" ); } - let cleanup = linux_dependencies - .find("remove -y mercurial python3-importlib-metadata python3-jwt") - .expect("runner Python cleanup"); let multiarch = linux_dependencies .find("dpkg --add-architecture amd64") .expect("amd64 architecture setup"); assert!( - cleanup < multiarch, - "runner-only Python packages must be removed before enabling multiarch" + !linux_dependencies.contains("apt-get remove"), + "cross-build setup must not replace native runner packages" ); - let native_python = linux_dependencies - .find("install_packages python3 python3-typing-extensions") - .expect("native Python dependency setup"); let native_source_filter = linux_dependencies .find("'/^Architectures:/d; /^Types: deb$/a Architectures: arm64'") .expect("native apt architecture filter"); + let native_cross_compiler = linux_dependencies + .find("install_packages build-essential cmake gcc-x86-64-linux-gnu") + .expect("native cross compiler setup"); assert!( - linux_dependencies[native_source_filter..native_python].contains("sudo apt-get update"), + linux_dependencies[native_source_filter..native_cross_compiler] + .contains("sudo apt-get update"), "native apt indexes must be refreshed after constraining the source architecture" ); assert!( - native_python < multiarch, - "native Python dependencies must be fixed before enabling multiarch" + native_cross_compiler < multiarch, + "the native cross compiler must be installed before enabling multiarch" ); + assert!( + linux_dependencies.find("--download-only").unwrap() > multiarch, + "foreign libraries must only be downloaded after enabling multiarch" + ); + assert!(workflow.contains("PKG_CONFIG_SYSROOT_DIR: /opt/ruds-x64-sysroot")); let workspace_manifest = fs::read_to_string(workspace.join("Cargo.toml")).unwrap(); let core_manifest = fs::read_to_string(workspace.join("crates/bds-core/Cargo.toml")).unwrap();