Hi all! I’m wrestling with a situation in which something I’d like to package demands a Canadian cross compilation (the build
, host
, and 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 depsXY
in stdenv
(where X
and Y
are one of Build
, Host
, or 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 buildPlatform
, hostPlatform
, and targetPlatform
?
From what I’ve been able to discern, the Nixpkgs top-level limits you to specifying two systems: system
/localSystem
, and 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 buildPackages
, pkgsBuildBuild
, etc.) brings one back to the intended build
system—Nixpkgs is stuck at what was meant to be host
.
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:
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.