Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,57 @@
let
systems = [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});

# Cross dev shell (macOS only): build the *other* darwin arch locally.
# The native clang already cross-emits object code via -arch (scripts/env.sh
# exports ARCHFLAGS), so the only thing missing for a cross link is zlib:
# it is the product's single link-time dependency (`-lz`), and the host-arch
# copy cannot satisfy an x86_64 link on arm64 or vice versa. This shell puts
# the TARGET-arch zlib on the include and link paths, and nothing else.
#
# Building needs no Rosetta; *running* an x86_64 binary on Apple Silicon
# does. The target-arch libs come from prebuilt substitutes, so entering the
# shell is a download rather than a cross-build of the dependency tree.
#
# Returns {} off macOS, where there is no second darwin arch to target.
crossDevShells = pkgs:
let
inherit (nixpkgs) lib;
crossTarget =
{
"aarch64-darwin" = "x86_64-darwin";
"x86_64-darwin" = "aarch64-darwin";
}
.${pkgs.system} or null;
mkCrossShell =
targetSystem:
let
tpkgs = nixpkgs.legacyPackages.${targetSystem};
targetArch = if targetSystem == "x86_64-darwin" then "x86_64" else "arm64";
in
pkgs.mkShell {
# Host toolchain only — clang comes from the shell stdenv. Deliberately
# NOT inputsFrom the default package: that would put the HOST-arch zlib
# on the link path, which is exactly the wrong-arch copy this shell
# exists to displace.
nativeBuildInputs = [ pkgs.gnumake ];
shellHook = ''
# zlib is consumed as a bare `-lz` / `#include <zlib.h>`, so its
# include dir (the header is arch-independent) and lib dir are
# supplied by hand. NIX_LDFLAGS is searched ahead of the link's own
# -L, so the target-arch slice wins; a host-arch copy that still
# reaches ld is skipped as "wrong architecture" rather than
# producing a silently mislinked binary.
export NIX_CFLAGS_COMPILE="-I${lib.getDev tpkgs.zlib}/include ''${NIX_CFLAGS_COMPILE:-}"
export NIX_LDFLAGS="-L${lib.getLib tpkgs.zlib}/lib ''${NIX_LDFLAGS:-}"
echo "[cross] target ${targetSystem} — build with: scripts/build.sh --arch ${targetArch}"
'';
};
in
lib.optionalAttrs (crossTarget != null) {
# `nix develop .#cross` then `scripts/build.sh --arch <target>`.
cross = mkCrossShell crossTarget;
};
in
{
packages = forAllSystems (pkgs: {
Expand Down Expand Up @@ -45,6 +96,6 @@
default = pkgs.mkShell {
inputsFrom = [ self.packages.${pkgs.system}.default ];
};
});
} // crossDevShells pkgs);
};
}
Loading