I wrote a flake that has both x86_64-linux and aarch64-linux versions of the same package.
Now I would like to cross-compile that package for aarch64-linux on an x86_64-linux machine.
Is there a good way to do that?
None of the flags/options I saw in the wiki or elsewhere online seem to apply. Is there already a (convenient) way do do this, or is that functionality just not available yet?
to the configuration of my x86_64-linux build system.
As soon as I did that I was able to build my flake using
nix build .#defaultPackage.aarch64-linux
That worked like a charm! I even copied over the closure to verify that the result runs on the actual aarch64-linux target, and it does.
Just as a reference for others, before adding that option I only got the following error message:
nix build .#defaultPackage.aarch64-linux
warning: Git tree '/home/mschwaig/flakes/tensorflow-lite-hello-world' is dirty
error: --- Error ----------------------------------------------------- nix
a 'aarch64-linux' with features {} is required to build '/nix/store/my1h7yqcplmpihygkhq8s4i4syfcazpv-builder.pl.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
(use '--show-trace' to show detailed location information)
$ uname -a
Linux jon-desktop 5.4.142 #1-NixOS SMP Wed Aug 18 06:57:05 UTC 2021 x86_64 GNU/Linux
$ nix build nixpkgs#legacyPackages.x86_64-linux.pkgsCross.aarch64-multiplatform.hello
$ file ./result/bin/hello
./result/bin/hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /nix/store/zh8wdxlvbaycfnnd3c9hzq07h5x7blaw-glibc-aarch64-unknown-linux-gnu-2.33-47/lib/ld-linux-aarch64.so.1, for GNU/Linux 2.6.32, not stripped
Using boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; is still probably preferred, as the target system will likely expect to use aarch64 packages that were built on aarch64 (cross compilation produces different .drv’s). I’m not really sure how to “consume” cross compiled packages without referencing the store path directly.
means that you can do ‘real’ cross-compilation with Flakes, as an alternative to compiling under emulation. This seems helpful if you want to cross-compile a package from nixpkgs with the new nix command.
As far as I can see this only works with nxpkgs specifically and I don’t know what it would take to have any other Flake to offer an interface for cross-compilation like that. I have not read about anything like that yet.
@jonringer do you have an example of doing that? I am struggling to figure out how to get it to work based on my limited nix (and flake) experience, and I can’t seem to find any documentation showing how to do it with a flake.
The important thing here is that I used legacyPackages instead of packages as otherwise nix flake show would fail. This way I can list content with nix flake show . as well as do cross-compilation using nix build .#pkgsCross.aarch64-multiplatform.foo (as an example).
Is there a simple better way to do this? Adding overlay seems kinda hacky…
I am specifically looking to build a boot ISO for my raspberry Pi. So far I’ve been deploying to it using cross-compiling from my PC just fine, but for some reason ISO generation is getting overly complicated.
My flake expects that packages are defined in either directory pkgs or file pkgs.nix. If that is how you have it then make sure that it is part of git. Nix won’t include files outside of git in case of flake. This smells like you either do not have pkgs or is just ignored by nix.
@payas here’s an SD image that I made for Raspberry Pi in case that’s helpful to you:
I’m sharing it here because of how simple it is to specify. I’m fairly sure this is compiled under emulation and not cross-compiled. I’m also wondering what it would take to make cross-compilation similarly ergonomic, maybe it’s possible to write a nice function for that.
packages are defined in flakes using an overlay which is applied to the Nixpkgs set. This allows your packages to be cross-compiled in other flakes.
This also limits how i write overlays https://git.sr.ht/~ehmry/sigil/tree/post-mortem/item/overlay/default.nix
gemini://gemini.spam.works/~emery/sigil-report.gmi
At this point in time, flakes are designed to take away control of the nixpkgs invocation, while neglecting to support cross compilation and other Nixpkgs configuration.
By using overlays, you opt out of the way flakes suggest to do things, which is by using the inputs’ packages and legacyPackages attributes. This reduces your use of flakes to little more than a simple lock manager like niv, and you’ll be doing things the way we used to do them before flakes.
While I consider this a valid thing to do, I can’t call it “cross-compiling a flake” especially considering that you have to write your own flake in order to even invoke nixpkgs for cross compilation. True cross compilation support would allow any flake out there to be evaluated for cross compilation, without having to write your own. Barring any mistakes in the expressions or lack of cross support in packaged tools, this should just work.