From 9a238d06295ac59cfeaf1bf5af497a53b6efc150 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Tue, 8 Sep 2026 15:00:31 +0200 Subject: [PATCH 1/3] feat(build): add ARM64 Linux musl cross shell Signed-off-by: Evan Lezar --- architecture/build.md | 11 +++++++ flake.nix | 17 ++++++++-- nix/devShells/cross-aarch64-linux-musl.nix | 37 ++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 nix/devShells/cross-aarch64-linux-musl.nix diff --git a/architecture/build.md b/architecture/build.md index 972f847bb9..e40ccaac08 100644 --- a/architecture/build.md +++ b/architecture/build.md @@ -77,6 +77,17 @@ continue to opt in with `bundled-z3`. ## Linux Runtime Environments +### macOS-hosted ARM64 musl CLI builds + +On Apple Silicon macOS, `nix develop .#crossShells.aarch64-darwin.aarch64-linux.musl` provides a +Darwin-hosted toolchain for building Linux ARM64 musl binaries. Its `cargo` +shim dispatches `cargo build` through `cargo-zigbuild` with the +`aarch64-unknown-linux-musl` target, so a plain CLI build produces +`target/aarch64-unknown-linux-musl//openshell`. The resulting static +ELF binary is intended for a Linux guest VM; this shell is not a Linux runtime +environment and does not replace `devShells.aarch64-linux.musl`, which remains +the native Linux shell used in ARM64 Linux CI. + OpenShell uses different Linux libc environments for different host artifacts. The standalone `openshell` CLI is built as a static musl binary so it can run on a wide range of Linux distributions without depending on the host's glibc. Host diff --git a/flake.nix b/flake.nix index e361fd1597..fe383cb0a5 100644 --- a/flake.nix +++ b/flake.nix @@ -37,7 +37,8 @@ rust-overlay, ... }: - flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ] ( + let + perSystem = flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ] ( system: let pkgs = import nixpkgs { @@ -100,6 +101,11 @@ ++ commonDevShellPackages; }; } + // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { + cross-aarch64-linux-musl = import ./nix/devShells/cross-aarch64-linux-musl.nix { + inherit pkgs rust-overlay commonDevShellPackages; + }; + } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { glibc-2-28 = import ./nix/devShells/glibc-2-28.nix { inherit pkgs rust-overlay commonDevShellPackages; @@ -111,5 +117,12 @@ formatter = treefmtEval.config.build.wrapper; } - ); + ); + in + perSystem + // { + # Cross-shell names describe the Linux target, rather than the Darwin + # execution platform that runs their toolchains. + crossShells.aarch64-darwin.aarch64-linux.musl = perSystem.devShells.aarch64-darwin.cross-aarch64-linux-musl; + }; } diff --git a/nix/devShells/cross-aarch64-linux-musl.nix b/nix/devShells/cross-aarch64-linux-musl.nix new file mode 100644 index 0000000000..7a0793f36a --- /dev/null +++ b/nix/devShells/cross-aarch64-linux-musl.nix @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + rust-overlay, + commonDevShellPackages, +}: + +let + target = "aarch64-unknown-linux-musl"; + rust-bin = rust-overlay.lib.mkRustBin { } pkgs; + rustToolchain = (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml).override { + enableLibsecret = false; + targets = [ target ]; + }; + cargo = pkgs.writeShellScriptBin "cargo" '' + if [[ $# -gt 0 && $1 == build ]]; then + shift + # Keep the real Cargo ahead of this shim so cargo-zigbuild can invoke it + # without recursively dispatching back into this script. + export PATH=${rustToolchain}/bin:${pkgs.cargo-zigbuild}/bin:${pkgs.zig}/bin:$PATH + exec ${pkgs.cargo-zigbuild}/bin/cargo-zigbuild zigbuild --target ${target} "$@" + fi + + exec ${rustToolchain}/bin/cargo "$@" + ''; +in +pkgs.mkShell { + packages = [ + cargo + rustToolchain + pkgs.cargo-zigbuild + pkgs.zig + ] + ++ commonDevShellPackages; +} From 10175eed91d693882c4f4c7bb6f9936bd93d4bb5 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Tue, 8 Sep 2026 15:51:16 +0200 Subject: [PATCH 2/3] feat(build): add ARM64 Linux gnu cross shell Signed-off-by: Evan Lezar --- architecture/build.md | 6 +++ flake.nix | 4 ++ nix/devShells/cross-aarch64-linux-gnu.nix | 45 +++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 nix/devShells/cross-aarch64-linux-gnu.nix diff --git a/architecture/build.md b/architecture/build.md index e40ccaac08..4c8cb855e3 100644 --- a/architecture/build.md +++ b/architecture/build.md @@ -88,6 +88,12 @@ ELF binary is intended for a Linux guest VM; this shell is not a Linux runtime environment and does not replace `devShells.aarch64-linux.musl`, which remains the native Linux shell used in ARM64 Linux CI. +`nix develop .#crossShells.aarch64-darwin.aarch64-linux.gnu` provides the +corresponding gateway shell. Its Cargo shim uses Zig's glibc 2.28 target while +Cargo writes artifacts beneath `target/aarch64-unknown-linux-gnu/`. It supplies +a Nix-built static ARM64 Z3 library, matching the default-feature gateway CI +build without enabling `bundled-z3`. + OpenShell uses different Linux libc environments for different host artifacts. The standalone `openshell` CLI is built as a static musl binary so it can run on a wide range of Linux distributions without depending on the host's glibc. Host diff --git a/flake.nix b/flake.nix index fe383cb0a5..6827084509 100644 --- a/flake.nix +++ b/flake.nix @@ -105,6 +105,9 @@ cross-aarch64-linux-musl = import ./nix/devShells/cross-aarch64-linux-musl.nix { inherit pkgs rust-overlay commonDevShellPackages; }; + cross-aarch64-linux-gnu = import ./nix/devShells/cross-aarch64-linux-gnu.nix { + inherit pkgs rust-overlay commonDevShellPackages; + }; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { glibc-2-28 = import ./nix/devShells/glibc-2-28.nix { @@ -124,5 +127,6 @@ # Cross-shell names describe the Linux target, rather than the Darwin # execution platform that runs their toolchains. crossShells.aarch64-darwin.aarch64-linux.musl = perSystem.devShells.aarch64-darwin.cross-aarch64-linux-musl; + crossShells.aarch64-darwin.aarch64-linux.gnu = perSystem.devShells.aarch64-darwin.cross-aarch64-linux-gnu; }; } diff --git a/nix/devShells/cross-aarch64-linux-gnu.nix b/nix/devShells/cross-aarch64-linux-gnu.nix new file mode 100644 index 0000000000..1d1db37c5a --- /dev/null +++ b/nix/devShells/cross-aarch64-linux-gnu.nix @@ -0,0 +1,45 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + rust-overlay, + commonDevShellPackages, +}: + +let + target = "aarch64-unknown-linux-gnu"; + zigTarget = "${target}.2.28"; + crossPkgs = pkgs.pkgsCross.aarch64-multiplatform; + z3-static = crossPkgs.callPackage ../pkgs/z3-static.nix { }; + rust-bin = rust-overlay.lib.mkRustBin { } pkgs; + rustToolchain = (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml).override { + enableLibsecret = false; + targets = [ target ]; + }; + cargo = pkgs.writeShellScriptBin "cargo" '' + if [[ $# -gt 0 && $1 == build ]]; then + shift + # Keep the real Cargo ahead of this shim so cargo-zigbuild can invoke it + # without recursively dispatching back into this script. + export PATH=${rustToolchain}/bin:${pkgs.cargo-zigbuild}/bin:${pkgs.zig}/bin:$PATH + exec ${pkgs.cargo-zigbuild}/bin/cargo-zigbuild zigbuild --target ${zigTarget} "$@" + fi + + exec ${rustToolchain}/bin/cargo "$@" + ''; +in +pkgs.mkShell { + packages = [ + cargo + rustToolchain + pkgs.cargo-zigbuild + pkgs.zig + z3-static + ] + ++ commonDevShellPackages; + + # CI builds the gateway against a Nix-provided static Z3. Keep the same + # default-feature behavior while supplying the ARM64 Linux target library. + Z3_LIBRARY_PATH_OVERRIDE = "${z3-static}/lib"; +} From 4edf3aec1bf788a0b8c19fefff4e3d44de857b45 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Tue, 8 Sep 2026 16:00:45 +0200 Subject: [PATCH 3/3] refactor(build): share cross Rust shell setup Signed-off-by: Evan Lezar --- nix/devShells/cross-aarch64-linux-gnu.nix | 35 +++-------------- nix/devShells/cross-aarch64-linux-musl.nix | 30 ++------------- nix/devShells/cross-rust.nix | 44 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 56 deletions(-) create mode 100644 nix/devShells/cross-rust.nix diff --git a/nix/devShells/cross-aarch64-linux-gnu.nix b/nix/devShells/cross-aarch64-linux-gnu.nix index 1d1db37c5a..fa17922921 100644 --- a/nix/devShells/cross-aarch64-linux-gnu.nix +++ b/nix/devShells/cross-aarch64-linux-gnu.nix @@ -8,38 +8,15 @@ }: let - target = "aarch64-unknown-linux-gnu"; - zigTarget = "${target}.2.28"; crossPkgs = pkgs.pkgsCross.aarch64-multiplatform; z3-static = crossPkgs.callPackage ../pkgs/z3-static.nix { }; - rust-bin = rust-overlay.lib.mkRustBin { } pkgs; - rustToolchain = (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml).override { - enableLibsecret = false; - targets = [ target ]; - }; - cargo = pkgs.writeShellScriptBin "cargo" '' - if [[ $# -gt 0 && $1 == build ]]; then - shift - # Keep the real Cargo ahead of this shim so cargo-zigbuild can invoke it - # without recursively dispatching back into this script. - export PATH=${rustToolchain}/bin:${pkgs.cargo-zigbuild}/bin:${pkgs.zig}/bin:$PATH - exec ${pkgs.cargo-zigbuild}/bin/cargo-zigbuild zigbuild --target ${zigTarget} "$@" - fi - - exec ${rustToolchain}/bin/cargo "$@" - ''; in -pkgs.mkShell { - packages = [ - cargo - rustToolchain - pkgs.cargo-zigbuild - pkgs.zig - z3-static - ] - ++ commonDevShellPackages; - +import ./cross-rust.nix { + inherit pkgs rust-overlay commonDevShellPackages; + rustTarget = "aarch64-unknown-linux-gnu"; + zigTarget = "aarch64-unknown-linux-gnu.2.28"; + extraPackages = [ z3-static ]; # CI builds the gateway against a Nix-provided static Z3. Keep the same # default-feature behavior while supplying the ARM64 Linux target library. - Z3_LIBRARY_PATH_OVERRIDE = "${z3-static}/lib"; + shellAttributes.Z3_LIBRARY_PATH_OVERRIDE = "${z3-static}/lib"; } diff --git a/nix/devShells/cross-aarch64-linux-musl.nix b/nix/devShells/cross-aarch64-linux-musl.nix index 7a0793f36a..f1f4699b86 100644 --- a/nix/devShells/cross-aarch64-linux-musl.nix +++ b/nix/devShells/cross-aarch64-linux-musl.nix @@ -7,31 +7,7 @@ commonDevShellPackages, }: -let - target = "aarch64-unknown-linux-musl"; - rust-bin = rust-overlay.lib.mkRustBin { } pkgs; - rustToolchain = (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml).override { - enableLibsecret = false; - targets = [ target ]; - }; - cargo = pkgs.writeShellScriptBin "cargo" '' - if [[ $# -gt 0 && $1 == build ]]; then - shift - # Keep the real Cargo ahead of this shim so cargo-zigbuild can invoke it - # without recursively dispatching back into this script. - export PATH=${rustToolchain}/bin:${pkgs.cargo-zigbuild}/bin:${pkgs.zig}/bin:$PATH - exec ${pkgs.cargo-zigbuild}/bin/cargo-zigbuild zigbuild --target ${target} "$@" - fi - - exec ${rustToolchain}/bin/cargo "$@" - ''; -in -pkgs.mkShell { - packages = [ - cargo - rustToolchain - pkgs.cargo-zigbuild - pkgs.zig - ] - ++ commonDevShellPackages; +import ./cross-rust.nix { + inherit pkgs rust-overlay commonDevShellPackages; + rustTarget = "aarch64-unknown-linux-musl"; } diff --git a/nix/devShells/cross-rust.nix b/nix/devShells/cross-rust.nix new file mode 100644 index 0000000000..fce4d2017e --- /dev/null +++ b/nix/devShells/cross-rust.nix @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +{ + pkgs, + rust-overlay, + commonDevShellPackages, + rustTarget, + zigTarget ? rustTarget, + extraPackages ? [ ], + shellAttributes ? { }, +}: + +let + rust-bin = rust-overlay.lib.mkRustBin { } pkgs; + rustToolchain = (rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml).override { + enableLibsecret = false; + targets = [ rustTarget ]; + }; + cargo = pkgs.writeShellScriptBin "cargo" '' + if [[ $# -gt 0 && $1 == build ]]; then + shift + # Keep the real Cargo ahead of this shim so cargo-zigbuild can invoke it + # without recursively dispatching back into this script. + export PATH=${rustToolchain}/bin:${pkgs.cargo-zigbuild}/bin:${pkgs.zig}/bin:$PATH + exec ${pkgs.cargo-zigbuild}/bin/cargo-zigbuild zigbuild --target ${zigTarget} "$@" + fi + + exec ${rustToolchain}/bin/cargo "$@" + ''; +in +pkgs.mkShell ( + { + packages = [ + cargo + rustToolchain + pkgs.cargo-zigbuild + pkgs.zig + ] + ++ extraPackages + ++ commonDevShellPackages; + } + // shellAttributes +)