From 7e53559f8c3efcdc4ffbb623bc42e249c7a52e1b Mon Sep 17 00:00:00 2001 From: Simon Scatton Date: Wed, 9 Sep 2026 17:15:39 +0200 Subject: [PATCH 1/4] chore(nix): unify Linux cross-compilation toolchains Signed-off-by: Simon Scatton --- flake.nix | 64 +++++----- nix/devShells/glibc-2-28.nix | 40 ------ nix/devShells/musl.nix | 27 ---- nix/pkgs/aws-lc-static.nix | 14 --- nix/pkgs/aws-lc.nix | 40 ++++++ nix/pkgs/{z3-static.nix => z3.nix} | 12 +- nix/strings.nix | 12 ++ nix/toolchain/default.nix | 42 +++++++ nix/toolchain/driver.nix | 34 +++++ nix/toolchain/gnu.nix | 116 ++++++++++++++++++ .../linux-gnu-2.28 => toolchain}/libc.nix | 18 +++ nix/toolchain/sysroot.nix | 41 +++++++ nix/toolchains/linux-gnu-2.28/default.nix | 106 ---------------- 13 files changed, 349 insertions(+), 217 deletions(-) delete mode 100644 nix/devShells/glibc-2-28.nix delete mode 100644 nix/devShells/musl.nix delete mode 100644 nix/pkgs/aws-lc-static.nix create mode 100644 nix/pkgs/aws-lc.nix rename nix/pkgs/{z3-static.nix => z3.nix} (57%) create mode 100644 nix/strings.nix create mode 100644 nix/toolchain/default.nix create mode 100644 nix/toolchain/driver.nix create mode 100644 nix/toolchain/gnu.nix rename nix/{toolchains/linux-gnu-2.28 => toolchain}/libc.nix (68%) create mode 100644 nix/toolchain/sysroot.nix delete mode 100644 nix/toolchains/linux-gnu-2.28/default.nix diff --git a/flake.nix b/flake.nix index b6cb70e387..6498ac9afb 100644 --- a/flake.nix +++ b/flake.nix @@ -69,9 +69,38 @@ projectRootFile = "flake.nix"; programs.nixfmt.enable = true; }; - rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; - z3-static = pkgs.callPackage ./nix/pkgs/z3-static.nix { }; - aws-lc-static = pkgs.callPackage ./nix/pkgs/aws-lc-static.nix { }; + rustToolchain = + ((pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml).override { + targets = map (toolchain: toolchain.target) (builtins.attrValues toolchains) ++ [ + "aarch64-apple-darwin" + ]; + }).overrideAttrs + { + propagatedBuildInputs = [ ]; + depsHostHostPropagated = [ ]; + }; + buildInputs = { pkgs, stdenv }: [ + (pkgs.callPackage ./nix/pkgs/z3.nix { inherit stdenv; }) + (pkgs.callPackage ./nix/pkgs/aws-lc.nix { inherit stdenv; }) + ]; + toolchains = { + x86_64-gnu = pkgs.callPackage ./nix/toolchain { + pkgs = pkgs.pkgsCross.gnu64; + inherit buildInputs; + }; + x86_64-musl = pkgs.callPackage ./nix/toolchain { + pkgs = pkgs.pkgsCross.musl64; + inherit buildInputs; + }; + aarch64-gnu = pkgs.callPackage ./nix/toolchain { + pkgs = pkgs.pkgsCross.aarch64-multiplatform; + inherit buildInputs; + }; + aarch64-musl = pkgs.callPackage ./nix/toolchain { + pkgs = pkgs.pkgsCross.aarch64-multiplatform-musl; + inherit buildInputs; + }; + }; vmRuntime = pkgs.callPackage ./nix/pkgs/vm-runtime.nix { }; testGuest = import ./nix/test-guest { inherit pkgs; @@ -85,31 +114,10 @@ packages.vm-runtime = vmRuntime; - devShells = { - default = - (pkgs.mkShell.override { - stdenv = - if pkgs.stdenv.hostPlatform.isLinux then - pkgs.stdenvAdapters.useMoldLinker pkgs.stdenv - else - pkgs.stdenv; - }) - { - packages = [ - rustToolchain - z3-static - aws-lc-static - ] - ++ commonDevShellPackages; - }; - } - // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { - glibc-2-28 = import ./nix/devShells/glibc-2-28.nix { - inherit pkgs rust-overlay commonDevShellPackages; - }; - musl = import ./nix/devShells/musl.nix { - inherit pkgs rust-overlay commonDevShellPackages; - }; + devShells.default = pkgs.mkShellNoCC { + packages = [ rustToolchain ] ++ commonDevShellPackages; + + env = pkgs.lib.foldl' (env: toolchain: env // toolchain.env) { } (builtins.attrValues toolchains); }; formatter = treefmtEval.config.build.wrapper; diff --git a/nix/devShells/glibc-2-28.nix b/nix/devShells/glibc-2-28.nix deleted file mode 100644 index 1bba2ef637..0000000000 --- a/nix/devShells/glibc-2-28.nix +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -{ - pkgs, - rust-overlay, - commonDevShellPackages, -}: - -let - toolchain = import ../toolchains/linux-gnu-2.28 { inherit pkgs; }; - z3-static = pkgs.callPackage ../pkgs/z3-static.nix { - stdenv = toolchain.stdenv; - }; - aws-lc-static = pkgs.callPackage ../pkgs/aws-lc-static.nix { - stdenv = toolchain.stdenv; - }; - rustScope = { - stdenv = toolchain.stdenv; - gccForLibs.lib = toolchain.sharedRuntime; - pkgsTargetTarget = pkgs.pkgsTargetTarget // { - stdenv = toolchain.stdenv; - }; - }; - rust-bin = rust-overlay.lib.mkRustBin { } ( - pkgs - // rustScope - // { - callPackage = pkgs.newScope rustScope; - } - ); -in -(pkgs.mkShell.override { stdenv = toolchain.stdenv; }) { - packages = [ - (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml) - z3-static - aws-lc-static - ] - ++ commonDevShellPackages; -} diff --git a/nix/devShells/musl.nix b/nix/devShells/musl.nix deleted file mode 100644 index d0dbda93c1..0000000000 --- a/nix/devShells/musl.nix +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -{ - pkgs, - rust-overlay, - commonDevShellPackages, -}: - -let - muslPkgs = pkgs.pkgsMusl; - stdenv = muslPkgs.stdenv; - rust-bin = rust-overlay.lib.mkRustBin { } muslPkgs; - rustToolchain = (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml).override { - enableLibsecret = false; - }; -in -(muslPkgs.mkShell.override { inherit stdenv; }) { - packages = [ - rustToolchain - (muslPkgs.callPackage ../pkgs/z3-static.nix { }) - (muslPkgs.callPackage ../pkgs/aws-lc-static.nix { - rust-bindgen = pkgs.rust-bindgen; - }) - ] - ++ commonDevShellPackages; -} diff --git a/nix/pkgs/aws-lc-static.nix b/nix/pkgs/aws-lc-static.nix deleted file mode 100644 index 45fd5ad174..0000000000 --- a/nix/pkgs/aws-lc-static.nix +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -{ - aws-lc, - rust-bindgen, - stdenv, -}: - -aws-lc.override { - inherit stdenv rust-bindgen; - useSharedLibraries = false; - withRustBindings = true; -} diff --git a/nix/pkgs/aws-lc.nix b/nix/pkgs/aws-lc.nix new file mode 100644 index 0000000000..cd82735c51 --- /dev/null +++ b/nix/pkgs/aws-lc.nix @@ -0,0 +1,40 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + lib, + stdenv, + aws-lc, + buildEnv, + callPackage, +}: + +let + strings = callPackage ../strings.nix { }; + target = stdenv.hostPlatform.config; + package = + (aws-lc.override { + inherit stdenv; + useSharedLibraries = false; + withRustBindings = true; + }).overrideAttrs + (old: { + BINDGEN_EXTRA_CLANG_ARGS = "--target=${target}"; + passthru = old.passthru // { + env.${strings.targetEnvVar target "AWS_LC_SYS_SYSTEM_DIR"} = "${libraries}"; + }; + }); + libraries = buildEnv { + name = "${target}-aws-lc-libraries"; + paths = [ + (lib.getLib package) + (lib.getDev package) + ]; + pathsToLink = [ + "/include" + "/lib" + "/share/rust" + ]; + }; +in +package diff --git a/nix/pkgs/z3-static.nix b/nix/pkgs/z3.nix similarity index 57% rename from nix/pkgs/z3-static.nix rename to nix/pkgs/z3.nix index f58c36920c..36f4c82245 100644 --- a/nix/pkgs/z3-static.nix +++ b/nix/pkgs/z3.nix @@ -1,12 +1,20 @@ # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -{ z3, stdenv }: +{ + lib, + stdenv, + z3, +}: (z3.override { inherit stdenv; pythonBindings = false; }).overrideAttrs (old: { - cmakeFlags = old.cmakeFlags ++ [ "-DZ3_BUILD_LIBZ3_SHARED=OFF" ]; + cmakeFlags = old.cmakeFlags ++ [ + (lib.cmakeBool "Z3_BUILD_LIBZ3_SHARED" false) + ]; + doCheck = false; + doInstallCheck = false; }) diff --git a/nix/strings.nix b/nix/strings.nix new file mode 100644 index 0000000000..1b9df3ef4f --- /dev/null +++ b/nix/strings.nix @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ lib }: + +let + targetSuffix = builtins.replaceStrings [ "-" ] [ "_" ]; +in +{ + targetEnvVar = target: name: "${name}_${targetSuffix target}"; + cargoTargetEnvVar = target: name: "CARGO_TARGET_${lib.toUpper (targetSuffix target)}_${name}"; +} diff --git a/nix/toolchain/default.nix b/nix/toolchain/default.nix new file mode 100644 index 0000000000..93ec873890 --- /dev/null +++ b/nix/toolchain/default.nix @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + buildInputs, +}: + +let + strings = pkgs.callPackage ../strings.nix { }; + target = pkgs.stdenv.hostPlatform.config; + isMusl = pkgs.stdenv.hostPlatform.isMusl; + gnu = pkgs.callPackage ./gnu.nix { }; + stdenv = if isMusl then pkgs.stdenv else gnu.stdenv; + packages = buildInputs { inherit pkgs stdenv; }; + sysroot = + if isMusl then + null + else + pkgs.callPackage ./sysroot.nix { + buildInputs = packages; + inherit (gnu) glibc runtime; + }; + cc = if isMusl then stdenv.cc else gnu.gcc; + toolchain = pkgs.callPackage ./driver.nix { + inherit sysroot; + compiler = "${cc}/bin/${stdenv.cc.targetPrefix}gcc"; + buildInputs = if isMusl then packages else [ ]; + }; +in +toolchain.overrideAttrs (old: { + passthru = (old.passthru or { }) // { + inherit target stdenv sysroot; + buildInputs = packages; + env = pkgs.lib.foldl' (env: package: env // (package.passthru.env or { })) { } packages // { + ${strings.cargoTargetEnvVar target "LINKER"} = "${toolchain}/bin/${target}-cc"; + ${strings.targetEnvVar target "CC"} = "${toolchain}/bin/${target}-cc"; + ${strings.targetEnvVar target "AS"} = "${stdenv.cc.bintools}/bin/${stdenv.cc.targetPrefix}as"; + ${strings.targetEnvVar target "AR"} = "${stdenv.cc.bintools}/bin/${stdenv.cc.targetPrefix}ar"; + }; + }; +}) diff --git a/nix/toolchain/driver.nix b/nix/toolchain/driver.nix new file mode 100644 index 0000000000..244a31f413 --- /dev/null +++ b/nix/toolchain/driver.nix @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + compiler, + sysroot ? null, + buildInputs ? [ ], +}: + +let + target = pkgs.stdenv.hostPlatform.config; + mold = pkgs.buildPackages.mold-unwrapped; + searchFlags = + pkgs.lib.optionals (sysroot != null) [ + "--sysroot=${sysroot}" + "-isystem${sysroot}/usr/include" + "-B${sysroot}/usr/lib" + "-L${sysroot}/usr/lib" + ] + ++ map (package: "-L${pkgs.lib.getLib package}/lib") buildInputs; + runtimeFlags = pkgs.lib.optionals (sysroot != null) [ + "-static-libgcc" + "-lssp" + ]; +in +pkgs.buildPackages.writeShellScriptBin "${target}-cc" '' + exec ${compiler} \ + -B${mold}/bin \ + -B${pkgs.buildPackages.binutils-unwrapped}/${target}/bin \ + ${pkgs.lib.escapeShellArgs searchFlags} \ + "$@" \ + -fuse-ld=mold ${pkgs.lib.escapeShellArgs runtimeFlags} +'' diff --git a/nix/toolchain/gnu.nix b/nix/toolchain/gnu.nix new file mode 100644 index 0000000000..b014746216 --- /dev/null +++ b/nix/toolchain/gnu.nix @@ -0,0 +1,116 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ pkgs }: + +let + glibc = pkgs.callPackage ./libc.nix { }; + gcc = pkgs.buildPackages.gccNGPackages.gcc-unwrapped.overrideAttrs (old: { + postPatch = + builtins.replaceStrings [ "gcc/config/darwin-c.c" ] [ "gcc/config/darwin-c.cc" ] old.postPatch + + '' + substituteInPlace gcc/collect2.cc \ + --replace-fail 'basename(c_file_name)' 'lbasename(c_file_name)' + ''; + configureFlags = old.configureFlags ++ [ + "--disable-fixincludes" + "--with-native-system-header-dir=/include" + ]; + }); + mkRuntime = + libraryPaths: + pkgs.buildEnv { + name = "gcc-static-runtime"; + paths = libraryPaths ++ map pkgs.lib.getDev libraryPaths; + pathsToLink = [ + "/include" + "/include-cxx" + "/lib" + ]; + postBuild = '' + mkdir -p $out/lib + find $out/lib -type l ! \( -name '*.a' -o -name 'crt*.o' \) -delete + printf 'GROUP ( libgcc.a libgcc_eh.a )\n' > $out/lib/libgcc_s.a + ''; + passthru.isGNU = true; + }; + mkStdenv = + { + libraryPaths ? [ ], + ldflags ? null, + }: + let + runtime = mkRuntime libraryPaths; + in + pkgs.overrideCC pkgs.stdenv ( + pkgs.buildPackages.wrapCCWith { + cc = gcc; + bintools = pkgs.buildPackages.wrapBintoolsWith { + bintools = pkgs.buildPackages.binutils-unwrapped; + libc = glibc; + }; + extraPackages = [ runtime ]; + libcxx = runtime; + nixSupport = { + cc-cflags = [ + "-isystem${pkgs.linuxHeaders}/include" + "-static-libgcc" + "-B${runtime}/lib" + ]; + } + // pkgs.lib.optionalAttrs (ldflags != null) { cc-ldflags = ldflags; }; + } + ); + libgcc = + (pkgs.gccNGPackages.libgcc.override { + stdenv = mkStdenv { }; + }).overrideAttrs + (old: { + makeFlags = old.makeFlags ++ [ "SHLIB_LC=-lc" ]; + }); + libssp = + (pkgs.gccNGPackages.libssp.override { + stdenv = mkStdenv { libraryPaths = [ libgcc ]; }; + }).overrideAttrs + { + dontDisableStatic = true; + }; + libstdcxxStdenv = mkStdenv { + libraryPaths = [ + libgcc + libssp + ]; + }; + libstdcxx = + (pkgs.gccNGPackages.libstdcxx.override { + stdenv = libstdcxxStdenv; + inherit libgcc; + libbacktrace = pkgs.libbacktrace.override { + stdenv = libstdcxxStdenv; + }; + }).overrideAttrs + { + dontDisableStatic = true; + }; + runtime = mkRuntime [ + libgcc + libssp + libstdcxx + ]; + stdenv = mkStdenv { + libraryPaths = [ + libgcc + libssp + libstdcxx + ]; + ldflags = [ "-lssp" ]; + }; +in +{ + inherit + glibc + gcc + runtime + stdenv + ; +} diff --git a/nix/toolchains/linux-gnu-2.28/libc.nix b/nix/toolchain/libc.nix similarity index 68% rename from nix/toolchains/linux-gnu-2.28/libc.nix rename to nix/toolchain/libc.nix index 8f1c9864bd..36230beae3 100644 --- a/nix/toolchains/linux-gnu-2.28/libc.nix +++ b/nix/toolchain/libc.nix @@ -2,8 +2,10 @@ # SPDX-License-Identifier: Apache-2.0 { + lib, stdenv, fetchurl, + fetchpatch, linuxHeaders, bison, gawk, @@ -24,6 +26,13 @@ stdenv.mkDerivation { hash = "sha256-8xjW4/H07Qt00oMqxPSR0PuSjkUcntpZTL8cO+569Hw="; }; + patches = lib.optionals stdenv.buildPlatform.isDarwin [ + (fetchpatch { + url = "https://raw.githubusercontent.com/NixOS/nixpkgs/022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf/pkgs/development/libraries/glibc/darwin-cross-build.patch"; + hash = "sha256-RFs6jNY11ZVNnflm7B5NkFbCbVuRiR+RyJmdA993ArE="; + }) + ]; + postPatch = '' substituteInPlace sysdeps/gnu/Makefile \ --replace-fail \ @@ -46,6 +55,15 @@ stdenv.mkDerivation { mkdir build cd build configureScript=../configure + + # Keep the cross tools selected by Nix instead of GCC's bare tool names. + sed -i \ + -e '/^AR=/d' \ + -e '/^AS=/d' \ + -e '/^LD=/d' \ + -e '/^OBJCOPY=/d' \ + -e '/^OBJDUMP=/d' \ + "$configureScript" ''; postConfigure = '' diff --git a/nix/toolchain/sysroot.nix b/nix/toolchain/sysroot.nix new file mode 100644 index 0000000000..b282d32263 --- /dev/null +++ b/nix/toolchain/sysroot.nix @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + glibc, + runtime, + buildInputs ? [ ], +}: + +let + target = pkgs.stdenv.targetPlatform.config; + +in +pkgs.buildEnv { + name = "${target}-sysroot"; + paths = [ + glibc + runtime + pkgs.linuxHeaders + ] + ++ pkgs.lib.concatMap (package: [ + (pkgs.lib.getDev package) + (pkgs.lib.getLib package) + ]) buildInputs; + pathsToLink = [ + "/include" + "/lib" + ]; + extraPrefix = "/usr"; + + postBuild = '' + # Linker scripts must resolve libraries through the sysroot, not the store. + rm "$out/usr/lib/libc.so" "$out/usr/lib/libm.so" + sed 's|${glibc}/lib/||g' ${glibc}/lib/libc.so > "$out/usr/lib/libc.so" + sed 's|${glibc}/lib/||g' ${glibc}/lib/libm.so > "$out/usr/lib/libm.so" + + ln -s usr/lib "$out/lib" + ln -s usr/lib "$out/lib64" + ''; +} diff --git a/nix/toolchains/linux-gnu-2.28/default.nix b/nix/toolchains/linux-gnu-2.28/default.nix deleted file mode 100644 index 4b8b0ab453..0000000000 --- a/nix/toolchains/linux-gnu-2.28/default.nix +++ /dev/null @@ -1,106 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -{ pkgs }: - -let - glibc = pkgs.callPackage ./libc.nix { }; - mkStdenv = - { - libraryPaths ? [ ], - ldflags ? null, - }: - let - runtime = pkgs.buildEnv { - name = "gcc-static-runtime"; - paths = libraryPaths ++ map pkgs.lib.getDev libraryPaths; - pathsToLink = [ - "/include" - "/include-cxx" - "/lib" - ]; - postBuild = '' - mkdir -p $out/lib - find $out/lib -type l ! \( -name '*.a' -o -name 'crt*.o' \) -delete - printf 'GROUP ( libgcc.a libgcc_eh.a )\n' > $out/lib/libgcc_s.a - ''; - passthru.isGNU = true; - }; - in - pkgs.stdenvAdapters.useMoldLinker ( - pkgs.overrideCC pkgs.stdenv ( - pkgs.wrapCCWith { - cc = pkgs.gccNGPackages.gcc-unwrapped.overrideAttrs (old: { - configureFlags = old.configureFlags ++ [ - "--disable-fixincludes" - "--with-native-system-header-dir=/include" - ]; - }); - bintools = pkgs.wrapBintoolsWith { - bintools = pkgs.binutils-unwrapped; - libc = glibc; - }; - extraPackages = [ runtime ]; - libcxx = runtime; - nixSupport = { - cc-cflags = [ - "-isystem${pkgs.linuxHeaders}/include" - "-static-libgcc" - "-B${runtime}/lib" - ]; - } - // pkgs.lib.optionalAttrs (ldflags != null) { cc-ldflags = ldflags; }; - } - ) - ); - libgcc = - (pkgs.gccNGPackages.libgcc.override { - stdenv = mkStdenv { }; - }).overrideAttrs - (old: { - makeFlags = old.makeFlags ++ [ "SHLIB_LC=-lc" ]; - }); - libssp = - (pkgs.gccNGPackages.libssp.override { - stdenv = mkStdenv { libraryPaths = [ libgcc ]; }; - }).overrideAttrs - { - dontDisableStatic = true; - }; - libstdcxxStdenv = mkStdenv { - libraryPaths = [ - libgcc - libssp - ]; - }; - libstdcxx = - (pkgs.gccNGPackages.libstdcxx.override { - stdenv = libstdcxxStdenv; - inherit libgcc; - libbacktrace = pkgs.libbacktrace.override { - stdenv = libstdcxxStdenv; - }; - }).overrideAttrs - { - dontDisableStatic = true; - }; - sharedRuntime = pkgs.buildEnv { - name = "gcc-shared-runtime"; - paths = [ - libgcc - libstdcxx - ]; - pathsToLink = [ "/lib" ]; - }; - stdenv = mkStdenv { - libraryPaths = [ - libgcc - libssp - libstdcxx - ]; - ldflags = [ "-lssp" ]; - }; -in -{ - inherit sharedRuntime stdenv; -} From 675411f4fa43a0edbd8436fd331f07ecc7dfc1db Mon Sep 17 00:00:00 2001 From: Simon Scatton Date: Wed, 9 Sep 2026 18:16:00 +0200 Subject: [PATCH 2/4] ci(nix): allow longer shell builds with verbose logs Signed-off-by: Simon Scatton --- .github/workflows/branch-checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/branch-checks.yml b/.github/workflows/branch-checks.yml index 5d4a98c61a..79a9510d59 100644 --- a/.github/workflows/branch-checks.yml +++ b/.github/workflows/branch-checks.yml @@ -120,7 +120,7 @@ jobs: - runner: macos-15-xlarge system: aarch64-darwin runs-on: ${{ matrix.runner }} - timeout-minutes: 30 + timeout-minutes: 300 defaults: run: shell: nix develop .#devShells.${{ matrix.system }}.default -c bash -euo pipefail {0} @@ -138,7 +138,7 @@ jobs: - name: Realize Nix development shell shell: bash - run: nix build --no-link ".#devShells.${{ matrix.system }}.default" + run: nix build -L --no-link ".#devShells.${{ matrix.system }}.default" - name: Cache Rust target and registry uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 From dc6a328ef73faa44efecb8175e289e4a7d2ee848 Mon Sep 17 00:00:00 2001 From: Simon Scatton Date: Wed, 9 Sep 2026 19:25:50 +0200 Subject: [PATCH 3/4] fix(nix): provide a portable Darwin toolchain Signed-off-by: Simon Scatton --- architecture/build.md | 14 ++++++++++++++ flake.nix | 10 +++++++--- nix/pkgs/aws-lc.nix | 2 +- nix/toolchain/darwin.nix | 33 +++++++++++++++++++++++++++++++++ nix/toolchain/driver.nix | 29 ++++++++++++++++++++--------- 5 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 nix/toolchain/darwin.nix diff --git a/architecture/build.md b/architecture/build.md index 4365356f97..8d24ba9356 100644 --- a/architecture/build.md +++ b/architecture/build.md @@ -147,6 +147,20 @@ in platform-specific Nix development shells through reusable workflows and the shared `build-rust-binary` action. The image build downloads each binary artifact into the staging directory before running Buildx. +The Nix flake exposes one development shell with target-specific toolchains. +Each toolchain supplies its compiler driver, assembler, archiver, native +libraries, and Cargo environment through derivation passthru. The shell omits +an implicit host C compiler; Cargo builds select the appropriate tools with +`--target`. GNU targets use a glibc 2.28 sysroot and static GCC runtimes, while +musl targets produce static executables. + +On macOS, the shell also provides a native Darwin toolchain with static Z3 +and AWS-LC. Its Clang driver uses the pinned, unprocessed Apple SDK so system +library stubs, including libiconv and libc++, retain their Apple install names. +System libraries and frameworks remain dynamically linked. The deployment +target matches the Nix host platform's minimum macOS version. The Rust toolchain +does not propagate Nix's replacement system libraries into the link environment. + Gateway and supervisor binaries staged into branch E2E, Release Dev, and Release Tag images are compiled through `cargo auditable` (pinned in `mise.toml`), which embeds a `.dep-v0` section describing the Rust dependencies actually compiled diff --git a/flake.nix b/flake.nix index 6498ac9afb..082716ff46 100644 --- a/flake.nix +++ b/flake.nix @@ -71,13 +71,12 @@ }; rustToolchain = ((pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml).override { - targets = map (toolchain: toolchain.target) (builtins.attrValues toolchains) ++ [ - "aarch64-apple-darwin" - ]; + targets = map (toolchain: toolchain.target) (builtins.attrValues toolchains); }).overrideAttrs { propagatedBuildInputs = [ ]; depsHostHostPropagated = [ ]; + depsTargetTargetPropagated = [ ]; }; buildInputs = { pkgs, stdenv }: [ (pkgs.callPackage ./nix/pkgs/z3.nix { inherit stdenv; }) @@ -100,6 +99,11 @@ pkgs = pkgs.pkgsCross.aarch64-multiplatform-musl; inherit buildInputs; }; + } + // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { + aarch64-darwin = pkgs.callPackage ./nix/toolchain/darwin.nix { + inherit buildInputs; + }; }; vmRuntime = pkgs.callPackage ./nix/pkgs/vm-runtime.nix { }; testGuest = import ./nix/test-guest { diff --git a/nix/pkgs/aws-lc.nix b/nix/pkgs/aws-lc.nix index cd82735c51..ed46ec4943 100644 --- a/nix/pkgs/aws-lc.nix +++ b/nix/pkgs/aws-lc.nix @@ -11,7 +11,7 @@ let strings = callPackage ../strings.nix { }; - target = stdenv.hostPlatform.config; + target = stdenv.hostPlatform.rust.cargoShortTarget; package = (aws-lc.override { inherit stdenv; diff --git a/nix/toolchain/darwin.nix b/nix/toolchain/darwin.nix new file mode 100644 index 0000000000..7ac09fe9ce --- /dev/null +++ b/nix/toolchain/darwin.nix @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + buildInputs, +}: + +let + strings = pkgs.callPackage ../strings.nix { }; + inherit (pkgs) stdenv; + target = stdenv.hostPlatform.rust.cargoShortTarget; + packages = buildInputs { inherit pkgs stdenv; }; + # The processed Nix SDK removes system stubs such as libiconv and libc++. + sysroot = pkgs.apple-sdk.src; + toolchain = pkgs.callPackage ./driver.nix { + inherit sysroot; + compiler = "${stdenv.cc.cc}/bin/clang"; + buildInputs = packages; + }; +in +toolchain.overrideAttrs (old: { + passthru = (old.passthru or { }) // { + inherit target stdenv sysroot; + buildInputs = packages; + env = pkgs.lib.foldl' (env: package: env // (package.passthru.env or { })) { } packages // { + ${strings.cargoTargetEnvVar target "LINKER"} = "${toolchain}/bin/${target}-cc"; + ${strings.targetEnvVar target "CC"} = "${toolchain}/bin/${target}-cc"; + ${strings.targetEnvVar target "AS"} = "${stdenv.cc.bintools}/bin/as"; + ${strings.targetEnvVar target "AR"} = "${stdenv.cc.bintools}/bin/ar"; + }; + }; +}) diff --git a/nix/toolchain/driver.nix b/nix/toolchain/driver.nix index 244a31f413..0e38ca7b5e 100644 --- a/nix/toolchain/driver.nix +++ b/nix/toolchain/driver.nix @@ -9,7 +9,7 @@ }: let - target = pkgs.stdenv.hostPlatform.config; + target = pkgs.stdenv.hostPlatform.rust.cargoShortTarget; mold = pkgs.buildPackages.mold-unwrapped; searchFlags = pkgs.lib.optionals (sysroot != null) [ @@ -24,11 +24,22 @@ let "-lssp" ]; in -pkgs.buildPackages.writeShellScriptBin "${target}-cc" '' - exec ${compiler} \ - -B${mold}/bin \ - -B${pkgs.buildPackages.binutils-unwrapped}/${target}/bin \ - ${pkgs.lib.escapeShellArgs searchFlags} \ - "$@" \ - -fuse-ld=mold ${pkgs.lib.escapeShellArgs runtimeFlags} -'' +if pkgs.stdenv.hostPlatform.isDarwin then + pkgs.buildPackages.writeShellScriptBin "${target}-cc" '' + exec ${compiler} \ + "$@" \ + --target=${target} \ + -isysroot ${sysroot} \ + -mmacosx-version-min=${pkgs.stdenv.hostPlatform.darwinMinVersion} \ + -fuse-ld=${pkgs.stdenv.cc.bintools.bintools}/bin/ld \ + ${pkgs.lib.escapeShellArgs (map (package: "-L${pkgs.lib.getLib package}/lib") buildInputs)} + '' +else + pkgs.buildPackages.writeShellScriptBin "${target}-cc" '' + exec ${compiler} \ + -B${mold}/bin \ + -B${pkgs.buildPackages.binutils-unwrapped}/${target}/bin \ + ${pkgs.lib.escapeShellArgs searchFlags} \ + "$@" \ + -fuse-ld=mold ${pkgs.lib.escapeShellArgs runtimeFlags} + '' From 6067054b773c664b17889e7cf566c5846eb93c62 Mon Sep 17 00:00:00 2001 From: Simon Scatton Date: Wed, 9 Sep 2026 19:30:00 +0200 Subject: [PATCH 4/4] ci(nix): cross-compile Linux workspace from macOS Signed-off-by: Simon Scatton --- .github/workflows/branch-checks.yml | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/branch-checks.yml b/.github/workflows/branch-checks.yml index 79a9510d59..ac1c800c0d 100644 --- a/.github/workflows/branch-checks.yml +++ b/.github/workflows/branch-checks.yml @@ -197,6 +197,54 @@ jobs: exit 1 fi + macos-cross: + name: macOS cross (${{ matrix.target }}) + needs: pr_metadata + if: needs.pr_metadata.outputs.should_run == 'true' + strategy: + fail-fast: false + matrix: + target: + - x86_64-unknown-linux-gnu + - aarch64-unknown-linux-gnu + - x86_64-unknown-linux-musl + - aarch64-unknown-linux-musl + runs-on: macos-15-xlarge + timeout-minutes: 300 + defaults: + run: + shell: nix develop .#devShells.aarch64-darwin.default -c bash -euo pipefail {0} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + with: + name: openshell + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - name: Realize Nix development shell + shell: bash + run: nix build -L --no-link .#devShells.aarch64-darwin.default + + - name: Cache Rust target and registry + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + shared-key: macos-cross-${{ matrix.target }} + cache-on-failure: "true" + cache-workspace-crates: "true" + cache-bin: "false" + cmd-format: nix develop .#devShells.aarch64-darwin.default -c {0} + + - name: Build workspace + run: cargo build --locked --workspace --target ${{ matrix.target }} + + - name: Compile Linux tests + run: cargo test --locked --no-run --workspace --features openshell-server/test-support --target ${{ matrix.target }} + python: name: Python (${{ matrix.runner }}) needs: pr_metadata