git-subtree-dir: third_party/nix
git-subtree-mainline: cf8cd640c1
git-subtree-split: be66c7a6b24e3c3c6157fd37b86c7203d14acf10
		
	
			
		
			
				
	
	
		
			119 lines
		
	
	
		
			No EOL
		
	
	
		
			4.7 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			No EOL
		
	
	
		
			4.7 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
<section xmlns="http://docbook.org/ns/docbook"
 | 
						|
      xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
						|
      xmlns:xi="http://www.w3.org/2001/XInclude"
 | 
						|
      version="5.0"
 | 
						|
      xml:id='sec-build-script'>
 | 
						|
 | 
						|
<title>Build Script</title>
 | 
						|
 | 
						|
<example xml:id='ex-hello-builder'><title>Build script for GNU Hello
 | 
						|
(<filename>builder.sh</filename>)</title>
 | 
						|
<programlisting>
 | 
						|
source $stdenv/setup <co xml:id='ex-hello-builder-co-1' />
 | 
						|
 | 
						|
PATH=$perl/bin:$PATH <co xml:id='ex-hello-builder-co-2' />
 | 
						|
 | 
						|
tar xvfz $src <co xml:id='ex-hello-builder-co-3' />
 | 
						|
cd hello-*
 | 
						|
./configure --prefix=$out <co xml:id='ex-hello-builder-co-4' />
 | 
						|
make <co xml:id='ex-hello-builder-co-5' />
 | 
						|
make install</programlisting>
 | 
						|
</example>
 | 
						|
 | 
						|
<para><xref linkend='ex-hello-builder' /> shows the builder referenced
 | 
						|
from Hello's Nix expression (stored in
 | 
						|
<filename>pkgs/applications/misc/hello/ex-1/builder.sh</filename>).
 | 
						|
The builder can actually be made a lot shorter by using the
 | 
						|
<emphasis>generic builder</emphasis> functions provided by
 | 
						|
<varname>stdenv</varname>, but here we write out the build steps to
 | 
						|
elucidate what a builder does.  It performs the following
 | 
						|
steps:</para>
 | 
						|
 | 
						|
<calloutlist>
 | 
						|
 | 
						|
  <callout arearefs='ex-hello-builder-co-1'>
 | 
						|
 | 
						|
    <para>When Nix runs a builder, it initially completely clears the
 | 
						|
    environment (except for the attributes declared in the
 | 
						|
    derivation).  For instance, the <envar>PATH</envar> variable is
 | 
						|
    empty<footnote><para>Actually, it's initialised to
 | 
						|
    <filename>/path-not-set</filename> to prevent Bash from setting it
 | 
						|
    to a default value.</para></footnote>.  This is done to prevent
 | 
						|
    undeclared inputs from being used in the build process.  If for
 | 
						|
    example the <envar>PATH</envar> contained
 | 
						|
    <filename>/usr/bin</filename>, then you might accidentally use
 | 
						|
    <filename>/usr/bin/gcc</filename>.</para>
 | 
						|
 | 
						|
    <para>So the first step is to set up the environment.  This is
 | 
						|
    done by calling the <filename>setup</filename> script of the
 | 
						|
    standard environment.  The environment variable
 | 
						|
    <envar>stdenv</envar> points to the location of the standard
 | 
						|
    environment being used.  (It wasn't specified explicitly as an
 | 
						|
    attribute in <xref linkend='ex-hello-nix' />, but
 | 
						|
    <varname>mkDerivation</varname> adds it automatically.)</para>
 | 
						|
 | 
						|
  </callout>
 | 
						|
 | 
						|
  <callout arearefs='ex-hello-builder-co-2'>
 | 
						|
 | 
						|
    <para>Since Hello needs Perl, we have to make sure that Perl is in
 | 
						|
    the <envar>PATH</envar>.  The <envar>perl</envar> environment
 | 
						|
    variable points to the location of the Perl package (since it
 | 
						|
    was passed in as an attribute to the derivation), so
 | 
						|
    <filename><replaceable>$perl</replaceable>/bin</filename> is the
 | 
						|
    directory containing the Perl interpreter.</para>
 | 
						|
 | 
						|
  </callout>
 | 
						|
 | 
						|
  <callout arearefs='ex-hello-builder-co-3'>
 | 
						|
 | 
						|
    <para>Now we have to unpack the sources.  The
 | 
						|
    <varname>src</varname> attribute was bound to the result of
 | 
						|
    fetching the Hello source tarball from the network, so the
 | 
						|
    <envar>src</envar> environment variable points to the location in
 | 
						|
    the Nix store to which the tarball was downloaded.  After
 | 
						|
    unpacking, we <command>cd</command> to the resulting source
 | 
						|
    directory.</para>
 | 
						|
 | 
						|
    <para>The whole build is performed in a temporary directory
 | 
						|
    created in <varname>/tmp</varname>, by the way.  This directory is
 | 
						|
    removed after the builder finishes, so there is no need to clean
 | 
						|
    up the sources afterwards.  Also, the temporary directory is
 | 
						|
    always newly created, so you don't have to worry about files from
 | 
						|
    previous builds interfering with the current build.</para>
 | 
						|
 | 
						|
  </callout>
 | 
						|
 | 
						|
  <callout arearefs='ex-hello-builder-co-4'>
 | 
						|
 | 
						|
    <para>GNU Hello is a typical Autoconf-based package, so we first
 | 
						|
    have to run its <filename>configure</filename> script.  In Nix
 | 
						|
    every package is stored in a separate location in the Nix store,
 | 
						|
    for instance
 | 
						|
    <filename>/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1</filename>.
 | 
						|
    Nix computes this path by cryptographically hashing all attributes
 | 
						|
    of the derivation.  The path is passed to the builder through the
 | 
						|
    <envar>out</envar> environment variable.  So here we give
 | 
						|
    <filename>configure</filename> the parameter
 | 
						|
    <literal>--prefix=$out</literal> to cause Hello to be installed in
 | 
						|
    the expected location.</para>
 | 
						|
 | 
						|
  </callout>
 | 
						|
 | 
						|
  <callout arearefs='ex-hello-builder-co-5'>
 | 
						|
 | 
						|
    <para>Finally we build Hello (<literal>make</literal>) and install
 | 
						|
    it into the location specified by <envar>out</envar>
 | 
						|
    (<literal>make install</literal>).</para>
 | 
						|
 | 
						|
  </callout>
 | 
						|
 | 
						|
</calloutlist>
 | 
						|
 | 
						|
<para>If you are wondering about the absence of error checking on the
 | 
						|
result of various commands called in the builder: this is because the
 | 
						|
shell script is evaluated with Bash's <option>-e</option> option,
 | 
						|
which causes the script to be aborted if any command fails without an
 | 
						|
error check.</para>
 | 
						|
 | 
						|
</section> |