How should this table of dependencies be read?

Nixpkgs 23.05 manual | Nix & NixOS says

A dependency is said to be propagated when some of its
other-transitive (non-immediate) downstream dependencies also need it
as an immediate dependency. [3]

It is important to note that dependencies are not necessarily
propagated as the same sort of dependency that they were before, but
rather as the corresponding sort so that the platform rules still line
up. To determine the exact rules for dependency propagation, we start
by assigning to each dependency a couple of ternary numbers (-1 for
build, 0 for host, and 1 for target) representing its dependency type,
which captures how its host and target platforms are each “offset”
from the depending derivation’s host and target platforms. The
following table summarize the different combinations that can be

host → target		attribute name		offset
build --> build		depsBuildBuild		-1, -1
build --> host		nativeBuildInputs	-1, 0
build --> target	depsBuildTarget		-1, 1
host --> host		depsHostHost		0, 0
host --> target		buildInputs			0, 1
target --> target	depsTargetTarget	1, 1

I was wondering how to read the table?

What do the arrows in “host → target” and “build → build” mean?

How are the offsets calculated?

I’ve needed that bit of documentation a couple times and have done cross several times and I can tell you: No clue.

First, let’s elaborate the platforms:

  • buildPlatform: The platform that builds the drv. If you’re cross-compiling from x86 to arm, it’d be x86.
  • hostPlatform: The platform on which the result of the drv will run. In the same case, it’d be arm.
  • targetPlatform: The platform for which the result of the drv will produce code for when ran. This matters if you are building a cross-compiler. Let’s say you want to build a compiler that runs on arm but produces risv binaries. In this case the hostPlatform would be arm and the target platform riscv.

You could complicate that example further and cross-compile the arm → riscv compiler from x86. In this case all 3 platforms would be different.

I believe this is where the offsets come from; how far you are into this chain. From the perspective of the drv result, the buildPlatform is the platform “before” and the targetPlatform is the “next” platform but I’m not certain on that.

I can explain what the arrows mean with relatively good certainty though:

Left side is on which platform the dep’s code will run and on the right is which platform the dep will produce code for.

With nativeBuildInputs, it runs on the buildPlatform and produces code for the hostPlatform. bash, make, cmake, pkg-config, meson etc. fall into this category; they execute during the build and produce executable code (i.e. app binary) which runs on the hostPlatform.

buildInputs can only run on the hostPlatform and will produce code for the targetPlatform. These are your typical library .sos. They don’t really “run” during a build, so the only thing that matters is that they can be linked into targetPlatform binaries.
(Note that the most common case, targetPlatform = hostPlatform.)

I hope that helps :slight_smile:

1 Like