211 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
	
		
			9 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="ssec-derivation">
 | 
						||
 | 
						||
<title>Derivations</title>
 | 
						||
 | 
						||
<para>The most important built-in function is
 | 
						||
<function>derivation</function>, which is used to describe a single
 | 
						||
derivation (a build action).  It takes as input a set, the attributes
 | 
						||
of which specify the inputs of the build.</para>
 | 
						||
 | 
						||
<itemizedlist>
 | 
						||
 | 
						||
  <listitem xml:id="attr-system"><para>There must be an attribute named
 | 
						||
  <varname>system</varname> whose value must be a string specifying a
 | 
						||
  Nix platform identifier, such as <literal>"i686-linux"</literal> or
 | 
						||
  <literal>"x86_64-darwin"</literal><footnote><para>To figure out
 | 
						||
  your platform identifier, look at the line <quote>Checking for the
 | 
						||
  canonical Nix system name</quote> in the output of Nix's
 | 
						||
  <filename>configure</filename> script.</para></footnote> The build
 | 
						||
  can only be performed on a machine and operating system matching the
 | 
						||
  platform identifier.  (Nix can automatically forward builds for
 | 
						||
  other platforms by forwarding them to other machines; see <xref
 | 
						||
  linkend='chap-distributed-builds' />.)</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>There must be an attribute named
 | 
						||
  <varname>name</varname> whose value must be a string.  This is used
 | 
						||
  as a symbolic name for the package by <command>nix-env</command>,
 | 
						||
  and it is appended to the output paths of the
 | 
						||
  derivation.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>There must be an attribute named
 | 
						||
  <varname>builder</varname> that identifies the program that is
 | 
						||
  executed to perform the build.  It can be either a derivation or a
 | 
						||
  source (a local file reference, e.g.,
 | 
						||
  <filename>./builder.sh</filename>).</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>Every attribute is passed as an environment variable
 | 
						||
  to the builder.  Attribute values are translated to environment
 | 
						||
  variables as follows:
 | 
						||
 | 
						||
    <itemizedlist>
 | 
						||
 | 
						||
      <listitem><para>Strings and numbers are just passed
 | 
						||
      verbatim.</para></listitem>
 | 
						||
 | 
						||
      <listitem><para>A <emphasis>path</emphasis> (e.g.,
 | 
						||
      <filename>../foo/sources.tar</filename>) causes the referenced
 | 
						||
      file to be copied to the store; its location in the store is put
 | 
						||
      in the environment variable.  The idea is that all sources
 | 
						||
      should reside in the Nix store, since all inputs to a derivation
 | 
						||
      should reside in the Nix store.</para></listitem>
 | 
						||
 | 
						||
      <listitem><para>A <emphasis>derivation</emphasis> causes that
 | 
						||
      derivation to be built prior to the present derivation; its
 | 
						||
      default output path is put in the environment
 | 
						||
      variable.</para></listitem>
 | 
						||
 | 
						||
      <listitem><para>Lists of the previous types are also allowed.
 | 
						||
      They are simply concatenated, separated by
 | 
						||
      spaces.</para></listitem>
 | 
						||
 | 
						||
      <listitem><para><literal>true</literal> is passed as the string
 | 
						||
      <literal>1</literal>, <literal>false</literal> and
 | 
						||
      <literal>null</literal> are passed as an empty string.
 | 
						||
      </para></listitem>
 | 
						||
    </itemizedlist>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The optional attribute <varname>args</varname>
 | 
						||
  specifies command-line arguments to be passed to the builder.  It
 | 
						||
  should be a list.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The optional attribute <varname>outputs</varname>
 | 
						||
  specifies a list of symbolic outputs of the derivation.  By default,
 | 
						||
  a derivation produces a single output path, denoted as
 | 
						||
  <literal>out</literal>.  However, derivations can produce multiple
 | 
						||
  output paths.  This is useful because it allows outputs to be
 | 
						||
  downloaded or garbage-collected separately.  For instance, imagine a
 | 
						||
  library package that provides a dynamic library, header files, and
 | 
						||
  documentation.  A program that links against the library doesn’t
 | 
						||
  need the header files and documentation at runtime, and it doesn’t
 | 
						||
  need the documentation at build time.  Thus, the library package
 | 
						||
  could specify:
 | 
						||
<programlisting>
 | 
						||
outputs = [ "lib" "headers" "doc" ];
 | 
						||
</programlisting>
 | 
						||
  This will cause Nix to pass environment variables
 | 
						||
  <literal>lib</literal>, <literal>headers</literal> and
 | 
						||
  <literal>doc</literal> to the builder containing the intended store
 | 
						||
  paths of each output.  The builder would typically do something like
 | 
						||
<programlisting>
 | 
						||
./configure --libdir=$lib/lib --includedir=$headers/include --docdir=$doc/share/doc
 | 
						||
</programlisting>
 | 
						||
  for an Autoconf-style package.  You can refer to each output of a
 | 
						||
  derivation by selecting it as an attribute, e.g.
 | 
						||
<programlisting>
 | 
						||
buildInputs = [ pkg.lib pkg.headers ];
 | 
						||
</programlisting>
 | 
						||
  The first element of <varname>output</varname> determines the
 | 
						||
  <emphasis>default output</emphasis>.  Thus, you could also write
 | 
						||
<programlisting>
 | 
						||
buildInputs = [ pkg pkg.headers ];
 | 
						||
</programlisting>
 | 
						||
  since <literal>pkg</literal> is equivalent to
 | 
						||
  <literal>pkg.lib</literal>.</para></listitem>
 | 
						||
 | 
						||
</itemizedlist>
 | 
						||
 | 
						||
<para>The function <function>mkDerivation</function> in the Nixpkgs
 | 
						||
standard environment is a wrapper around
 | 
						||
<function>derivation</function> that adds a default value for
 | 
						||
<varname>system</varname> and always uses Bash as the builder, to
 | 
						||
which the supplied builder is passed as a command-line argument.  See
 | 
						||
the Nixpkgs manual for details.</para>
 | 
						||
 | 
						||
<para>The builder is executed as follows:
 | 
						||
 | 
						||
<itemizedlist>
 | 
						||
 | 
						||
  <listitem><para>A temporary directory is created under the directory
 | 
						||
  specified by <envar>TMPDIR</envar> (default
 | 
						||
  <filename>/tmp</filename>) where the build will take place.  The
 | 
						||
  current directory is changed to this directory.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The environment is cleared and set to the derivation
 | 
						||
  attributes, as specified above.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>In addition, the following variables are set:
 | 
						||
 | 
						||
  <itemizedlist>
 | 
						||
 | 
						||
    <listitem><para><envar>NIX_BUILD_TOP</envar> contains the path of
 | 
						||
    the temporary directory for this build.</para></listitem>
 | 
						||
 | 
						||
    <listitem><para>Also, <envar>TMPDIR</envar>,
 | 
						||
    <envar>TEMPDIR</envar>, <envar>TMP</envar>, <envar>TEMP</envar>
 | 
						||
    are set to point to the temporary directory.  This is to prevent
 | 
						||
    the builder from accidentally writing temporary files anywhere
 | 
						||
    else.  Doing so might cause interference by other
 | 
						||
    processes.</para></listitem>
 | 
						||
 | 
						||
    <listitem><para><envar>PATH</envar> is set to
 | 
						||
    <filename>/path-not-set</filename> to prevent shells from
 | 
						||
    initialising it to their built-in default value.</para></listitem>
 | 
						||
 | 
						||
    <listitem><para><envar>HOME</envar> is set to
 | 
						||
    <filename>/homeless-shelter</filename> to prevent programs from
 | 
						||
    using <filename>/etc/passwd</filename> or the like to find the
 | 
						||
    user's home directory, which could cause impurity.  Usually, when
 | 
						||
    <envar>HOME</envar> is set, it is used as the location of the home
 | 
						||
    directory, even if it points to a non-existent
 | 
						||
    path.</para></listitem>
 | 
						||
 | 
						||
    <listitem><para><envar>NIX_STORE</envar> is set to the path of the
 | 
						||
    top-level Nix store directory (typically,
 | 
						||
    <filename>/nix/store</filename>).</para></listitem>
 | 
						||
 | 
						||
    <listitem><para>For each output declared in
 | 
						||
    <varname>outputs</varname>, the corresponding environment variable
 | 
						||
    is set to point to the intended path in the Nix store for that
 | 
						||
    output.  Each output path is a concatenation of the cryptographic
 | 
						||
    hash of all build inputs, the <varname>name</varname> attribute
 | 
						||
    and the output name.  (The output name is omitted if it’s
 | 
						||
    <literal>out</literal>.)</para></listitem>
 | 
						||
 | 
						||
  </itemizedlist>
 | 
						||
 | 
						||
  </para></listitem>
 | 
						||
 | 
						||
  <listitem><para>If an output path already exists, it is removed.
 | 
						||
  Also, locks are acquired to prevent multiple Nix instances from
 | 
						||
  performing the same build at the same time.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>A log of the combined standard output and error is
 | 
						||
  written to <filename>/nix/var/log/nix</filename>.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The builder is executed with the arguments specified
 | 
						||
  by the attribute <varname>args</varname>.  If it exits with exit
 | 
						||
  code 0, it is considered to have succeeded.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>The temporary directory is removed (unless the
 | 
						||
  <option>-K</option> option was specified).</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>If the build was successful, Nix scans each output
 | 
						||
  path for references to input paths by looking for the hash parts of
 | 
						||
  the input paths.  Since these are potential runtime dependencies,
 | 
						||
  Nix registers them as dependencies of the output
 | 
						||
  paths.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para>After the build, Nix sets the last-modified
 | 
						||
  timestamp on all files in the build result to 1 (00:00:01 1/1/1970
 | 
						||
  UTC), sets the group to the default group, and sets the mode of the
 | 
						||
  file to 0444 or 0555 (i.e., read-only, with execute permission
 | 
						||
  enabled if the file was originally executable).  Note that possible
 | 
						||
  <literal>setuid</literal> and <literal>setgid</literal> bits are
 | 
						||
  cleared.  Setuid and setgid programs are not currently supported by
 | 
						||
  Nix.  This is because the Nix archives used in deployment have no
 | 
						||
  concept of ownership information, and because it makes the build
 | 
						||
  result dependent on the user performing the build.</para></listitem>
 | 
						||
 | 
						||
</itemizedlist>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
<xi:include href="advanced-attributes.xml" />
 | 
						||
 | 
						||
</section>
 |