Hedronite Lesson · Polyglot-Dev / Nix · Wed 2026-09-30 · T7

Static musl cross for a Rust binary — pkgsCross.musl64 vs pkgsStatic

Say what musl static buys. Enter Linux musl through pkgsCross; do not trust Darwin pkgsStatic.

Lesson Class: Asr (Nix T7 Env & CI · Rust roads)
Focus: Musl Buy · Cross Seat Map · Expression Read · pkgsCross.musl64 · pkgsStatic
Done-criteria: what musl static linking buys; read a cross/static expression without guessing
Grounding: verified pkgsCross.musl64 + nested pkgsStatic.hello · nixpkgs #chap-cross
Note: Not Duha Beat B · not flake schema · not floor gate · Bend s08 is peer · next #19 flake
Musl Buy
Portable Linux file; named musl triple; static means libc in the binary.
Cross Seat Map
musl64 = musl Linux; musl64.pkgsStatic = static+musl; bare pkgsStatic follows host.
Expression Read
pkgsCross.musl64.rustPlatform.buildRustPackage; verify attrs; no corpus invent.
Cross first for Linux musl. Static is a second dial. Do not invent attribute names.

<!-- hal:authoritative:yaml -->

Say what musl static linking buys. Read a cross/static expression without guessing attribute names.

§I — Frame

Asr session 18. Topic T7 Env & CI. Third fire of the Nix Rust-roads block. Home: . Cite: Nixpkgs cross-compilation (pkgsCross / pkgsStatic) at https://nixos.org/manual/nixpkgs/stable/#chap-cross. Corpus: ~/projects/rust-tops/nix/cargo-tops.nix and flake.nix (vault mirror under foundry/rust-tops/repo/rust-tops/). Those files have no musl expression today. That absence is the teaching edge, not a prompt to invent attrs or push the repo.

Session 16 named rustPlatform.buildRustPackage. Session 17 mapped writer vs cargo-script vs crate. Today the unmarked row asks the deploy road: how do you aim a Rust binary at Linux musl, and when is that binary actually static.

Verified on this Mac (Darwin arm64 host) before drafting:

EvalResult
pkgsCross.musl64.stdenv.hostPlatform.configx86_64-unknown-linux-musl
pkgsCross.musl64.hello.namehello-x86_64-unknown-linux-musl-…
pkgsCross.musl64.stdenv.hostPlatform.isMusl / isStatictrue / false
pkgsCross.musl64.pkgsStatic.hello.namehello-static-x86_64-unknown-linux-musl-…
bare pkgsStatic.hello.namehello-static-arm64-apple-darwin-…

Other musl keys seen under pkgsCross: musl32, aarch64-multiplatform-musl, muslpi, and related power/riscv keys. Do not invent names outside what you eval.

Today's Duha Nix packaging shell (lesson_class: duha, async/await crate) does not consume this Asr cursor.

Done-criteria from the syllabus: you can state what musl static linking buys, and read a cross/static build expression without guessing.

Not flake devShell/checks schema. Not Bend encode-a-clause (peer seat today).

§II — Musl Buy (named technique)

Musl Buy: say the product before the attribute.

A musl-linked Linux binary talks to musl libc instead of glibc. A static musl binary carries its libc into the file. That buys:

  1. Portable deploy: one file onto a scratch image, many Alpine hosts, or a glibc-skewed fleet without matching the host libc.
  2. Fewer runtime shared-object surprises: no "GLIBC_2.XX not found" on the target.
  3. Clear target triple: x86_64-unknown-linux-musl (or aarch64 musl) names the ABI you meant.

Musl alone is not automatic static. On this host, pkgsCross.musl64 is musl and not static (isStatic = false). Static musl is a second turn of the dial.

Yagyu: name the buy in one breath. Musashi: portable file, named triple, no glibc lottery.

§III — Cross Seat Map (named technique)

Cross Seat Map: three seats you must not collapse.

SeatAttr path (verified)Host platform story
Musl crosspkgs.pkgsCross.musl64Linux musl, dynamic-capable (isStatic = false)
Static musl crosspkgs.pkgsCross.musl64.pkgsStaticLinux musl and static
Host staticpkgs.pkgsStaticFollows this host; on Darwin → arm64-apple-darwin static

Bare pkgsStatic on a Darwin laptop is the Darwin static story. It is the wrong road when the syllabus asks for Linux musl. For that road, start at pkgsCross.musl64, then take .pkgsStatic when you need the static file.

aarch64 Linux musl uses the verified key pkgsCross.aarch64-multiplatform-musl (aarch64-unknown-linux-musl). Same seat logic: cross first, nested pkgsStatic when you need static+musl.

Chozanshi: if the host is Darwin and the target is Linux musl, then do not trust bare pkgsStatic; thus enter through pkgsCross.musl64 (or the aarch64 musl key).

§IV — Expression Read (named technique)

Expression Read: read a minimal teaching shape with only verified nouns.

Hello smoke (attrs verified; no invent):

let
  pkgs = import <nixpkgs> { };
in
{
  musl = pkgs.pkgsCross.musl64.hello;
  staticMusl = pkgs.pkgsCross.musl64.pkgsStatic.hello;
}

Rust crate road (same cross seat, session 16 builder):

let
  pkgs = import <nixpkgs> { };
  muslPkgs = pkgs.pkgsCross.musl64;
in
muslPkgs.rustPlatform.buildRustPackage {
  pname = "demo";
  version = "0.1.0";
  src = ./.;
  cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
}

muslPkgs.rustPlatform.buildRustPackage exists under pkgsCross.musl64 (verified hasAttr). Fill cargoHash / cargoLock the same way session 16 taught on native cargo-tops.nix. For a static musl binary, prefer the nested static seat:

muslPkgs.pkgsStatic.rustPlatform.buildRustPackage { /* same fields */ }

only after you confirm that attribute path on your nixpkgs pin the way you confirmed hello.

Corpus honesty: nix/cargo-tops.nix and flake.nix have no pkgsCross / musl output today. Teach the expression from nixpkgs. Do not push a musl package into rust-tops from this lesson.

§V — Why this road

Asr Nix seats T7 so Rust packaging has a deploy road after crate and writer seats. Session 16 built native. Session 17 sorted thin scripts. Session 18 names Musl Buy, Cross Seat Map, and Expression Read so you stop confusing Darwin pkgsStatic with Linux musl.

Keep the Duha/Asr split clear: Duha Beat B may package today's lesson crate under lesson_class: duha. Asr advances NIX-SYLLABUS rows under lesson_class: asr and topic: T7.

§VI — Done-criteria check

Say aloud without looking:

  1. Musl Buy: portable Linux file, named musl triple, less glibc skew; static means libc in the binary.
  2. Cross Seat Map: pkgsCross.musl64 = musl Linux; nested .pkgsStatic = static+musl; bare pkgsStatic follows host (Darwin here).
  3. Expression Read: pkgsCross.musl64.rustPlatform.buildRustPackage { … } with verified attrs only.
  4. Corpus honesty: rust-tops has no musl expression yet; do not invent one in the product repo from class.

§VII — Common mistakes

  1. Treating bare pkgsStatic on Darwin as Linux musl.
  2. Calling pkgsCross.musl64 "static" when isStatic is false.
  3. Inventing attribute names without nix eval.
  4. Treating today's Duha Nix packaging shell as this Asr Topics #18 ship.
  5. Jumping to flake schema (row #19) or POSIX floor gate (row #20) before this seat map is fluent.
  6. Editing rust-tops to add a musl output from this lesson.

§VIII — Boundaries

§IX — Close

Session 17 mapped writer and cargo-script seats. Session 18 maps Musl Buy, Cross Seat Map, and Expression Read against verified pkgsCross.musl64 / nested pkgsStatic. Next unmarked: session 19, flake devShell and checks for a real crate.

Related:

Eval the three seats once. Leave the keyboard.