mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 16:26:18 +02:00
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>"powerpc-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 integers 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 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 <xref linkend='sec-standard-environment'
|
|||
|
/>.</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>
|