I’m currently tinkering with cross-compiling NixOS from an AMD machine (“x86_64-linux”) to Raspberry Pi 5 (“aarch64-linux”) and Starfive VisionFive 2 (“riscv-linux”), and would like to know about the latest best practice to recommend in guides. I found several similar styles, but i’m not sure which one is the latest and best:
I have sometimes also have seem both system and config having been defined.
So which one is the latest, recommended way? (Or what are the trade-offs?). I could create a PR against the official documentation as well if you can point me to the right place.
Shameless bump as i stumbled upon this part-hilarious blog post https://ianthehenry.com/posts/how-to-learn-nix/cross-compilation/ about the state of the Nix manual on cross-compiling and it describes the same questions and confusion i have. I would like to improve the documentation and start with this low-hanging fruit here.
{
# This is the architecture we build from (pkgs.system from above)
nixpkgs.buildPlatform = builtins.currentSystem;
# pkgsCross.<yourtarget>.system
nixpkgs.hostPlatform = "aarch64-linux";
}
but you have to pass --impure but i’m not sure otherwise how to make a nixosConfiguration that I can either build on my laptop or on my raspberry pi. I feel like I’m missin gsomething.
I haven’t decided. I’m still waiting for some Nix experts to give recommendations. I think i remember all variants working, but it’s confusing for non-experts as every guide is slightly different.
That’s because, as with many things in Nix, there isn’t one proven best way of doing things. If you ask 4 experts, you’ll get 4 opinions on how things should be done.
I wish there was a way to search for specific hydra built images and inspect the sources for all those artifacts. I am hoping this could help me overcome my current armv7l cross compilation issues.
Don’t take my word as gospel since it’s been a while since I touched this topic. Here is an implicit way to cross compile with flakes (don’t ask me why this works).
The only argument I can give for this method is that it looks clean.
As a blob of general knowledge I can add that cross-compiled derivations have a slightly different output because the compiler does slightly different things depending on instruction set. This is the reason cross-compiled derivations are impure?! and means when the target system wants to rebuild it will rebuild everything.
Instruction level emulation (binfmt) of the native compiler avoids this, at the cost of massively reduced speed.
These lines do nothing in your code, and this is not cross-compiling. Probably you’re using emulated compilation. If you want to cross compile, one way would be to do this: