From 8e3208528ec85c085d1d8cf267c2453e32c3ceeb Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Fri, 12 Jun 2026 21:43:23 +0000 Subject: [PATCH] build: static musl release build capability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rust-toolchain.toml gains the x86_64-unknown-linux-musl target; the flake devShell gains a musl cc (pkgsCross.musl64) + CC/linker env so a `cargo build --target …-musl` compiles rusqlite's bundled SQLite C and links fully static (D2: single static binary, no runtime deps). Cargo release profile strips symbols (13MB -> 10MB). Verified locally: the musl binary is static-pie, statically linked, stripped, runs standalone. --- Cargo.toml | 6 ++++++ flake.nix | 15 +++++++++++++++ rust-toolchain.toml | 9 +++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 10c5fd4..32408ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,12 @@ tempfile = "3.27.0" incremental = false debug = "line-tables-only" +# Release builds back the distributed binaries (D2: single static binary). +# strip = "symbols" drops the symbol table at link time so the shipped artifact +# is lean (≈13 MB → 10 MB for the musl build) without a separate strip step. +[profile.release] +strip = "symbols" + [lints.rust] unsafe_code = "forbid" unreachable_pub = "warn" diff --git a/flake.nix b/flake.nix index e5f8fd8..77e74d3 100644 --- a/flake.nix +++ b/flake.nix @@ -27,6 +27,13 @@ # from the crate metadata (no hand-maintained duplicate here). cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); + # musl-targeting C compiler for the static release build: rusqlite's + # `bundled` SQLite is compiled from C, so a `--target …-musl` cargo build + # needs a musl `cc` for that C, plus a musl linker. `targetPrefix` is + # "x86_64-unknown-linux-musl-", so the wrapped binary is + # `${muslCC}/bin/x86_64-unknown-linux-musl-cc`. + muslCC = pkgs.pkgsCross.musl64.stdenv.cc; + # System build inputs are deliberately tiny — this is a pure-Rust TUI: # * libsqlite3-sys is built with the `bundled` feature, so SQLite is # compiled from vendored C. That needs a C compiler, which the @@ -68,9 +75,17 @@ # CLAUDE.md "Build hygiene"). cargo-sweep prunes them; run it # periodically between milestones. pkgs.cargo-sweep + # musl cc/linker for the static release build (see muslCC above). + muslCC ]; + # Point cargo's musl target at the musl cc for both the bundled-C + # compile (CC_, consumed by the `cc` crate) and the final link + # (CARGO_TARGET__LINKER). Harmless for normal glibc builds — + # these only take effect when building `--target x86_64-…-musl`. shellHook = '' + export CC_x86_64_unknown_linux_musl="${muslCC}/bin/${muslCC.targetPrefix}cc" + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER="${muslCC}/bin/${muslCC.targetPrefix}cc" echo "RDBMS Playground dev shell ($(uname -s))" echo " rust: $(rustc --version | cut -d' ' -f1-2)" echo " cargo: $(cargo --version | cut -d' ' -f1-2)" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index cabb063..68cd111 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -5,6 +5,11 @@ # flake's convention (its ADR 0046). Bump deliberately, in its own commit. channel = "1.95.0" # rustfmt + clippy back the `fmt`/`clippy` CI stages; no coverage or WASM -# tooling is needed here (pure-Rust TUI). Cross-compilation targets for the -# eventual D1 release matrix are added when that CI lands, not before. +# tooling is needed here (pure-Rust TUI). components = ["rustfmt", "clippy"] +# x86_64 musl for the static release binary (D2: single static binary, no +# runtime deps). The glibc default links the host/nix-store glibc dynamically +# and isn't portable; the musl target with crt-static produces a fully static +# binary. Further D1 matrix targets (aarch64, windows-gnu, …) are added as the +# release matrix expands, step by step. +targets = ["x86_64-unknown-linux-musl"]