summary refs log tree commit diff
path: root/doc/stdenv/cross-compilation.chapter.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/stdenv/cross-compilation.chapter.md')
-rw-r--r--doc/stdenv/cross-compilation.chapter.md35
1 files changed, 19 insertions, 16 deletions
diff --git a/doc/stdenv/cross-compilation.chapter.md b/doc/stdenv/cross-compilation.chapter.md
index 3755c13facf..53522962a5c 100644
--- a/doc/stdenv/cross-compilation.chapter.md
+++ b/doc/stdenv/cross-compilation.chapter.md
@@ -6,7 +6,6 @@
 
 This chapter will be organized in three parts. First, it will describe the basics of how to package software in a way that supports cross-compilation. Second, it will describe how to use Nixpkgs when cross-compiling. Third, it will describe the internal infrastructure supporting cross-compilation.
 
-
 ## Packaging in a cross-friendly manner {#sec-cross-packaging}
 
 ### Platform parameters {#ssec-cross-platform-parameters}
@@ -65,8 +64,8 @@ The exact schema these fields follow is a bit ill-defined due to a long and conv
 
 ### Theory of dependency categorization {#ssec-cross-dependency-categorization}
 
-::: note
-This is a rather philosophical description that isn't very Nixpkgs-specific. For an overview of all the relevant attributes given to `mkDerivation`, see <xref linkend="ssec-stdenv-dependencies"/>. For a description of how everything is implemented, see <xref linkend="ssec-cross-dependency-implementation"/>.
+::: {.note}
+This is a rather philosophical description that isn't very Nixpkgs-specific. For an overview of all the relevant attributes given to `mkDerivation`, see [](#ssec-stdenv-dependencies). For a description of how everything is implemented, see [](#ssec-cross-dependency-implementation).
 :::
 
 In this section we explore the relationship between both runtime and build-time dependencies and the 3 Autoconf platforms.
@@ -81,10 +80,10 @@ Finally, if the depending package is a compiler or other machine-code-producing
 
 Putting this all together, that means we have dependencies in the form "host → target", in at most the following six combinations:
 
+#### Possible dependency types {#possible-dependency-types}
 
-#### Possible dependency types
-| Dependency's host platform | Dependency's target platform |
-| --                         | --                           |
+| Dependency’s host platform | Dependency’s target platform |
+|----------------------------|------------------------------|
 | build                      | build                        |
 | build                      | host                         |
 | build                      | target                       |
@@ -113,15 +112,18 @@ On less powerful machines, it can be inconvenient to cross-compile a package onl
 $ nix-build '<nixpkgs>' -A pkgsCross.raspberryPi.hello
 ```
 
-#### What if my package's build system needs to build a C program to be run under the build environment? {#cross-qa-build-c-program-in-build-environment}
+#### What if my package’s build system needs to build a C program to be run under the build environment? {#cross-qa-build-c-program-in-build-environment}
+
 Add the following to your `mkDerivation` invocation.
+
 ```nix
 depsBuildBuild = [ buildPackages.stdenv.cc ];
 ```
 
-####  My package's testsuite needs to run host platform code. {#cross-testsuite-runs-host-code}
+#### My package’s testsuite needs to run host platform code. {#cross-testsuite-runs-host-code}
 
 Add the following to your `mkDerivation` invocation.
+
 ```nix
 doCheck = stdenv.hostPlatform == stdenv.buildPlatform;
 ```
@@ -134,7 +136,7 @@ Nixpkgs can be instantiated with `localSystem` alone, in which case there is no
 $ nix-build '<nixpkgs>' --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz' -A whatever
 ```
 
-::: note
+::: {.note}
 Eventually we would like to make these platform examples an unnecessary convenience so that
 
 ```ShellSession
@@ -146,7 +148,7 @@ works in the vast majority of cases. The problem today is dependencies on other
 
 While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields. As discussed in the previous section, only one of `system`, `config`, and `parsed` is needed to infer the other two. Additionally, `libc` will be inferred from `parse`. Finally, `localSystem.system` is also _impurely_ inferred based on the platform evaluation occurs. This means it is often not necessary to pass `localSystem` at all, as in the command-line example in the previous paragraph.
 
-::: note
+::: {.note}
 Many sources (manual, wiki, etc) probably mention passing `system`, `platform`, along with the optional `crossSystem` to Nixpkgs: `import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }`. Passing those two instead of `localSystem` is still supported for compatibility, but is discouraged. Indeed, much of the inference we do for these parameters is motivated by compatibility as much as convenience.
 :::
 
@@ -156,7 +158,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 <xref linkend="ssec-cross-dependency-categorization"/> are specified as lists of derivations given to `mkDerivation`, as documented in <xref linkend="ssec-stdenv-dependencies"/>. In short, each list of dependencies for "host → target" of "foo → bar" is called `depsFooBar`, with exceptions for backwards compatibility that `depsBuildHost` is instead called `nativeBuildInputs` and `depsHostTarget` is instead called `buildInputs`. Nixpkgs is now structured so that each `depsFooBar` is automatically taken from `pkgsFooBar`. (These `pkgsFooBar`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" of "foo → bar" is called `depsFooBar`, with exceptions for backwards compatibility that `depsBuildHost` is instead called `nativeBuildInputs` and `depsHostTarget` is instead called `buildInputs`. Nixpkgs is now structured so that each `depsFooBar` is automatically taken from `pkgsFooBar`. (These `pkgsFooBar`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 `pkgsFooBar` 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.
 
@@ -178,7 +180,7 @@ While there are many package sets, and thus many edges, the stages can also be a
 
 In each stage, `pkgsBuildHost` refers to the previous stage, `pkgsBuildBuild` refers to the one before that, and `pkgsHostTarget` refers to the current one, and `pkgsTargetTarget` refers to the next one. When there is no previous or next stage, they instead refer to the current stage. Note how all the invariants regarding the mapping between dependency and depending packages' build host and target platforms are preserved. `pkgsBuildTarget` and `pkgsHostHost` are more complex in that the stage fitting the requirements isn't always a fixed chain of "prevs" and "nexts" away (modulo the "saturating" self-references at the ends). We just special case each instead. All the primary edges are implemented is in `pkgs/stdenv/booter.nix`, and secondarily aliases in `pkgs/top-level/stage.nix`.
 
-::: note
+::: {.note}
 The native stages are bootstrapped in legacy ways that predate the current cross implementation. This is why the bootstrapping stages leading up to the final stages are ignored in the previous paragraph.
 :::
 
@@ -186,6 +188,7 @@ If one looks at the 3 platform triples, one can see that they overlap such that
 ```
 (native, native, native, foreign, foreign)
 ```
+
 If one imagines the saturating self references at the end being replaced with infinite stages, and then overlays those platform triples, one ends up with the infinite tuple:
 ```
 (native..., native, native, native, foreign, foreign, foreign...)
@@ -193,8 +196,8 @@ If one imagines the saturating self references at the end being replaced with in
 One can then imagine any sequence of platforms such that there are bootstrap stages with their 3 platforms determined by "sliding a window" that is the 3 tuple through the sequence. This was the original model for bootstrapping. Without a target platform (assume a better world where all compilers are multi-target and all standard libraries are built in their own derivation), this is sufficient. Conversely if one wishes to cross compile "faster", with a "Canadian Cross" bootstrapping stage where `build != host != target`, more bootstrapping stages are needed since no sliding window provides the pesky `pkgsBuildTarget` package set since it skips the Canadian cross stage's "host".
 
 
-::: note
-It is much better to refer to `buildPackages` than `targetPackages`, or more broadly package sets that do not mention "target". There are three reasons for this.
+::: {.note}
+It is much better to refer to `buildPackages` than `targetPackages`, or more broadly package sets that do not mention “target”. There are three reasons for this.
 
 First, it is because bootstrapping stages do not have a unique `targetPackages`. For example a `(x86-linux, x86-linux, arm-linux)` and `(x86-linux, x86-linux, x86-windows)` package set both have a `(x86-linux, x86-linux, x86-linux)` package set. Because there is no canonical `targetPackages` for such a native (`build == host == target`) package set, we set their `targetPackages`
 
@@ -203,6 +206,6 @@ Second, it is because this is a frequent source of hard-to-follow "infinite recu
 Thirdly, it is because everything target-mentioning only exists to accommodate compilers with lousy build systems that insist on the compiler itself and standard library being built together. Of course that is bad because bigger derivations means longer rebuilds. It is also problematic because it tends to make the standard libraries less like other libraries than they could be, complicating code and build systems alike. Because of the other problems, and because of these innate disadvantages, compilers ought to be packaged another way where possible.
 :::
 
-::: note
-If one explores Nixpkgs, they will see derivations with names like `gccCross`. Such `*Cross` derivations is a holdover from before we properly distinguished between the host and target platforms—the derivation with "Cross" in the name covered the `build = host != target` case, while the other covered the `host = target`, with build platform the same or not based on whether one was using its `.nativeDrv` or `.crossDrv`. This ugliness will disappear soon.
+::: {.note}
+If one explores Nixpkgs, they will see derivations with names like `gccCross`. Such `*Cross` derivations is a holdover from before we properly distinguished between the host and target platforms—the derivation with “Cross” in the name covered the `build = host != target` case, while the other covered the `host = target`, with build platform the same or not based on whether one was using its `.nativeDrv` or `.crossDrv`. This ugliness will disappear soon.
 :::