motivation
I have a set of steps to build a cross-compiled project (https://github.com/n64decomp/sm64). These steps require e.g. binutils targeting a MIPS platform like e.g. mips-linux-gnu. (Others like mips64-elf or mips64-linux-gnu are allegedly also supported by this project.)
-> I want to make a shell.nix file that, under nix-shell (or nix shell), generates an environment with cross-targeting binutils executables.
One more note: I am compiling on an M1 mac. However the project doesn't support building from aarm64-darwin, so I'm using x86_64-darwin as the build platform under the Rosetta2 compatibility layer.
attempt
I wrote a shell.nix like so:
{ pkgs ? import <nixpkgs> { # https://nixos.org/manual/nixpkgs/stable/#sec-cross-usage localSystem = (import <nixpkgs/lib>).systems.examples.x86_64-darwin; crossSystem = (import <nixpkgs/lib>).systems.examples.mips-linux-gnu; } }: pkgs.mkShell { # stuff I want at build-time # -> package host = project build # -> package target = project host # pulled from https://github.com/n64decomp/sm64#step-1-install-dependencies-1 nativeBuildInputs = [ # doesn't compile code -> no target pkgs.gnumake42 pkgs.coreutils pkgs.pkg-config # compiles -> target = mips-linux-gnu pkgs.binutils ]; shellHook = '' # some other setup commands... ''; } Running nix-shell and trying to use any of the dependencies (e.g., make) generates an error like cannot execute binary file: Exec format error. It seems like all the binaries are built to run on mips, not to build for mips.
I also tried to put these dependencies in buildInputs instead. Running the project build then generates the error
ld: archive has no table of contents file 'audiofile/libaudiofile.a' for architecture x86_64 Imo, this conversely makes it sound like the target for mips-unknown-linux-gnu-ld is x86_64, and NOT mips.
question
How do I rewrite this shell.nix file to specify packages that run on x86_64-darwin, and build for the target mips-linux-gnu?
EDIT: more info
I opened up a nix repl to check what build/host/target my shell would generate:
nix-repl> pkgs = import <nixpkgs> { localSystem = (import <nixpkgs/lib>).systems.examples.x86_64-darwin; crossSystem = (import <nixpkgs/lib>).systems.examples.mips-linux-gnu; } nix-repl> pkgs.stdenv.buildPlatform.config "x86_64-apple-darwin" nix-repl> pkgs.stdenv.hostPlatform.config "mips-unknown-linux-gnu" nix-repl> pkgs.stdenv.targetPlatform.config "mips-unknown-linux-gnu" It looks like my build platform is x86_64-darwin, and my host and target platforms are both mips-linux. This sounds right; I am using x86_64-darwin to build this project, and the resulting ROM runs on mips. (It doesn't generate other code, so the target is irrelevant.)
But nix-shell is used for development; when you run nix-shell derivation.nix, it drops you into the build sequence for the derivation. Thus the environment is on the build platform, right? But it seems here like nix-shell shell.nix is generating a host-platform environment. Why is that?