Merge pull request #29418 from vanschelven/small-documentation-improvements
documentation: cross-compilation - partial rewrite
This commit is contained in:
		
						commit
						350a5e31fc
					
				@ -11,7 +11,7 @@
 | 
			
		||||
    For example, a typical use of cross compilation is to compile programs for embedded devices.
 | 
			
		||||
    These devices often don't have the computing power and memory to compile their own programs.
 | 
			
		||||
    One might think that cross-compilation is a fairly niche concern, but there are advantages to being rigorous about distinguishing build-time vs run-time environments even when one is developing and deploying on the same machine.
 | 
			
		||||
    Nixpkgs is increasingly adopting this opinion in that packages should be written with cross-compilation in mind, and nixpkgs should evaluate in a similar way (by minimizing cross-compilation-specific special cases) whether or not one is cross-compiling.
 | 
			
		||||
    Nixpkgs is increasingly adopting the opinion that packages should be written with cross-compilation in mind, and nixpkgs should evaluate in a similar way (by minimizing cross-compilation-specific special cases) whether or not one is cross-compiling.
 | 
			
		||||
  </para>
 | 
			
		||||
 | 
			
		||||
  <para>
 | 
			
		||||
@ -30,11 +30,11 @@
 | 
			
		||||
  <section>
 | 
			
		||||
    <title>Platform parameters</title>
 | 
			
		||||
    <para>
 | 
			
		||||
      The three GNU Autoconf platforms, <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>target</wordasword>, are historically the result of much confusion.
 | 
			
		||||
      <link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html" /> clears this up somewhat but there is more to be said.
 | 
			
		||||
      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.
 | 
			
		||||
      Dealing with just two platforms usually better matches people's preconceptions, and in this case is completely correct.
 | 
			
		||||
      Nixpkgs follows the <link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html">common historical convention of GNU autoconf</link> of distinguishing between 3 types of platform: <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>target</wordasword>.
 | 
			
		||||
 | 
			
		||||
      In summary, <wordasword>build</wordasword> is the platform on which a package is being built, <wordasword>host</wordasword> is the platform on which it is to run. The third attribute, <wordasword>target</wordasword>, is relevant only for certain specific compilers and build tools.
 | 
			
		||||
    </para>
 | 
			
		||||
 | 
			
		||||
    <para>
 | 
			
		||||
      In Nixpkgs, these three platforms are defined as attribute sets under the names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>, and <literal>targetPlatform</literal>.
 | 
			
		||||
      All three are always defined as attributes in the standard environment, and at the top level. That means one can get at them just like a dependency in a function that is imported with <literal>callPackage</literal>:
 | 
			
		||||
@ -52,7 +52,7 @@
 | 
			
		||||
      <varlistentry>
 | 
			
		||||
        <term><varname>hostPlatform</varname></term>
 | 
			
		||||
        <listitem><para>
 | 
			
		||||
          The "host platform" is the platform on which a package is run.
 | 
			
		||||
          The "host platform" is the platform on which a package will be run.
 | 
			
		||||
          This is the simplest platform to understand, but also the one with the worst name.
 | 
			
		||||
        </para></listitem>
 | 
			
		||||
      </varlistentry>
 | 
			
		||||
@ -60,22 +60,24 @@
 | 
			
		||||
        <term><varname>targetPlatform</varname></term>
 | 
			
		||||
        <listitem>
 | 
			
		||||
          <para>
 | 
			
		||||
            The "target platform" is black sheep.
 | 
			
		||||
            The other two intrinsically apply to all compiled software—or any build process with a notion of "build-time" followed by "run-time".
 | 
			
		||||
            The target platform only applies to programming tools, and even then only is a good for for some of them.
 | 
			
		||||
            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.
 | 
			
		||||
            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.
 | 
			
		||||
            The "target platform" attribute is, unlike the other two attributes, not actually fundamental to the process of building software.
 | 
			
		||||
            Instead, it is only relevant for compatability with building certain specific compilers and build tools.
 | 
			
		||||
            It can be safely ignored for all other packages.
 | 
			
		||||
          </para>
 | 
			
		||||
          <para>
 | 
			
		||||
            There is no fundamental need to think about the target ahead of time like this.
 | 
			
		||||
            LLVM, for example, was designed from the beginning with cross-compilation in mind, and so a normal LLVM binary will support every architecture that LLVM supports.
 | 
			
		||||
            If the tool supports modular or pluggable backends, one might imagine specifying a <emphasis>set</emphasis> of target platforms / backends one wishes to support, rather than a single one.
 | 
			
		||||
            The build process of certain compilers is written in such a way that the compiler resulting from a single build can itself only produce binaries for a single platform.
 | 
			
		||||
            The task specifying this single "target platform" is thus pushed to build time of the compiler.
 | 
			
		||||
            The root cause of this mistake is often that the compiler (which will be run on the host) and the the standard library/runtime (which will be run on the target) are built by a single build process.
 | 
			
		||||
          </para>
 | 
			
		||||
          <para>
 | 
			
		||||
            The biggest reason for mess, if there is one, is that many compilers have the bad habit a build process that builds the compiler and standard library/runtime together.
 | 
			
		||||
            Then the specifying target platform is essential, because it determines the host platform of the standard library/runtime.
 | 
			
		||||
            Nixpkgs tries to avoid this where possible too, but still, because the concept of a target platform is so ingrained now in Autoconf and other tools, it is best to support it as is.
 | 
			
		||||
            Tools like LLVM that don't need up-front target platforms can safely ignore it like normal packages, and it will do no harm.
 | 
			
		||||
            There is no fundamental need to think about a single target ahead of time like this.
 | 
			
		||||
            If the tool supports modular or pluggable backends, both the need to specify the target at build time and the constraint of having only a single target disappear.
 | 
			
		||||
            An example of such a tool is LLVM.
 | 
			
		||||
          </para>
 | 
			
		||||
          <para>
 | 
			
		||||
            Although the existance of a "target platfom" is arguably a historical mistake, it is a common one: examples of tools that suffer from it are GCC, Binutils, GHC and Autoconf.
 | 
			
		||||
            Nixpkgs tries to avoid sharing in the mistake where possible.
 | 
			
		||||
            Still, because the concept of a target platform is so ingrained, it is best to support it as is.
 | 
			
		||||
          </para>
 | 
			
		||||
        </listitem>
 | 
			
		||||
      </varlistentry>
 | 
			
		||||
@ -155,14 +157,22 @@
 | 
			
		||||
  <section>
 | 
			
		||||
    <title>Specifying Dependencies</title>
 | 
			
		||||
    <para>
 | 
			
		||||
      As mentioned in the introduction to this chapter, one can think about a build time vs run time distinction whether cross-compiling or not.
 | 
			
		||||
      In the case of cross-compilation, this corresponds with whether a derivation running on the native or foreign platform is produced.
 | 
			
		||||
      An interesting thing to think about is how this corresponds with the three Autoconf platforms.
 | 
			
		||||
      In the run-time case, the depending and depended-on package simply have matching build, host, and target platforms.
 | 
			
		||||
      But in the build-time case, one can imagine "sliding" the platforms one over.
 | 
			
		||||
      The depended-on package's host and target platforms (respectively) become the depending package's build and host platforms.
 | 
			
		||||
      This is the most important guiding principle behind cross-compilation with Nixpkgs, and will be called the <wordasword>sliding window principle</wordasword>.
 | 
			
		||||
      In this section we explore the relationship between both runtime and buildtime dependencies and the 3 Autoconf platforms.
 | 
			
		||||
    </para>
 | 
			
		||||
    <para>
 | 
			
		||||
      A runtime dependency between 2 packages implies that between them both the host and target platforms match.
 | 
			
		||||
      This is directly implied by the meaning of "host platform" and "runtime dependency":
 | 
			
		||||
      The package dependency exists while both packages are runnign on a single host platform.
 | 
			
		||||
    </para>
 | 
			
		||||
    <para>
 | 
			
		||||
      A build time dependency, however, implies a shift in platforms between the depending package and the depended-on package.
 | 
			
		||||
      The meaning of a build time dependency is that to build the depending package we need to be able to run the depended-on's package.
 | 
			
		||||
      The depending package's build platform is therefore equal to the depended-on package's host platform.
 | 
			
		||||
      Analogously, the depending package's host platform is equal to the depended-on package's target platform.
 | 
			
		||||
    </para>
 | 
			
		||||
    <para>
 | 
			
		||||
      In this manner, given the 3 platforms for one package, we can determine the three platforms for all its transitive dependencies.
 | 
			
		||||
      This is the most important guiding principle behind cross-compilation with Nixpkgs, and will be called the <wordasword>sliding window principle</wordasword>.
 | 
			
		||||
    </para>
 | 
			
		||||
    <para>
 | 
			
		||||
      Some examples will probably make this clearer.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user