To OP: just set extra-platforms
and since you have binfmt-misc
set up, I expect it will just work.
To Valentin: There are a few errata in your post.
You could try pkgsCross
by following the cross-compilation tutorial.
pkgsCross
is the incorrect approach for cross-building NixOS specifically (unless you use pkgsCross.blah.nixos
as an entry point, but that’s extremely obscure, doesn’t work with non-flakes, and is not the clean way to do it).
The reason for this is that you either need a native-arch builder (such as by setting extra-platforms
and using binfmt-misc
or having a native machine), or you need to fully cross-build the system, since you need to be able to build any arbitrary derivation required by the system, which, for NixOS, will not all be in cache; thus, you need to import nixpkgs with the right architecture settings, which can be achieved by setting the nixpkgs.*
NixOS options.
The correct approach to build a non-native NixOS architecture to set system
in the nixosSystem
invocation to aarch64-linux
in the case of native-building with emulation (or indeed, not set it/set it to null
and then set nixpkgs.system
). For cross-building from x86_64-linux, set nixpkgs.buildPlatform
and nixpkgs.hostPlatform
and don’t pass system
.
jade’s post may need some corrections in the overview and the section on cross-compilation.
Nope. I just don’t bother mentioning how to actually do the cross compilation in there, just how to support it as a downstream flake, which is perhaps an omission, but the post is 5k words long already. The point with suggesting overlays there is making it possible to “bring your own pkgs”. That’s the entire reason.
A workaround would be to set extra-platforms = aarch64_linux
in nix.conf
on Ubuntu
Yep, and set up binfmt-misc properly with the Ubuntu package; should be easy enough. I believe the extra-platforms
is the only thing that the original poster is actually missing, and their config would just work then.
You could even set it inside your flake with nixConfig
, I suppose. For remote build machines, you can set up the Nix builders config file, or you can use --build-machine
of nixos-rebuild
which will uhhh do a shitload of extremely unsurprising crimes involving nix eval
, nix copy
and nix-store -r
to avoid the Nix remote build protocol, probably because it is really slow on non-local connections.
A full example of a command to (cross, or otherwise) build a flake based NixOS configuration locally and deploy it to another machine is:
NIX_SSHOPTS="-l root" nixos-rebuild switch --target-host YOUR_HOSTNAME --fast --flake .#yourConfig
One very embarrassing docs omission in the NixOS docs and arguably nix.dev
is that it doesn’t mention anywhere in the manual to use --fast
on nixos-rebuild
, which is necessary for cross building a config, since otherwise it will try to re-exec Nix of the wrong architecture.
An alternative would be to use niv
for dependency management
This is basically irrelevant to the question at hand, and I would argue that flakes are much more pleasant to use for NixOS since you can control the entry point to your configuration. But you could use this. It wouldn’t change the cross compilation steps, you just would have to use -I nixos-config=./mymachine.nix
and then uhhhhhhhhh write a bad nixos-rebuild
wrapper script to nix-instantiate --eval
the store path out of npins
/niv
, then pass it as -I nixpkgs=/nix/store/....
. I don’t particularly wonder why most people use flakes instead of doing this.