diff options
Diffstat (limited to 'doc/manual/expressions/derivations.xml')
-rw-r--r-- | doc/manual/expressions/derivations.xml | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/doc/manual/expressions/derivations.xml b/doc/manual/expressions/derivations.xml new file mode 100644 index 000000000000..5efe2213e370 --- /dev/null +++ b/doc/manual/expressions/derivations.xml @@ -0,0 +1,211 @@ +<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> |