|
30 | 30 | <section>
|
31 | 31 | <title>Platform parameters</title>
|
32 | 32 | <para>
|
33 |
| - The three GNU Autoconf platforms, <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>cross</wordasword>, are historically the result of much confusion. |
| 33 | + The three GNU Autoconf platforms, <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>target</wordasword>, are historically the result of much confusion. |
34 | 34 | <link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html" /> clears this up somewhat but there is more to be said.
|
35 | 35 | An important advice to get out the way is, unless you are packaging a compiler or other build tool, just worry about the build and host platforms.
|
36 | 36 | Dealing with just two platforms usually better matches people's preconceptions, and in this case is completely correct.
|
|
62 | 62 | The "target platform" is black sheep.
|
63 | 63 | The other two intrinsically apply to all compiled software—or any build process with a notion of "build-time" followed by "run-time".
|
64 | 64 | The target platform only applies to programming tools, and even then only is a good for for some of them.
|
65 |
| - Briefly, GCC, Binutils, GHC, and certain other tools are written in such a way such that a single build can only compiler code for a single platform. |
66 |
| - Thus, when building them, one must think ahead about what platforms they wish to use the tool to produce machine code for, and build binaries for each. |
| 65 | + Briefly, GCC, Binutils, GHC, and certain other tools are written in such a way such that a single build can only compile code for a single platform. |
| 66 | + Thus, when building them, one must think ahead about which platforms they wish to use the tool to produce machine code for, and build binaries for each. |
67 | 67 | </para>
|
68 | 68 | <para>
|
69 | 69 | There is no fundamental need to think about the target ahead of time like this.
|
|
85 | 85 | This field is obsolete and will soon disappear—please do not use it.
|
86 | 86 | </para></note>
|
87 | 87 | <para>
|
88 |
| - The exact scheme these fields is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up. |
| 88 | + The exact schema these fields follow is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up. |
| 89 | + You can see examples of ones used in practice in <literal>lib.systems.examples</literal>; note how they are not all very consistent. |
89 | 90 | For now, here are few fields can count on them containing:
|
90 | 91 | </para>
|
91 | 92 | <variablelist>
|
|
118 | 119 | This is a nix representation of a parsed LLVM target triple with white-listed components.
|
119 | 120 | This can be specified directly, or actually parsed from the <varname>config</varname>.
|
120 | 121 | [Technically, only one need be specified and the others can be inferred, though the precision of inference may not be very good.]
|
121 |
| - See <literal>lib.systems.parse</literal> for the exact representation, along with some <literal>is*</literal>predicates. |
122 |
| - These predicates are superior to the ones in <varname>stdenv</varname> as they aren't tied to the build platform (host, as previously discussed, would be a saner default). |
| 122 | + See <literal>lib.systems.parse</literal> for the exact representation. |
| 123 | + </para> |
| 124 | + </listitem> |
| 125 | + </varlistentry> |
| 126 | + <varlistentry> |
| 127 | + <term><varname>libc</varname></term> |
| 128 | + <listitem> |
| 129 | + <para> |
| 130 | + This is a string identifying the standard C library used. |
| 131 | + Valid identifiers include "glibc" for GNU libc, "libSystem" for Darwin's Libsystem, and "uclibc" for µClibc. |
| 132 | + It should probably be refactored to use the module system, like <varname>parse</varname>. |
| 133 | + </para> |
| 134 | + </listitem> |
| 135 | + </varlistentry> |
| 136 | + <varlistentry> |
| 137 | + <term><varname>is*</varname></term> |
| 138 | + <listitem> |
| 139 | + <para> |
| 140 | + These predicates are defined in <literal>lib.systems.inspect</literal>, and slapped on every platform. |
| 141 | + They are superior to the ones in <varname>stdenv</varname> as they force the user to be explicit about which platform they are inspecting. |
| 142 | + Please use these instead of those. |
123 | 143 | </para>
|
124 | 144 | </listitem>
|
125 | 145 | </varlistentry>
|
|
128 | 148 | <listitem>
|
129 | 149 | <para>
|
130 | 150 | This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set).
|
131 |
| - See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform one is working. |
| 151 | + See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform that is working. |
132 | 152 | Please help us triage these flags and give them better homes!
|
133 | 153 | </para>
|
134 | 154 | </listitem>
|
|
158 | 178 | The depending package's target platform is unconstrained by the sliding window principle, which makes sense in that one can in principle build cross compilers targeting arbitrary platforms.
|
159 | 179 | </para></note>
|
160 | 180 | <para>
|
161 |
| - How does this work in practice? Nixpkgs is now structured so that build-time dependencies are taken from from <varname>buildPackages</varname>, whereas run-time dependencies are taken from the top level attribute set. |
| 181 | + How does this work in practice? Nixpkgs is now structured so that build-time dependencies are taken from <varname>buildPackages</varname>, whereas run-time dependencies are taken from the top level attribute set. |
162 | 182 | For example, <varname>buildPackages.gcc</varname> should be used at build time, while <varname>gcc</varname> should be used at run time.
|
163 | 183 | Now, for most of Nixpkgs's history, there was no <varname>buildPackages</varname>, and most packages have not been refactored to use it explicitly.
|
164 |
| - Instead, one can use the four attributes used for specifying dependencies as documented in <link linkend="ssec-stdenv-attributes" />. |
| 184 | + Instead, one can use the four attributes used for specifying dependencies as documented in <xref linkend="ssec-stdenv-attributes"/>. |
165 | 185 | We "splice" together the run-time and build-time package sets with <varname>callPackage</varname>, and then <varname>mkDerivation</varname> for each of four attributes pulls the right derivation out.
|
166 | 186 | This splicing can be skipped when not cross compiling as the package sets are the same, but is a bit slow for cross compiling.
|
167 | 187 | Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
|
|
184 | 204 | More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section.
|
185 | 205 | </para></note>
|
186 | 206 | <para>
|
187 |
| - Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, and, optionally, <varname>crossSystem</varname> to nixpkgs: |
188 |
| - <literal>import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }</literal>. |
189 |
| - <varname>system</varname> and <varname>platform</varname> together determine the system on which packages are built, and <varname>crossSystem</varname> specifies the platform on which packages are ultimately intended to run, if it is different. |
190 |
| - This still works, but with more recent changes, one can alternatively pass <varname>localSystem</varname>, containing <varname>system</varname> and <varname>platform</varname>, for symmetry. |
| 207 | + Nixpkgs can be instantiated with <varname>localSystem</varname> alone, in which case there is no cross compiling and everything is built by and for that system, |
| 208 | + or also with <varname>crossSystem</varname>, in which case packages run on the latter, but all building happens on the former. |
| 209 | + Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section. |
| 210 | + As mentioned above, <literal>lib.systems.examples</literal> has some platforms which are used as arguments for these parameters in practice. |
| 211 | + You can use them programmatically, or on the command line like <command>nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz'</command>. |
191 | 212 | </para>
|
| 213 | + <para> |
| 214 | + While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields. |
| 215 | + As discussed in the previous section, only one of <varname>system</varname>, <varname>config</varname>, and <varname>parsed</varname> is needed to infer the other two. |
| 216 | + Additionally, <varname>libc</varname> will be inferred from <varname>parse</varname>. |
| 217 | + Finally, <literal>localSystem.system</literal> is also <emphasis>impurely</emphasis> inferred based on the platform evaluation occurs. |
| 218 | + This means it is often not necessary to pass <varname>localSystem</varname> at all, as in the command-line example in the previous paragraph. |
| 219 | + </para> |
| 220 | + <note> |
| 221 | + <para> |
| 222 | + Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, along with the optional <varname>crossSystem</varname> to nixpkgs: |
| 223 | + <literal>import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }</literal>. |
| 224 | + Passing those two instead of <varname>localSystem</varname> is still supported for compatibility, but is discouraged. |
| 225 | + Indeed, much of the inference we do for these parameters is motivated by compatibility as much as convenience. |
| 226 | + </para> |
| 227 | + </note> |
192 | 228 | <para>
|
193 | 229 | One would think that <varname>localSystem</varname> and <varname>crossSystem</varname> overlap horribly with the three <varname>*Platforms</varname> (<varname>buildPlatform</varname>, <varname>hostPlatform,</varname> and <varname>targetPlatform</varname>; see <varname>stage.nix</varname> or the manual).
|
194 | 230 | Actually, those identifiers are purposefully not used here to draw a subtle but important distinction:
|
|
0 commit comments