Skip to content

feat(build): add a macOS cross-architecture Nix dev shell - #1761

Merged
DeusData merged 1 commit into
mainfrom
feat/nix-cross-dev-shell
Aug 20, 2026
Merged

feat(build): add a macOS cross-architecture Nix dev shell#1761
DeusData merged 1 commit into
mainfrom
feat/nix-cross-dev-shell

Conversation

@DeusData

Copy link
Copy Markdown
Owner

feat(build): add a macOS cross-architecture Nix dev shell

Addresses #705. Distilled from #724 by @kriswill, credited via Co-authored-by.

What

nix develop .#cross on macOS exposes the other darwin architecture's zlib, so scripts/build.sh --arch <target> can link an x86_64 binary on Apple Silicon and vice versa.

The native clang already cross-emits object code via -arch (that's what scripts/env.sh's ARCHFLAGS does, fixed in #723). The only remaining gap is the link: zlib is the product's single link-time dependency (-lz), and the host-arch copy cannot satisfy a cross link. This shell puts the target-arch zlib on the include and link paths, and nothing else.

Cost

Close to zero:

  • Darwin-gated and opt-incrossDevShells returns {} on Linux, so the attribute doesn't exist there.
  • flake.lock untouched, no new flake input. The target-arch packages resolve through the same pinned nixpkgs, and come from prebuilt substitutes, so entering the shell is a download rather than a cross-build of a dependency tree.
  • The default shell is unchanged.
  • No CI leg exercises it, as @kriswill disclosed on the original PR and I agree with — it's developer tooling, and gating it in CI would cost more than it protects.

One deliberate design point: the cross shell does not use inputsFrom the default package. Doing so would put the host-arch zlib back on the link path, which is exactly the wrong-arch copy the shell exists to displace.

What changed from #724

The original also wired libgit2 through pkg-config. That's now dead weight: libgit2 was removed project-wide for GPL-licensing reasons, and I verified it appears nowhere in the tree — not in flake.nix, not in any Makefile. Carrying it forward would have reintroduced a GPL-adjacent reference for a library we no longer link. Both it and pkg-config are dropped, leaving zlib as the only library the cross shell needs to place, which also makes the shell hook considerably smaller.

Verification, stated honestly

There is no Nix toolchain on this machine, so I validated by parsing the flake with nix-instantiate --parse inside a nixos/nix container. That confirms the syntax and — the part most likely to break — that the shell hook's ''${...} escaping resolves to literal shell expansions rather than Nix interpolations.

What that does not cover: actually evaluating the derivation or entering the shell, which needs a macOS host with Nix installed. @kriswill validated the original shell end-to-end and posted a transcript; this version is that shell minus the libgit2/pkg-config wiring, so the untested delta is a deletion. If anyone with Nix on macOS wants to confirm nix develop .#cross before this merges, I'd welcome it.

`nix develop .#cross` on macOS exposes the OTHER darwin architecture's
zlib, so `scripts/build.sh --arch <target>` can link an x86_64 binary on
Apple Silicon and vice versa. The native clang already cross-emits object
code via -arch; zlib is the product's single link-time dependency, and the
host-arch copy cannot satisfy a cross link, which is the whole gap.

Darwin-gated and opt-in: the attribute set is empty on Linux, the default
shell is untouched, flake.lock is unchanged and no new flake input is
introduced. The shell deliberately does not use inputsFrom, since that
would put the host-arch zlib back on the link path.

Distilled from #724 by Kris Williams. That version also wired libgit2 via
pkg-config, which is now dead weight: libgit2 was removed project-wide for
GPL-licensing reasons and appears nowhere in the tree, so both it and
pkg-config are dropped here — leaving zlib as the only library the cross
shell needs to place.

Validated by parsing the flake with nix-instantiate in a nixos/nix
container (no Nix toolchain on the maintainer host), which also confirms
the shellHook's ''${...} escaping resolves to literal shell expansions.
Evaluating or entering the shell needs a macOS host with Nix; no CI leg
exercises it, as noted on the original PR.

Addresses #705.

Co-authored-by: Kris Williams <115474+kriswill@users.noreply.github.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
@DeusData
DeusData enabled auto-merge August 20, 2026 11:09
@DeusData
DeusData merged commit edfc2de into main Aug 20, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant