Hi all! I’m wrestling with a situation in which something I’d like to package demands a Canadian cross compilation (the
target machines all differ from one-another). Presently, I understand how to use Nixpkgs in the simpler case where either
build = host or
host = target, as well as (I think) the use of
pkgsXY in Nixpkgs and
Y are one of
Target). This leaves me feeling tantalizingly close to a solution, but I’m having a difficult time figuring out how to do this idiomatically.
I get the impression in some places that Nixpkgs wants to avoid the direct
(build, host, target) situation by having the “sliding window” mentioned in the docs evolve along the following lines.
(build, build, build) (build, build, host) (build, host, host) (host, host, host) (host, host, target)
This seems plausible since you can then pluck the desired
(host, target)-configured package from the last stage in that list (assuming you have a
host system to use as a second build system, I think).
Unfortunately, my package depends extensively on others at build time which are not able to be built to run on
host. In other words, it is critical that, at different times, the package be able to refer to all of the components of these triples, while all of them are different.
What I can’t figure out is how to use Nixpkgs to this effect. The
depsXY construct used in packages are suggestive (to me) that this is an intended use, but how does one instantiate a Nixpkgs with a
stdenv with differing
From what I’ve been able to discern, the Nixpkgs top-level limits you to specifying two systems:
crossSystem, corresponding to the left and right side of the “sliding window” respectively. If those are set to platforms other than one’s own (what would be the
build platform), no amount of sliding the window to the left (via
pkgsBuildBuild, etc.) brings one back to the intended
build system—Nixpkgs is stuck at what was meant to be
I do think I could hack a derivation together that builds the particular output that I’m interested in by instantiating Nixpkgs twice, one with
crossSystem set to
host, and one with it set to
target, and then pulling what I need from each of those. Along these lines, I could perhaps extend
pkgsCross with the needed platforms so that I can reference these packages from within a single Nixpkgs instantiation. Maybe slightly better would be to define a function that takes a target platform, and then after instantiating Nixpkgs with
crossSystem set to
host, pulling the desired package by passing
target as the argument. I suppose I’m slightly worried that this is conceptually wrong and will come back to bite me somehow down the line.
The manual mentions:
Conversely if one wishes to cross compile “faster”, with a “Canadian Cross” bootstrapping stage where
build != host != target, more bootstrapping stages are needed since no sliding window provides the pesky
pkgsBuildTargetpackage set since it skips the Canadian cross stage’s “host”.
I’ve looked at the machinery handling
stdenv’s bootstrapping stages, and the above makes me feel like there should be something I can do to manipulate these somehow to achieve the desired effect. The custom stage, for instance, takes a
replaceStdenv attribute from
config, which almost sounds like what I want, but I think it’s meant for other purposes.
Any ideas and input are much appreciated! Hoping to learn the idiomatic solution, if one exists, plus any other adjacent tricks that might prove useful in the future.