Unverified Commit 1ba8a6db authored by Aleksana's avatar Aleksana Committed by GitHub
Browse files

doc: align formatting in dependency type tables (#448875)

parents 9bd1fcd8 69c7504a
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ If both the dependency and depending packages aren't compilers or other machine-

Finally, if the depending package is a compiler or other machine-code-producing tool, it might need dependencies that run at "emit time". This is for compilers that (regrettably) insist on being built together with their source languages' standard libraries. Assuming build != host != target, a run-time dependency of the standard library cannot be run at the compiler's build time or run time, but only at the run time of code emitted by the compiler.

Putting this all together, that means that we have dependency types of the form "X→ E", which means that the dependency executes on X and emits code for E; each of X and E can be `build`, `host`, or `target`, and E can be `*` to indicate that the dependency is not a compiler-like package.
Putting this all together, that means that we have dependency types of the form `X → E`, which means that the dependency executes on `X` and emits code for `E`; each of `X` and `E` can be `build`, `host`, or `target`, and `E` can be `*` to indicate that the dependency is not a compiler-like package.

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`.

@@ -95,16 +95,16 @@ 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                       |
|-------------------|----------------------------|------------------------------|
| `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.

@@ -235,7 +235,7 @@ One would think that `localSystem` and `crossSystem` overlap horribly with the t

### Implementation of dependencies {#ssec-cross-dependency-implementation}

The categories of dependencies developed in [](#ssec-cross-dependency-categorization) are specified as lists of derivations given to `mkDerivation`, as documented in [](#ssec-stdenv-dependencies). In short, each list of dependencies for "host → target" is called `deps<host><target>` (where `host`, and `target` values are either `build`, `host`, or `target`), with exceptions for backwards compatibility that `depsBuildHost` is instead called `nativeBuildInputs` and `depsHostTarget` is instead called `buildInputs`. Nixpkgs is now structured so that each `deps<host><target>` is automatically taken from `pkgs<host><target>`. (These `pkgs<host><target>`s are quite new, so there is no special case for `nativeBuildInputs` and `buildInputs`.) For example, `pkgsBuildHost.gcc` should be used at build-time, while `pkgsHostTarget.gcc` should be used at run-time.
The categories of dependencies developed in [](#ssec-cross-dependency-categorization) are specified as lists of derivations given to `mkDerivation`, as documented in [](#ssec-stdenv-dependencies). In short, each list of dependencies for `host → target` is called `deps<host><target>` (where `host`, and `target` values are either `build`, `host`, or `target`), with exceptions for backwards compatibility that `depsBuildHost` is instead called `nativeBuildInputs` and `depsHostTarget` is instead called `buildInputs`. Nixpkgs is now structured so that each `deps<host><target>` is automatically taken from `pkgs<host><target>`. (These `pkgs<host><target>`s are quite new, so there is no special case for `nativeBuildInputs` and `buildInputs`.) For example, `pkgsBuildHost.gcc` should be used at build-time, while `pkgsHostTarget.gcc` should be used at run-time.

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.

+8 −8
Original line number Diff line number Diff line
@@ -327,14 +327,14 @@ Dependency propagation takes cross compilation into account, meaning that depend

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](#possible-dependency-types), 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 obtained:

| `host → target`     | attribute name      | offset   | typical purpose                               |
| ------------------- | ------------------- | -------- | --------------------------------------------- |
| `build --> build`   | `depsBuildBuild`    | `-1, -1` | compilers for build helpers                   |
| `build --> host`    | `nativeBuildInputs` | `-1, 0`  | build tools, compilers, setup hooks           |
| `build --> target`  | `depsBuildTarget`   | `-1, 1`  | compilers to build stdlibs to run on target   |
| `host --> host`     | `depsHostHost`      | `0, 0`   | compilers to build C code at runtime (rare)   |
| `host --> target`   | `buildInputs`       | `0, 1`   | libraries                                     |
| `target --> target` | `depsTargetTarget`  | `1, 1`   | stdlibs to run on target                      |
| Dependency type   | attribute name      | offset   | typical purpose                               |
| ----------------- | ------------------- | -------- | --------------------------------------------- |
| `build  build`   | `depsBuildBuild`    | `-1, -1` | compilers for build helpers                   |
| `build  host`    | `nativeBuildInputs` | `-1, 0`  | build tools, compilers, setup hooks           |
| `build  target`  | `depsBuildTarget`   | `-1, 1`  | compilers to build stdlibs to run on target   |
| `host  host`     | `depsHostHost`      | `0, 0`   | compilers to build C code at runtime (rare)   |
| `host  target`   | `buildInputs`       | `0, 1`   | libraries                                     |
| `target  target` | `depsTargetTarget`  | `1, 1`   | stdlibs to run on target                      |

Algorithmically, we traverse propagated inputs, accumulating every propagated dependency’s propagated dependencies and adjusting them to account for the “shift in perspective” described by the current dependency’s platform offsets. This results in a sort of transitive closure of the dependency relation, with the offsets being approximately summed when two dependency links are combined. We also prune transitive dependencies whose combined offsets go out-of-bounds, which can be viewed as a filter over that transitive closure removing dependencies that are blatantly absurd.