Minimal canadian cross example

I have been trying to learn more about the architecture of nixpkgs, including cross compilation. I gave myself to try to do the classic Canadian cross, where build != host != target.

I think it would be nice if we could have a minimal example of how to do a Canadian cross, but I was unable to find anyone online succeeding at it. So to get concrete, lets try to compile a aarch64 → riscv64 compiler on x86.

I can get a x86 → aarch64 crosscompiler from my host like this

pkgs.pkgsCross.aarch64-multiplatform.buildPackages.gcc

But I am unable to figure out how to get a canadian cross. I tried things like this

pkgs.pkgsCross.aarch64-multiplatform.pkgsCross.riscv64.pkgsBuildTarget.gcc
pkgs.pkgsCross.aarch64-multiplatform.pkgsCross.riscv64.pkgsHostTarget.gcc

but then the gcc ELF file is either x86 or riscv. Never aarch64.

Somebody got a working example or some hints here?

My thinking is that in GCC land this should be simple. We just need to pass --host=aarch64 and --target=riscv right? So why is so much more complicated in nixpkgs?

I’m a part of the stdenv team so I’m sort of aware of what’s going on. When you use cross compilation in nix, it uses the boostrap and then builds up a compiler in a similar fashion to make things not point to the host. This means it happens in stages. At least this is how I’ve interpreted it.

We’re actually working on redesigning GCC to be split up. This means you will have to build more but it opens the door for us to get GCC to function similar to Clang where it is a multitarget compiler. This means you will only compile GCC once. We’re also staging improvements on the stdenv and CC wrapper. It is possible much of these changes will likely help you out.

The issue you’ve also seen with stacking pkgsCross is something we’re also looking into improving. The current problem is when you apply it, it overrides the current target platform which means it doesn’t stack. It only overwrites the target.

2 Likes

Thanks for the info!

Just FYI I have no actual use case for this. I was just playing around and kind of expected nixpkgs to be able to do things like this, since it talked about so much in the manual, but never demonstrated in practice.