Why is `buildPackages` aka `pkgsBuildHost` used in `depsBuildBuild` instead of `pkgsBuildBuild`

From the NixPkgs manual:

depsBuildBuild

A list of dependencies whose host and target platforms are the new derivation’s build platform. These are programs and libraries used at build time that produce programs and libraries also used at build time. If the dependency doesn’t care about the target platform (i.e. isn’t a compiler or similar tool), put it in nativeBuildInputs instead. The most common use of this buildPackages.stdenv.cc, the default C compiler for this role. That example crops up more than one might think in old commonly used C libraries.

https://nixos.org/manual/nixpkgs/unstable/#var-stdenv-depsBuildBuild

However:

Now, for most of Nixpkgs’s history, there were no pkgs<host><target> attributes, and most packages have not been refactored to use it explicitly. Prior to those, there were just buildPackages, pkgs, and targetPackages. Those are now redefined as aliases to pkgsBuildHost, pkgsHostTarget, and pkgsTargetTarget. It is acceptable, even recommended, to use them for libraries to show that the host platform is irrelevant.

https://nixos.org/manual/nixpkgs/unstable/#ssec-cross-dependency-implementation

So as far as I understand it we put packages that are supposed to run on the buildPlatform and produce binaries for the hostPlatform in the dependency list for packages that are supposed to run on and produce binaries for the buildPlatform.

Whattt?

And if we just put stdenv.cc into there, wouldn’t :sparkles:splicing :sparkles: just automatically select pkgsBuildBuild for us?

Answer by Emily <@emilazy:matrix.org>:

stdenv.cc is one level up.
stdenv.cc is build→host, buildPackages.stdenv.cc is build→build.
Yes this is confusing.

Splicing doesn’t work for stdenv.cc because it’s not a top-level package I guess. And also because of the thing where it’s “one level up”. (I don’t know, splicing is black magic and/or a mess)
think of it as “pkgSet.stdenv.cc is the compiler you use to build pkgSet.whatever

you write

{ stdenv, … }: stdenv.mkDerivation …

to produce a package that builds on stdenv.buildPlatform and runs on stdenv.hostPlatform so stdenv.mkDerivation has to know what compiler to use for build→host, and that’s stdenv.cc.

buildPackages is pkgsBuildHost, so buildPackages.stdenv.hostPlatform == stdenv.buildPlatform.

(and buildPackages.stdenv.buildPlatform == stdenv.buildPlatform, since it “bottoms out” there)

Therefore buildPackages.stdenv.cc is the build→build compiler, that is used to compile e.g. buildPackages.hello.

hopefully that makes it a bit clearer :slight_smile:

(the other confusing thing is that in pkgsFooBar, Bar is never relevant unless the package is a compiler. targetPlatform usually means nothing.
IOW, pkgsBuildBuild.hello is the same as pkgsBuildHost.hello and so on; it’s pkgsBuildBuild.gcc and pkgsBuildHost.gcc that differ)

1 Like