Home Explore Blog CI



nixpkgs

4th chunk of `doc/stdenv/cross-compilation.chapter.md`
ab3e7c7a6526878007eccaa06a1d534573fcb30480ad6ff500000001000010f3
Dependency types describe the relationships that a package has with each of its transitive dependencies.  You could think of attaching one or more dependency types to each of the formal parameters at the top of a package's `.nix` file, as well as to all of *their* formal parameters, and so on.   Triples like `(foo, bar, baz)`, on the other hand, are a property of an instantiated derivation -- you could would attach a triple `(mips-linux, mips-linux, sparc-solaris)` to a `.drv` file in `/nix/store`.

Only nine dependency types matter in practice:

#### Possible dependency types {#possible-dependency-types}

| Dependency type | Dependency’s host platform | Dependency’s target platform |
|-----------------|----------------------------|------------------------------|
| build → *       | build                      | (none)                       |
| build → build   | build                      | build                        |
| build → host    | build                      | host                         |
| build → target  | build                      | target                       |
| host → *        | host                       | (none)                       |
| host → host     | host                       | host                         |
| host → target   | host                       | target                       |
| target → *      | target                     | (none)                       |
| target → target | target                     | target                       |

Let's use `g++` as an example to make this table clearer.  `g++` is a C++ compiler written in C.  Suppose we are building `g++` with a `(build, host, target)` platform triple of `(foo, bar, baz)`.  This means we are using a `foo`-machine to build a copy of `g++` which will run on a `bar`-machine and emit binaries for the `baz`-machine.

* `g++` links against the host platform's `glibc` C library, which is a "host→ *" dependency with a triple of `(bar, bar, *)`.  Since it is a library, not a compiler, it has no "target".

* Since `g++` is written in C, the `gcc` compiler used to compile it is a "build→ host" dependency of `g++` with a triple of `(foo, foo, bar)`.  This compiler runs on the build platform and emits code for the host platform.

* `gcc` links against the build platform's `glibc` C library, which is a "build→ *" dependency with a triple of `(foo, foo, *)`.  Since it is a library, not a compiler, it has no "target".

* This `gcc` is itself compiled by an *earlier* copy of `gcc`.  This earlier copy of `gcc` is a "build→ build" dependency of `g++` with a triple of `(foo, foo, foo)`.  This "early `gcc`" runs on the build platform and emits code for the build platform.

* `g++` is bundled with `libgcc`, which includes a collection of target-machine routines for exception handling and
software floating point emulation.  `libgcc` would be a "target→ *" dependency with triple `(foo, baz, *)`, because it consists of machine code which gets linked against the output of the compiler that we are building.  It is a library, not a compiler, so it has no target of its own.

* `libgcc` is written in C and compiled with `gcc`.  The `gcc` that compiles it will be a "build→ target" dependency with triple `(foo, foo, baz)`.  It gets compiled *and run* at `g++`-build-time (on platform `foo`), but must emit code for the `baz`-platform.

* `g++` allows inline assembler code, so it depends on access to a copy of the `gas` assembler.  This would be a "host→ target" dependency with triple `(foo, bar, baz)`.

* `g++` (and `gcc`) include a library `libgccjit.so`, which wrap the compiler in a library to create a just-in-time compiler.  In nixpkgs, this library is in the `libgccjit` package; if C++ required that programs have access to a JIT, `g++` would need to add a "target→ target" dependency for `libgccjit` with triple `(foo, baz, baz)`.  This would ensure that the compiler ships with a copy of `libgccjit` which both executes on and generates code for the `baz`-platform.

* If `g++` itself linked against `libgccjit.so` (for example, to allow compile-time-evaluated C++ expressions), then the `libgccjit` package used to provide this functionality would be a "host→ host" dependency of `g++`: it is code which runs on the `host` and emits code for execution on the `host`.

Title: Possible Dependency Types and g++ Example
Summary
This section lists the nine dependency types that matter in practice, including their dependency's host and target platforms. It uses `g++` as an example to illustrate these dependency types, explaining how `g++` interacts with dependencies like `glibc`, `gcc`, and `libgcc`, and showing their corresponding triples `(build, host, target)`. Each dependency type and triple is explained in the context of how it's used when building `g++`.