about summary refs log tree commit diff
path: root/doc/manual/expressions/derivations.xml
blob: 90e2786faaab1e0d18865d2ebf8bc3d9e1ea7af9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
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>"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 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>