aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/expressions
diff options
context:
space:
mode:
authorMikey Ariel <mariel@redhat.com>2014-08-27 18:41:09 +0200
committerMikey Ariel <mariel@redhat.com>2014-08-27 18:41:09 +0200
commit8901acc97664aa8ebf687ee904428aa57a5192be (patch)
treef7bfefccbc2a08cc49eb37b424758a6158b29b58 /doc/manual/expressions
parent3f0a4bf0e7254edddaa864d23893d98da23c2977 (diff)
Restructuring the Nix manual
Diffstat (limited to 'doc/manual/expressions')
-rw-r--r--doc/manual/expressions/advanced-attributes.xml243
-rw-r--r--doc/manual/expressions/arguments-variables.xml121
-rw-r--r--doc/manual/expressions/build-script.xml119
-rw-r--r--doc/manual/expressions/builder-syntax.xml119
-rw-r--r--doc/manual/expressions/builtins.xml950
-rw-r--r--doc/manual/expressions/custom-builder.xml26
-rw-r--r--doc/manual/expressions/debug-build.xml33
-rw-r--r--doc/manual/expressions/derivations.xml211
-rw-r--r--doc/manual/expressions/expression-language.xml30
-rw-r--r--doc/manual/expressions/expression-syntax.xml148
-rw-r--r--doc/manual/expressions/generic-builder.xml98
-rw-r--r--doc/manual/expressions/language-constructs.xml344
-rw-r--r--doc/manual/expressions/language-operators.xml113
-rw-r--r--doc/manual/expressions/language-values.xml268
-rw-r--r--doc/manual/expressions/simple-building-testing.xml86
-rw-r--r--doc/manual/expressions/simple-expression.xml47
-rw-r--r--doc/manual/expressions/standard-env.xml60
-rw-r--r--doc/manual/expressions/writing-nix-expressions.xml27
18 files changed, 3043 insertions, 0 deletions
diff --git a/doc/manual/expressions/advanced-attributes.xml b/doc/manual/expressions/advanced-attributes.xml
new file mode 100644
index 000000000..40a5a80ac
--- /dev/null
+++ b/doc/manual/expressions/advanced-attributes.xml
@@ -0,0 +1,243 @@
+<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-advanced-attributes">
+
+<title>Advanced Attributes</title>
+
+<para>Derivations can declare some infrequently used optional
+attributes.</para>
+
+<variablelist>
+
+ <varlistentry><term><varname>allowedReferences</varname></term>
+
+ <listitem><para>The optional attribute
+ <varname>allowedReferences</varname> specifies a list of legal
+ references (dependencies) of the output of the builder. For
+ example,
+
+<programlisting>
+allowedReferences = [];
+</programlisting>
+
+ enforces that the output of a derivation cannot have any runtime
+ dependencies on its inputs. To allow an output to have a runtime
+ dependency on itself, use <literal>"out"</literal> as a list item.
+ This is used in NixOS to check that generated files such as
+ initial ramdisks for booting Linux don’t have accidental
+ dependencies on other paths in the Nix store.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><varname>exportReferencesGraph</varname></term>
+
+ <listitem><para>This attribute allows builders access to the
+ references graph of their inputs. The attribute is a list of
+ inputs in the Nix store whose references graph the builder needs
+ to know. The value of this attribute should be a list of pairs
+ <literal>[ <replaceable>name1</replaceable>
+ <replaceable>path1</replaceable> <replaceable>name2</replaceable>
+ <replaceable>path2</replaceable> <replaceable>...</replaceable>
+ ]</literal>. The references graph of each
+ <replaceable>pathN</replaceable> will be stored in a text file
+ <replaceable>nameN</replaceable> in the temporary build directory.
+ The text files have the format used by <command>nix-store
+ --register-validity</command> (with the deriver fields left
+ empty). For example, when the following derivation is built:
+
+<programlisting>
+derivation {
+ ...
+ exportReferencesGraph = [ "libfoo-graph" libfoo ];
+};
+</programlisting>
+
+ the references graph of <literal>libfoo</literal> is placed in the
+ file <filename>libfoo-graph</filename> in the temporary build
+ directory.</para>
+
+ <para><varname>exportReferencesGraph</varname> is useful for
+ builders that want to do something with the closure of a store
+ path. Examples include the builders in NixOS that generate the
+ initial ramdisk for booting Linux (a <command>cpio</command>
+ archive containing the closure of the boot script) and the
+ ISO-9660 image for the installation CD (which is populated with a
+ Nix store containing the closure of a bootable NixOS
+ configuration).</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry xml:id="fixed-output-drvs">
+ <term><varname>outputHash</varname></term>
+ <term><varname>outputHashAlgo</varname></term>
+ <term><varname>outputHashMode</varname></term>
+
+ <listitem><para>These attributes declare that the derivation is a
+ so-called <emphasis>fixed-output derivation</emphasis>, which
+ means that a cryptographic hash of the output is already known in
+ advance. When the build of a fixed-output derivation finishes,
+ Nix computes the cryptographic hash of the output and compares it
+ to the hash declared with these attributes. If there is a
+ mismatch, the build fails.</para>
+
+ <para>The rationale for fixed-output derivations is derivations
+ such as those produced by the <function>fetchurl</function>
+ function. This function downloads a file from a given URL. To
+ ensure that the downloaded file has not been modified, the caller
+ must also specify a cryptographic hash of the file. For example,
+
+<programlisting>
+fetchurl {
+ url = http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz;
+ md5 = "70c9ccf9fac07f762c24f2df2290784d";
+}
+</programlisting>
+
+ It sometimes happens that the URL of the file changes, e.g.,
+ because servers are reorganised or no longer available. We then
+ must update the call to <function>fetchurl</function>, e.g.,
+
+<programlisting>
+fetchurl {
+ url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
+ md5 = "70c9ccf9fac07f762c24f2df2290784d";
+}
+</programlisting>
+
+ If a <function>fetchurl</function> derivation was treated like a
+ normal derivation, the output paths of the derivation and
+ <emphasis>all derivations depending on it</emphasis> would change.
+ For instance, if we were to change the URL of the Glibc source
+ distribution in Nixpkgs (a package on which almost all other
+ packages depend) massive rebuilds would be needed. This is
+ unfortunate for a change which we know cannot have a real effect
+ as it propagates upwards through the dependency graph.</para>
+
+ <para>For fixed-output derivations, on the other hand, the name of
+ the output path only depends on the <varname>outputHash*</varname>
+ and <varname>name</varname> attributes, while all other attributes
+ are ignored for the purpose of computing the output path. (The
+ <varname>name</varname> attribute is included because it is part
+ of the path.)</para>
+
+ <para>As an example, here is the (simplified) Nix expression for
+ <varname>fetchurl</varname>:
+
+<programlisting>
+{ stdenv, curl }: # The <command>curl</command> program is used for downloading.
+
+{ url, md5 }:
+
+stdenv.mkDerivation {
+ name = baseNameOf (toString url);
+ builder = ./builder.sh;
+ buildInputs = [ curl ];
+
+ # This is a fixed-output derivation; the output must be a regular
+ # file with MD5 hash <varname>md5</varname>.
+ outputHashMode = "flat";
+ outputHashAlgo = "md5";
+ outputHash = md5;
+
+ inherit url;
+}
+</programlisting>
+
+ </para>
+
+ <para>The <varname>outputHashAlgo</varname> attribute specifies
+ the hash algorithm used to compute the hash. It can currently be
+ <literal>"md5"</literal>, <literal>"sha1"</literal> or
+ <literal>"sha256"</literal>.</para>
+
+ <para>The <varname>outputHashMode</varname> attribute determines
+ how the hash is computed. It must be one of the following two
+ values:
+
+ <variablelist>
+
+ <varlistentry><term><literal>"flat"</literal></term>
+
+ <listitem><para>The output must be a non-executable regular
+ file. If it isn’t, the build fails. The hash is simply
+ computed over the contents of that file (so it’s equal to what
+ Unix commands like <command>md5sum</command> or
+ <command>sha1sum</command> produce).</para>
+
+ <para>This is the default.</para></listitem>
+
+ </varlistentry>
+
+ <varlistentry><term><literal>"recursive"</literal></term>
+
+ <listitem><para>The hash is computed over the NAR archive dump
+ of the output (i.e., the result of <link
+ linkend="refsec-nix-store-dump"><command>nix-store
+ --dump</command></link>). In this case, the output can be
+ anything, including a directory tree.</para></listitem>
+
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+
+ <para>The <varname>outputHash</varname> attribute, finally, must
+ be a string containing the hash in either hexadecimal or base-32
+ notation. (See the <link
+ linkend="sec-nix-hash"><command>nix-hash</command> command</link>
+ for information about converting to and from base-32
+ notation.)</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><varname>impureEnvVars</varname></term>
+
+ <listitem><para>This attribute allows you to specify a list of
+ environment variables that should be passed from the environment
+ of the calling user to the builder. Usually, the environment is
+ cleared completely when the builder is executed, but with this
+ attribute you can allow specific environment variables to be
+ passed unmodified. For example, <function>fetchurl</function> in
+ Nixpkgs has the line
+
+<programlisting>
+impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
+</programlisting>
+
+ to make it use the proxy server configuration specified by the
+ user in the environment variables <envar>http_proxy</envar> and
+ friends.</para>
+
+ <para>This attribute is only allowed in <link
+ linkend="fixed-output-drvs">fixed-output derivations</link>, where
+ impurities such as these are okay since (the hash of) the output
+ is known in advance. It is ignored for all other
+ derivations.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><varname>preferLocalBuild</varname></term>
+
+ <listitem><para>If this attribute is set to
+ <literal>true</literal>, it has two effects. First, the
+ derivation will always be built, not substituted, even if a
+ substitute is available. Second, if <link
+ linkend="chap-distributed-builds">distributed building is
+ enabled</link>, then, if possible, the derivaton will be built
+ locally instead of forwarded to a remote machine. This is
+ appropriate for trivial builders where the cost of doing a
+ download or remote build would exceed the cost of building
+ locally.</para></listitem>
+
+ </varlistentry>
+
+</variablelist>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/arguments-variables.xml b/doc/manual/expressions/arguments-variables.xml
new file mode 100644
index 000000000..bf60cb7ee
--- /dev/null
+++ b/doc/manual/expressions/arguments-variables.xml
@@ -0,0 +1,121 @@
+<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-arguments'>
+
+<title>Arguments and Variables</title>
+
+<example xml:id='ex-hello-composition'>
+
+<title>Composing GNU Hello
+(<filename>all-packages.nix</filename>)</title>
+<programlisting>
+...
+
+rec { <co xml:id='ex-hello-composition-co-1' />
+
+ hello = import ../applications/misc/hello/ex-1 <co xml:id='ex-hello-composition-co-2' /> { <co xml:id='ex-hello-composition-co-3' />
+ inherit fetchurl stdenv perl;
+ };
+
+ perl = import ../development/interpreters/perl { <co xml:id='ex-hello-composition-co-4' />
+ inherit fetchurl stdenv;
+ };
+
+ fetchurl = import ../build-support/fetchurl {
+ inherit stdenv; ...
+ };
+
+ stdenv = ...;
+
+}
+</programlisting>
+</example>
+
+<para>The Nix expression in <xref linkend='ex-hello-nix' /> is a
+function; it is missing some arguments that have to be filled in
+somewhere. In the Nix Packages collection this is done in the file
+<filename>pkgs/top-level/all-packages.nix</filename>, where all
+Nix expressions for packages are imported and called with the
+appropriate arguments. <xref linkend='ex-hello-composition' /> shows
+some fragments of
+<filename>all-packages.nix</filename>.</para>
+
+<calloutlist>
+
+ <callout arearefs='ex-hello-composition-co-1'>
+
+ <para>This file defines a set of attributes, all of which are
+ concrete derivations (i.e., not functions). In fact, we define a
+ <emphasis>mutually recursive</emphasis> set of attributes. That
+ is, the attributes can refer to each other. This is precisely
+ what we want since we want to <quote>plug</quote> the
+ various packages into each other.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-composition-co-2'>
+
+ <para>Here we <emphasis>import</emphasis> the Nix expression for
+ GNU Hello. The import operation just loads and returns the
+ specified Nix expression. In fact, we could just have put the
+ contents of <xref linkend='ex-hello-nix' /> in
+ <filename>all-packages.nix</filename> at this point. That
+ would be completely equivalent, but it would make the file rather
+ bulky.</para>
+
+ <para>Note that we refer to
+ <filename>../applications/misc/hello/ex-1</filename>, not
+ <filename>../applications/misc/hello/ex-1/default.nix</filename>.
+ When you try to import a directory, Nix automatically appends
+ <filename>/default.nix</filename> to the file name.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-composition-co-3'>
+
+ <para>This is where the actual composition takes place. Here we
+ <emphasis>call</emphasis> the function imported from
+ <filename>../applications/misc/hello/ex-1</filename> with a set
+ containing the things that the function expects, namely
+ <varname>fetchurl</varname>, <varname>stdenv</varname>, and
+ <varname>perl</varname>. We use inherit again to use the
+ attributes defined in the surrounding scope (we could also have
+ written <literal>fetchurl = fetchurl;</literal>, etc.).</para>
+
+ <para>The result of this function call is an actual derivation
+ that can be built by Nix (since when we fill in the arguments of
+ the function, what we get is its body, which is the call to
+ <varname>stdenv.mkDerivation</varname> in <xref
+ linkend='ex-hello-nix' />).</para>
+
+ <note><para>Nixpkgs has a convenience function
+ <function>callPackage</function> that imports and calls a
+ function, filling in any missing arguments by passing the
+ corresponding attribute from the Nixpkgs set, like this:
+
+<programlisting>
+hello = callPackage ../applications/misc/hello/ex-1 { };
+</programlisting>
+
+ If necessary, you can set or override arguments:
+
+<programlisting>
+hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
+</programlisting>
+
+ </para></note>
+
+ </callout>
+
+ <callout arearefs='ex-hello-composition-co-4'>
+
+ <para>Likewise, we have to instantiate Perl,
+ <varname>fetchurl</varname>, and the standard environment.</para>
+
+ </callout>
+
+</calloutlist>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/build-script.xml b/doc/manual/expressions/build-script.xml
new file mode 100644
index 000000000..7bad8f808
--- /dev/null
+++ b/doc/manual/expressions/build-script.xml
@@ -0,0 +1,119 @@
+<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> \ No newline at end of file
diff --git a/doc/manual/expressions/builder-syntax.xml b/doc/manual/expressions/builder-syntax.xml
new file mode 100644
index 000000000..e51bade44
--- /dev/null
+++ b/doc/manual/expressions/builder-syntax.xml
@@ -0,0 +1,119 @@
+<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-builder-syntax'>
+
+<title>Builder Syntax</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> \ No newline at end of file
diff --git a/doc/manual/expressions/builtins.xml b/doc/manual/expressions/builtins.xml
new file mode 100644
index 000000000..4edb3a1a7
--- /dev/null
+++ b/doc/manual/expressions/builtins.xml
@@ -0,0 +1,950 @@
+<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-builtins'>
+
+<title>Built-in Functions</title>
+
+<para>This section lists the functions and constants built into the
+Nix expression evaluator. (The built-in function
+<function>derivation</function> is discussed above.) Some built-ins,
+such as <function>derivation</function>, are always in scope of every
+Nix expression; you can just access them right away. But to prevent
+polluting the namespace too much, most built-ins are not in scope.
+Instead, you can access them through the <varname>builtins</varname>
+built-in value, which is a set that contains all built-in functions
+and values. For instance, <function>derivation</function> is also
+available as <function>builtins.derivation</function>.</para>
+
+
+<variablelist>
+
+
+ <varlistentry><term><function>abort</function> <replaceable>s</replaceable></term>
+
+ <listitem><para>Abort Nix expression evaluation, print error
+ message <replaceable>s</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.add</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Return the sum of the integers
+ <replaceable>e1</replaceable> and
+ <replaceable>e2</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.attrNames</function>
+ <replaceable>set</replaceable></term>
+
+ <listitem><para>Return the names of the attributes in the set
+ <replaceable>set</replaceable> in a sorted list. For instance,
+ <literal>builtins.attrNames { y = 1; x = "foo"; }</literal>
+ evaluates to <literal>[ "x" "y" ]</literal>. There is no built-in
+ function <function>attrValues</function>, but you can easily
+ define it yourself:
+
+<programlisting>
+attrValues = set: map (name: builtins.getAttr name set) (builtins.attrNames set);</programlisting>
+
+ </para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>baseNameOf</function> <replaceable>s</replaceable></term>
+
+ <listitem><para>Return the <emphasis>base name</emphasis> of the
+ string <replaceable>s</replaceable>, that is, everything following
+ the final slash in the string. This is similar to the GNU
+ <command>basename</command> command.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><varname>builtins</varname></term>
+
+ <listitem><para>The set <varname>builtins</varname> contains all
+ the built-in functions and values. You can use
+ <varname>builtins</varname> to test for the availability of
+ features in the Nix installation, e.g.,
+
+<programlisting>
+if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
+
+ This allows a Nix expression to fall back gracefully on older Nix
+ installations that don’t have the desired built-in
+ function.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.compareVersions</function>
+ <replaceable>s1</replaceable> <replaceable>s2</replaceable></term>
+
+ <listitem><para>Compare two strings representing versions and
+ return <literal>-1</literal> if version
+ <replaceable>s1</replaceable> is older than version
+ <replaceable>s2</replaceable>, <literal>0</literal> if they are
+ the same, and <literal>1</literal> if
+ <replaceable>s1</replaceable> is newer than
+ <replaceable>s2</replaceable>. The version comparison algorithm
+ is the same as the one used by <link
+ linkend="ssec-version-comparisons"><command>nix-env
+ -u</command></link>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.concatLists</function>
+ <replaceable>lists</replaceable></term>
+
+ <listitem><para>Concatenate a list of lists into a single
+ list.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry
+ xml:id='builtin-currentSystem'><term><varname>builtins.currentSystem</varname></term>
+
+ <listitem><para>The built-in value <varname>currentSystem</varname>
+ evaluates to the Nix platform identifier for the Nix installation
+ on which the expression is being evaluated, such as
+ <literal>"i686-linux"</literal> or
+ <literal>"powerpc-darwin"</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <!--
+ <varlistentry><term><function>currentTime</function></term>
+
+ <listitem><para>The built-in value <varname>currentTime</varname>
+ returns the current system time in seconds since 00:00:00 1/1/1970
+ UTC. Due to the evaluation model of Nix expressions
+ (<emphasis>maximal laziness</emphasis>), it always yields the same
+ value within an execution of Nix.</para></listitem>
+
+ </varlistentry>
+ -->
+
+
+ <!--
+ <varlistentry><term><function>dependencyClosure</function></term>
+
+ <listitem><para>TODO</para></listitem>
+
+ </varlistentry>
+ -->
+
+
+ <varlistentry><term><function>derivation</function>
+ <replaceable>attrs</replaceable></term>
+
+ <listitem><para><function>derivation</function> is described in
+ <xref linkend='ssec-derivation' />.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>dirOf</function> <replaceable>s</replaceable></term>
+
+ <listitem><para>Return the directory part of the string
+ <replaceable>s</replaceable>, that is, everything before the final
+ slash in the string. This is similar to the GNU
+ <command>dirname</command> command.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.div</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Return the quotient of the integers
+ <replaceable>e1</replaceable> and
+ <replaceable>e2</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.elem</function>
+ <replaceable>x</replaceable> <replaceable>xs</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if a value equal to
+ <replaceable>x</replaceable> occurs in the list
+ <replaceable>xs</replaceable>, and <literal>false</literal>
+ otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.elemAt</function>
+ <replaceable>xs</replaceable> <replaceable>n</replaceable></term>
+
+ <listitem><para>Return element <replaceable>n</replaceable> from
+ the list <replaceable>xs</replaceable>. Elements are counted
+ starting from 0. A fatal error occurs in the index is out of
+ bounds.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.filter</function>
+ <replaceable>f</replaceable> <replaceable>xs</replaceable></term>
+
+ <listitem><para>Return a list consisting of the elements of
+ <replaceable>xs</replaceable> for which the function
+ <replaceable>f</replaceable> returns
+ <literal>true</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.filterSource</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem>
+
+ <para>This function allows you to copy sources into the Nix
+ store while filtering certain files. For instance, suppose that
+ you want to use the directory <filename>source-dir</filename> as
+ an input to a Nix expression, e.g.
+
+<programlisting>
+stdenv.mkDerivation {
+ ...
+ src = ./source-dir;
+}
+</programlisting>
+
+ However, if <filename>source-dir</filename> is a Subversion
+ working copy, then all those annoying <filename>.svn</filename>
+ subdirectories will also be copied to the store. Worse, the
+ contents of those directories may change a lot, causing lots of
+ spurious rebuilds. With <function>filterSource</function> you
+ can filter out the <filename>.svn</filename> directories:
+
+<programlisting>
+ src = builtins.filterSource
+ (path: type: type != "directory" || baseNameOf path != ".svn")
+ ./source-dir;
+</programlisting>
+
+ </para>
+
+ <para>Thus, the first argument <replaceable>e1</replaceable>
+ must be a predicate function that is called for each regular
+ file, directory or symlink in the source tree
+ <replaceable>e2</replaceable>. If the function returns
+ <literal>true</literal>, the file is copied to the Nix store,
+ otherwise it is omitted. The function is called with two
+ arguments. The first is the full path of the file. The second
+ is a string that identifies the type of the file, which is
+ either <literal>"regular"</literal>,
+ <literal>"directory"</literal>, <literal>"symlink"</literal> or
+ <literal>"unknown"</literal> (for other kinds of files such as
+ device nodes or fifos — but note that those cannot be copied to
+ the Nix store, so if the predicate returns
+ <literal>true</literal> for them, the copy will fail).</para>
+
+ </listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.fromJSON</function> <replaceable>e</replaceable></term>
+
+ <listitem><para>Convert a JSON string to a Nix
+ value. For example,
+
+<programlisting>
+builtins.fromJSON ''{"x": [1, 2, 3], "y": null}''
+</programlisting>
+
+ returns the value <literal>{ x = [ 1 2 3 ]; y = null;
+ }</literal>. Floating point numbers are not
+ supported.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.getAttr</function>
+ <replaceable>s</replaceable> <replaceable>set</replaceable></term>
+
+ <listitem><para><function>getAttr</function> returns the attribute
+ named <replaceable>s</replaceable> from
+ <replaceable>set</replaceable>. Evaluation aborts if the
+ attribute doesn’t exist. This is a dynamic version of the
+ <literal>.</literal> operator, since <replaceable>s</replaceable>
+ is an expression rather than an identifier.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.getEnv</function>
+ <replaceable>s</replaceable></term>
+
+ <listitem><para><function>getEnv</function> returns the value of
+ the environment variable <replaceable>s</replaceable>, or an empty
+ string if the variable doesn’t exist. This function should be
+ used with care, as it can introduce all sorts of nasty environment
+ dependencies in your Nix expression.</para>
+
+ <para><function>getEnv</function> is used in Nix Packages to
+ locate the file <filename>~/.nixpkgs/config.nix</filename>, which
+ contains user-local settings for Nix Packages. (That is, it does
+ a <literal>getEnv "HOME"</literal> to locate the user’s home
+ directory.)</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.hasAttr</function>
+ <replaceable>s</replaceable> <replaceable>set</replaceable></term>
+
+ <listitem><para><function>hasAttr</function> returns
+ <literal>true</literal> if <replaceable>set</replaceable> has an
+ attribute named <replaceable>s</replaceable>, and
+ <literal>false</literal> otherwise. This is a dynamic version of
+ the <literal>?</literal> operator, since
+ <replaceable>s</replaceable> is an expression rather than an
+ identifier.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.hashString</function>
+ <replaceable>type</replaceable> <replaceable>s</replaceable></term>
+
+ <listitem><para>Return a base-16 representation of the
+ cryptographic hash of string <replaceable>s</replaceable>. The
+ hash algorithm specified by <replaceable>type</replaceable> must
+ be one of <literal>"md5"</literal>, <literal>"sha1"</literal> or
+ <literal>"sha256"</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.head</function>
+ <replaceable>list</replaceable></term>
+
+ <listitem><para>Return the first element of a list; abort
+ evaluation if the argument isn’t a list or is an empty list. You
+ can test whether a list is empty by comparing it with
+ <literal>[]</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>import</function>
+ <replaceable>path</replaceable></term>
+
+ <listitem><para>Load, parse and return the Nix expression in the
+ file <replaceable>path</replaceable>. If <replaceable>path
+ </replaceable> is a directory, the file <filename>default.nix
+ </filename> in that directory is loaded. Evaluation aborts if the
+ file doesn’t exist or contains an incorrect Nix expression.
+ <function>import</function> implements Nix’s module system: you
+ can put any Nix expression (such as a set or a function) in a
+ separate file, and use it from Nix expressions in other
+ files.</para>
+
+ <para>A Nix expression loaded by <function>import</function> must
+ not contain any <emphasis>free variables</emphasis> (identifiers
+ that are not defined in the Nix expression itself and are not
+ built-in). Therefore, it cannot refer to variables that are in
+ scope at the call site. For instance, if you have a calling
+ expression
+
+<programlisting>
+rec {
+ x = 123;
+ y = import ./foo.nix;
+}</programlisting>
+
+ then the following <filename>foo.nix</filename> will give an
+ error:
+
+<programlisting>
+x + 456</programlisting>
+
+ since <varname>x</varname> is not in scope in
+ <filename>foo.nix</filename>. If you want <varname>x</varname>
+ to be available in <filename>foo.nix</filename>, you should pass
+ it as a function argument:
+
+<programlisting>
+rec {
+ x = 123;
+ y = import ./foo.nix x;
+}</programlisting>
+
+ and
+
+<programlisting>
+x: x + 456</programlisting>
+
+ (The function argument doesn’t have to be called
+ <varname>x</varname> in <filename>foo.nix</filename>; any name
+ would work.)</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.intersectAttrs</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Return a set consisting of the attributes in the
+ set <replaceable>e2</replaceable> that also exist in the set
+ <replaceable>e1</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.isAttrs</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to a set, and
+ <literal>false</literal> otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.isList</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to a list, and
+ <literal>false</literal> otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.isFunction</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to a function, and
+ <literal>false</literal> otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.isString</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to a string, and
+ <literal>false</literal> otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.isInt</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to an int, and
+ <literal>false</literal> otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.isBool</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to a bool, and
+ <literal>false</literal> otherwise.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>isNull</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if
+ <replaceable>e</replaceable> evaluates to <literal>null</literal>,
+ and <literal>false</literal> otherwise.</para>
+
+ <warning><para>This function is <emphasis>deprecated</emphasis>;
+ just write <literal>e == null</literal> instead.</para></warning>
+
+ </listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.length</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return the length of the list
+ <replaceable>e</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.lessThan</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if the integer
+ <replaceable>e1</replaceable> is less than the integer
+ <replaceable>e2</replaceable>, and <literal>false</literal>
+ otherwise. Evaluation aborts if either
+ <replaceable>e1</replaceable> or <replaceable>e2</replaceable>
+ does not evaluate to an integer.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.listToAttrs</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Construct a set from a list specifying the names
+ and values of each attribute. Each element of the list should be
+ a set consisting of a string-valued attribute
+ <varname>name</varname> specifying the name of the attribute, and
+ an attribute <varname>value</varname> specifying its value.
+ Example:
+
+<programlisting>
+builtins.listToAttrs
+ [ { name = "foo"; value = 123; }
+ { name = "bar"; value = 456; }
+ ]
+</programlisting>
+
+ evaluates to
+
+<programlisting>
+{ foo = 123; bar = 456; }
+</programlisting>
+
+ </para></listitem>
+
+ </varlistentry>
+
+ <varlistentry><term><function>map</function>
+ <replaceable>f</replaceable> <replaceable>list</replaceable></term>
+
+ <listitem><para>Apply the function <replaceable>f</replaceable> to
+ each element in the list <replaceable>list</replaceable>. For
+ example,
+
+<programlisting>
+map (x: "foo" + x) [ "bar" "bla" "abc" ]</programlisting>
+
+ evaluates to <literal>[ "foobar" "foobla" "fooabc"
+ ]</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.mul</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Return the product of the integers
+ <replaceable>e1</replaceable> and
+ <replaceable>e2</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.parseDrvName</function>
+ <replaceable>s</replaceable></term>
+
+ <listitem><para>Split the string <replaceable>s</replaceable> into
+ a package name and version. The package name is everything up to
+ but not including the first dash followed by a digit, and the
+ version is everything following that dash. The result is returned
+ in a set <literal>{ name, version }</literal>. Thus,
+ <literal>builtins.parseDrvName "nix-0.12pre12876"</literal>
+ returns <literal>{ name = "nix"; version = "0.12pre12876";
+ }</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.pathExists</function>
+ <replaceable>path</replaceable></term>
+
+ <listitem><para>Return <literal>true</literal> if the path
+ <replaceable>path</replaceable> exists, and
+ <literal>false</literal> otherwise. One application of this
+ function is to conditionally include a Nix expression containing
+ user configuration:
+
+<programlisting>
+let
+ fileName = builtins.getEnv "CONFIG_FILE";
+ config =
+ if fileName != "" &amp;&amp; builtins.pathExists (builtins.toPath fileName)
+ then import (builtins.toPath fileName)
+ else { someSetting = false; }; <lineannotation># default configuration</lineannotation>
+in config.someSetting</programlisting>
+
+ (Note that <envar>CONFIG_FILE</envar> must be an absolute path for
+ this to work.)</para></listitem>
+
+ </varlistentry>
+
+
+ <!--
+ <varlistentry><term><function>relativise</function></term>
+
+ <listitem><para>TODO</para></listitem>
+
+ </varlistentry>
+ -->
+
+
+ <varlistentry><term><function>builtins.readFile</function>
+ <replaceable>path</replaceable></term>
+
+ <listitem><para>Return the contents of the file
+ <replaceable>path</replaceable> as a string.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>removeAttrs</function>
+ <replaceable>set</replaceable> <replaceable>list</replaceable></term>
+
+ <listitem><para>Remove the attributes listed in
+ <replaceable>list</replaceable> from
+ <replaceable>set</replaceable>. The attributes don’t have to
+ exist in <replaceable>set</replaceable>. For instance,
+
+<screen>
+removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]</screen>
+
+ evaluates to <literal>{ y = 2; }</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.stringLength</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return the length of the string
+ <replaceable>e</replaceable>. If <replaceable>e</replaceable> is
+ not a string, evaluation is aborted.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.sub</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Return the difference between the integers
+ <replaceable>e1</replaceable> and
+ <replaceable>e2</replaceable>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.substring</function>
+ <replaceable>start</replaceable> <replaceable>len</replaceable>
+ <replaceable>s</replaceable></term>
+
+ <listitem><para>Return the substring of
+ <replaceable>s</replaceable> from character position
+ <replaceable>start</replaceable> (zero-based) up to but not
+ including <replaceable>start + len</replaceable>. If
+ <replaceable>start</replaceable> is greater than the length of the
+ string, an empty string is returned, and if <replaceable>start +
+ len</replaceable> lies beyond the end of the string, only the
+ substring up to the end of the string is returned.
+ <replaceable>start</replaceable> must be
+ non-negative.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.tail</function>
+ <replaceable>list</replaceable></term>
+
+ <listitem><para>Return the second to last elements of a list;
+ abort evaluation if the argument isn’t a list or is an empty
+ list.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>throw</function>
+ <replaceable>s</replaceable></term>
+
+ <listitem><para>Throw an error message
+ <replaceable>s</replaceable>. This usually aborts Nix expression
+ evaluation, but in <command>nix-env -qa</command> and other
+ commands that try to evaluate a set of derivations to get
+ information about those derivations, a derivation that throws an
+ error is silently skipped (which is not the case for
+ <function>abort</function>).</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry
+ xml:id='builtin-toFile'><term><function>builtins.toFile</function>
+ <replaceable>name</replaceable> <replaceable>s</replaceable></term>
+
+ <listitem><para>Store the string <replaceable>s</replaceable> in a
+ file in the Nix store and return its path. The file has suffix
+ <replaceable>name</replaceable>. This file can be used as an
+ input to derivations. One application is to write builders
+ “inline”. For instance, the following Nix expression combines
+ <xref linkend='ex-hello-nix' /> and <xref
+ linkend='ex-hello-builder' /> into one file:
+
+<programlisting>
+{ stdenv, fetchurl, perl }:
+
+stdenv.mkDerivation {
+ name = "hello-2.1.1";
+
+ builder = builtins.toFile "builder.sh" "
+ source $stdenv/setup
+
+ PATH=$perl/bin:$PATH
+
+ tar xvfz $src
+ cd hello-*
+ ./configure --prefix=$out
+ make
+ make install
+ ";
+
+ src = fetchurl {
+ url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz;
+ md5 = "70c9ccf9fac07f762c24f2df2290784d";
+ };
+ inherit perl;
+}</programlisting>
+
+ </para>
+
+ <para>It is even possible for one file to refer to another, e.g.,
+
+<programlisting>
+ builder = let
+ configFile = builtins.toFile "foo.conf" "
+ # This is some dummy configuration file.
+ <replaceable>...</replaceable>
+ ";
+ in builtins.toFile "builder.sh" "
+ source $stdenv/setup
+ <replaceable>...</replaceable>
+ cp ${configFile} $out/etc/foo.conf
+ ";</programlisting>
+
+ Note that <literal>${configFile}</literal> is an antiquotation
+ (see <xref linkend='ssec-values' />), so the result of the
+ expression <literal>configFile</literal> (i.e., a path like
+ <filename>/nix/store/m7p7jfny445k...-foo.conf</filename>) will be
+ spliced into the resulting string.</para>
+
+ <para>It is however <emphasis>not</emphasis> allowed to have files
+ mutually referring to each other, like so:
+
+<programlisting>
+let
+ foo = builtins.toFile "foo" "...${bar}...";
+ bar = builtins.toFile "bar" "...${foo}...";
+in foo</programlisting>
+
+ This is not allowed because it would cause a cyclic dependency in
+ the computation of the cryptographic hashes for
+ <varname>foo</varname> and <varname>bar</varname>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.toJSON</function> <replaceable>e</replaceable></term>
+
+ <listitem><para>Return a string containing a JSON representation
+ of <replaceable>e</replaceable>. Strings, integers, booleans,
+ nulls and lists are mapped to their JSON equivalents. Sets
+ (except derivations) are represented as objects. Derivations are
+ translated to a JSON string containing the derivation’s output
+ path. Paths are copied to the store and represented as a JSON
+ string of the resulting store path.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.toPath</function> <replaceable>s</replaceable></term>
+
+ <listitem><para>Convert the string value
+ <replaceable>s</replaceable> into a path value. The string
+ <replaceable>s</replaceable> must represent an absolute path
+ (i.e., must start with <literal>/</literal>). The path need not
+ exist. The resulting path is canonicalised, e.g.,
+ <literal>builtins.toPath "//foo/xyzzy/../bar/"</literal> returns
+ <literal>/foo/bar</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>toString</function> <replaceable>e</replaceable></term>
+
+ <listitem><para>Convert the expression
+ <replaceable>e</replaceable> to a string.
+ <replaceable>e</replaceable> can be a string (in which case
+ <function>toString</function> is a no-op) or a path (e.g.,
+ <literal>toString /foo/bar</literal> yields
+ <literal>"/foo/bar"</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry xml:id='builtin-toXML'><term><function>builtins.toXML</function> <replaceable>e</replaceable></term>
+
+ <listitem><para>Return a string containing an XML representation
+ of <replaceable>e</replaceable>. The main application for
+ <function>toXML</function> is to communicate information with the
+ builder in a more structured format than plain environment
+ variables.</para>
+
+ <!-- TODO: more formally describe the schema of the XML
+ representation -->
+
+ <para><xref linkend='ex-toxml' /> shows an example where this is
+ the case. The builder is supposed to generate the configuration
+ file for a <link xlink:href='http://jetty.mortbay.org/'>Jetty
+ servlet container</link>. A servlet container contains a number
+ of servlets (<filename>*.war</filename> files) each exported under
+ a specific URI prefix. So the servlet configuration is a list of
+ sets containing the <varname>path</varname> and
+ <varname>war</varname> of the servlet (<xref
+ linkend='ex-toxml-co-servlets' />). This kind of information is
+ difficult to communicate with the normal method of passing
+ information through an environment variable, which just
+ concatenates everything together into a string (which might just
+ work in this case, but wouldn’t work if fields are optional or
+ contain lists themselves). Instead the Nix expression is
+ converted to an XML representation with
+ <function>toXML</function>, which is unambiguous and can easily be
+ processed with the appropriate tools. For instance, in the
+ example an XSLT stylesheet (<xref linkend='ex-toxml-co-stylesheet'
+ />) is applied to it (<xref linkend='ex-toxml-co-apply' />) to
+ generate the XML configuration file for the Jetty server. The XML
+ representation produced from <xref linkend='ex-toxml-co-servlets'
+ /> by <function>toXML</function> is shown in <xref
+ linkend='ex-toxml-result' />.</para>
+
+ <para>Note that <xref linkend='ex-toxml' /> uses the <function
+ linkend='builtin-toFile'>toFile</function> built-in to write the
+ builder and the stylesheet “inline” in the Nix expression. The
+ path of the stylesheet is spliced into the builder at
+ <literal>xsltproc ${stylesheet}
+ <replaceable>...</replaceable></literal>.</para>
+
+ <example xml:id='ex-toxml'><title>Passing information to a builder
+ using <function>toXML</function></title>
+
+<programlisting><![CDATA[
+{ stdenv, fetchurl, libxslt, jira, uberwiki }:
+
+stdenv.mkDerivation (rec {
+ name = "web-server";
+
+ buildInputs = [ libxslt ];
+
+ builder = builtins.toFile "builder.sh" "
+ source $stdenv/setup
+ mkdir $out
+ echo $servlets | xsltproc ${stylesheet} - > $out/server-conf.xml]]> <co xml:id='ex-toxml-co-apply' /> <![CDATA[
+ ";
+
+ stylesheet = builtins.toFile "stylesheet.xsl"]]> <co xml:id='ex-toxml-co-stylesheet' /> <![CDATA[
+ "<?xml version='1.0' encoding='UTF-8'?>
+ <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
+ <xsl:template match='/'>
+ <Configure>
+ <xsl:for-each select='/expr/list/attrs'>
+ <Call name='addWebApplication'>
+ <Arg><xsl:value-of select=\"attr[@name = 'path']/string/@value\" /></Arg>
+ <Arg><xsl:value-of select=\"attr[@name = 'war']/path/@value\" /></Arg>
+ </Call>
+ </xsl:for-each>
+ </Configure>
+ </xsl:template>
+ </xsl:stylesheet>
+ ";
+
+ servlets = builtins.toXML []]> <co xml:id='ex-toxml-co-servlets' /> <![CDATA[
+ { path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
+ { path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
+ ];
+})]]></programlisting>
+
+ </example>
+
+ <example xml:id='ex-toxml-result'><title>XML representation produced by
+ <function>toXML</function></title>
+
+<programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<expr>
+ <list>
+ <attrs>
+ <attr name="path">
+ <string value="/bugtracker" />
+ </attr>
+ <attr name="war">
+ <path value="/nix/store/d1jh9pasa7k2...-jira/lib/atlassian-jira.war" />
+ </attr>
+ </attrs>
+ <attrs>
+ <attr name="path">
+ <string value="/wiki" />
+ </attr>
+ <attr name="war">
+ <path value="/nix/store/y6423b1yi4sx...-uberwiki/uberwiki.war" />
+ </attr>
+ </attrs>
+ </list>
+</expr>]]></programlisting>
+
+ </example>
+
+ </listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.trace</function>
+ <replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
+
+ <listitem><para>Evaluate <replaceable>e1</replaceable> and print its
+ abstract syntax representation on standard error. Then return
+ <replaceable>e2</replaceable>. This function is useful for
+ debugging.</para></listitem>
+
+ </varlistentry>
+
+
+ <varlistentry><term><function>builtins.typeOf</function>
+ <replaceable>e</replaceable></term>
+
+ <listitem><para>Return a string representing the type of the value
+ <replaceable>e</replaceable>, namely <literal>"int"</literal>,
+ <literal>"bool"</literal>, <literal>"string"</literal>,
+ <literal>"path"</literal>, <literal>"null"</literal>,
+ <literal>"set"</literal>, <literal>"list"</literal> or
+ <literal>"lambda"</literal>.</para></listitem>
+
+ </varlistentry>
+
+
+</variablelist>
+
+
+</section>
diff --git a/doc/manual/expressions/custom-builder.xml b/doc/manual/expressions/custom-builder.xml
new file mode 100644
index 000000000..c26deac40
--- /dev/null
+++ b/doc/manual/expressions/custom-builder.xml
@@ -0,0 +1,26 @@
+<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-custom-builder">
+
+<title>Customizing the Generic Builder</title>
+
+<para>The operation of the generic builder can be modified in many
+places by setting certain variables. These <emphasis>hook
+variables</emphasis> are typically set to the name of some shell
+function defined by you. For instance, to perform some additional
+steps after <command>make install</command> you would set the
+<varname>postInstall</varname> variable:
+
+<programlisting>
+postInstall=myPostInstall
+
+myPostInstall() {
+ mkdir $out/share/extra
+ cp extrafiles/* $out/share/extra
+}</programlisting>
+
+</para>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/debug-build.xml b/doc/manual/expressions/debug-build.xml
new file mode 100644
index 000000000..508cb2c19
--- /dev/null
+++ b/doc/manual/expressions/debug-build.xml
@@ -0,0 +1,33 @@
+<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-debug-build">
+
+<title>Debugging Build Failures</title>
+
+<para>At the beginning of each phase, the set of all shell variables
+is written to the file <filename>env-vars</filename> at the top-level
+build directory. This is useful for debugging: it allows you to
+recreate the environment in which a build was performed. For
+instance, if a build fails, then assuming you used the
+<option>-K</option> flag, you can go to the output directory and
+<quote>switch</quote> to the environment of the builder:
+
+<screen>
+$ nix-build -K ./foo.nix
+... fails, keeping build directory `/tmp/nix-1234-0'
+
+$ cd /tmp/nix-1234-0
+
+$ source env-vars
+
+<lineannotation>(edit some files...)</lineannotation>
+
+$ make
+
+<lineannotation>(execution continues with the same GCC, make, etc.)</lineannotation></screen>
+
+</para>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/derivations.xml b/doc/manual/expressions/derivations.xml
new file mode 100644
index 000000000..b57c33f4e
--- /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>"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> \ No newline at end of file
diff --git a/doc/manual/expressions/expression-language.xml b/doc/manual/expressions/expression-language.xml
new file mode 100644
index 000000000..240ef80f1
--- /dev/null
+++ b/doc/manual/expressions/expression-language.xml
@@ -0,0 +1,30 @@
+<chapter 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="ch-expression-language">
+
+<title>Nix Expression Language</title>
+
+<para>The Nix expression language is a pure, lazy, functional
+language. Purity means that operations in the language don't have
+side-effects (for instance, there is no variable assignment).
+Laziness means that arguments to functions are evaluated only when
+they are needed. Functional means that functions are
+<quote>normal</quote> values that can be passed around and manipulated
+in interesting ways. The language is not a full-featured, general
+purpose language. Its main job is to describe packages,
+compositions of packages, and the variability within
+packages.</para>
+
+<para>This section presents the various features of the
+language.</para>
+
+<xi:include href="language-values.xml" />
+<xi:include href="language-constructs.xml" />
+<xi:include href="language-operators.xml" />
+<xi:include href="derivations.xml" />
+<xi:include href="builtins.xml" />
+
+
+</chapter>
diff --git a/doc/manual/expressions/expression-syntax.xml b/doc/manual/expressions/expression-syntax.xml
new file mode 100644
index 000000000..6f1a3a10c
--- /dev/null
+++ b/doc/manual/expressions/expression-syntax.xml
@@ -0,0 +1,148 @@
+<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-expression-syntax'>
+
+<title>Expression Syntax</title>
+
+<example xml:id='ex-hello-nix'><title>Nix expression for GNU Hello
+(<filename>default.nix</filename>)</title>
+<programlisting>
+{ stdenv, fetchurl, perl }: <co xml:id='ex-hello-nix-co-1' />
+
+stdenv.mkDerivation { <co xml:id='ex-hello-nix-co-2' />
+ name = "hello-2.1.1"; <co xml:id='ex-hello-nix-co-3' />
+ builder = ./builder.sh; <co xml:id='ex-hello-nix-co-4' />
+ src = fetchurl { <co xml:id='ex-hello-nix-co-5' />
+ url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
+ md5 = "70c9ccf9fac07f762c24f2df2290784d";
+ };
+ inherit perl; <co xml:id='ex-hello-nix-co-6' />
+}</programlisting>
+</example>
+
+<para><xref linkend='ex-hello-nix' /> shows a Nix expression for GNU
+Hello. It's actually already in the Nix Packages collection in
+<filename>pkgs/applications/misc/hello/ex-1/default.nix</filename>.
+It is customary to place each package in a separate directory and call
+the single Nix expression in that directory
+<filename>default.nix</filename>. The file has the following elements
+(referenced from the figure by number):
+
+<calloutlist>
+
+ <callout arearefs='ex-hello-nix-co-1'>
+
+ <para>This states that the expression is a
+ <emphasis>function</emphasis> that expects to be called with three
+ arguments: <varname>stdenv</varname>, <varname>fetchurl</varname>,
+ and <varname>perl</varname>. They are needed to build Hello, but
+ we don't know how to build them here; that's why they are function
+ arguments. <varname>stdenv</varname> is a package that is used
+ by almost all Nix Packages packages; it provides a
+ <quote>standard</quote> environment consisting of the things you
+ would expect in a basic Unix environment: a C/C++ compiler (GCC,
+ to be precise), the Bash shell, fundamental Unix tools such as
+ <command>cp</command>, <command>grep</command>,
+ <command>tar</command>, etc. <varname>fetchurl</varname> is a
+ function that downloads files. <varname>perl</varname> is the
+ Perl interpreter.</para>
+
+ <para>Nix functions generally have the form <literal>{ x, y, ...,
+ z }: e</literal> where <varname>x</varname>, <varname>y</varname>,
+ etc. are the names of the expected arguments, and where
+ <replaceable>e</replaceable> is the body of the function. So
+ here, the entire remainder of the file is the body of the
+ function; when given the required arguments, the body should
+ describe how to build an instance of the Hello package.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-nix-co-2'>
+
+ <para>So we have to build a package. Building something from
+ other stuff is called a <emphasis>derivation</emphasis> in Nix (as
+ opposed to sources, which are built by humans instead of
+ computers). We perform a derivation by calling
+ <varname>stdenv.mkDerivation</varname>.
+ <varname>mkDerivation</varname> is a function provided by
+ <varname>stdenv</varname> that builds a package from a set of
+ <emphasis>attributes</emphasis>. A set is just a list of
+ key/value pairs where each key is a string and each value is an
+ arbitrary Nix expression. They take the general form <literal>{
+ <replaceable>name1</replaceable> =
+ <replaceable>expr1</replaceable>; <replaceable>...</replaceable>
+ <replaceable>nameN</replaceable> =
+ <replaceable>exprN</replaceable>; }</literal>.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-nix-co-3'>
+
+ <para>The attribute <varname>name</varname> specifies the symbolic
+ name and version of the package. Nix doesn't really care about
+ these things, but they are used by for instance <command>nix-env
+ -q</command> to show a <quote>human-readable</quote> name for
+ packages. This attribute is required by
+ <varname>mkDerivation</varname>.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-nix-co-4'>
+
+ <para>The attribute <varname>builder</varname> specifies the
+ builder. This attribute can sometimes be omitted, in which case
+ <varname>mkDerivation</varname> will fill in a default builder
+ (which does a <literal>configure; make; make install</literal>, in
+ essence). Hello is sufficiently simple that the default builder
+ would suffice, but in this case, we will show an actual builder
+ for educational purposes. The value
+ <command>./builder.sh</command> refers to the shell script shown
+ in <xref linkend='ex-hello-builder' />, discussed below.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-nix-co-5'>
+
+ <para>The builder has to know what the sources of the package
+ are. Here, the attribute <varname>src</varname> is bound to the
+ result of a call to the <command>fetchurl</command> function.
+ Given a URL and an MD5 hash of the expected contents of the file
+ at that URL, this function builds a derivation that downloads the
+ file and checks its hash. So the sources are a dependency that
+ like all other dependencies is built before Hello itself is
+ built.</para>
+
+ <para>Instead of <varname>src</varname> any other name could have
+ been used, and in fact there can be any number of sources (bound
+ to different attributes). However, <varname>src</varname> is
+ customary, and it's also expected by the default builder (which we
+ don't use in this example).</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-nix-co-6'>
+
+ <para>Since the derivation requires Perl, we have to pass the
+ value of the <varname>perl</varname> function argument to the
+ builder. All attributes in the set are actually passed as
+ environment variables to the builder, so declaring an attribute
+
+ <programlisting>
+perl = perl;</programlisting>
+
+ will do the trick: it binds an attribute <varname>perl</varname>
+ to the function argument which also happens to be called
+ <varname>perl</varname>. However, it looks a bit silly, so there
+ is a shorter syntax. The <literal>inherit</literal> keyword
+ causes the specified attributes to be bound to whatever variables
+ with the same name happen to be in scope.</para>
+
+ </callout>
+
+</calloutlist>
+
+</para>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/generic-builder.xml b/doc/manual/expressions/generic-builder.xml
new file mode 100644
index 000000000..f8567a042
--- /dev/null
+++ b/doc/manual/expressions/generic-builder.xml
@@ -0,0 +1,98 @@
+<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-generic-builder'>
+
+<title>Generic Builder Syntax</title>
+
+<para>Recall from <xref linkend='ex-hello-builder' /> that the builder
+looked something like this:
+
+<programlisting>
+PATH=$perl/bin:$PATH
+tar xvfz $src
+cd hello-*
+./configure --prefix=$out
+make
+make install</programlisting>
+
+The builders for almost all Unix packages look like this — set up some
+environment variables, unpack the sources, configure, build, and
+install. For this reason the standard environment provides some Bash
+functions that automate the build process. A builder using the
+generic build facilities in shown in <xref linkend='ex-hello-builder2'
+/>.</para>
+
+<example xml:id='ex-hello-builder2'><title>Build script using the generic
+build functions</title>
+<programlisting>
+buildInputs="$perl" <co xml:id='ex-hello-builder2-co-1' />
+
+source $stdenv/setup <co xml:id='ex-hello-builder2-co-2' />
+
+genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
+</example>
+
+<calloutlist>
+
+ <callout arearefs='ex-hello-builder2-co-1'>
+
+ <para>The <envar>buildInputs</envar> variable tells
+ <filename>setup</filename> to use the indicated packages as
+ <quote>inputs</quote>. This means that if a package provides a
+ <filename>bin</filename> subdirectory, it's added to
+ <envar>PATH</envar>; if it has a <filename>include</filename>
+ subdirectory, it's added to GCC's header search path; and so
+ on.<footnote><para>How does it work? <filename>setup</filename>
+ tries to source the file
+ <filename><replaceable>pkg</replaceable>/nix-support/setup-hook</filename>
+ of all dependencies. These “setup hooks” can then set up whatever
+ environment variables they want; for instance, the setup hook for
+ Perl sets the <envar>PERL5LIB</envar> environment variable to
+ contain the <filename>lib/site_perl</filename> directories of all
+ inputs.</para></footnote>
+ </para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-builder2-co-2'>
+
+ <para>The function <function>genericBuild</function> is defined in
+ the file <literal>$stdenv/setup</literal>.</para>
+
+ </callout>
+
+ <callout arearefs='ex-hello-builder2-co-3'>
+
+ <para>The final step calls the shell function
+ <function>genericBuild</function>, which performs the steps that
+ were done explicitly in <xref linkend='ex-hello-builder' />. The
+ generic builder is smart enough to figure out whether to unpack
+ the sources using <command>gzip</command>,
+ <command>bzip2</command>, etc. It can be customised in many ways;
+ see <xref linkend='sec-standard-environment' />.</para>
+
+ </callout>
+
+</calloutlist>
+
+<para>Discerning readers will note that the
+<envar>buildInputs</envar> could just as well have been set in the Nix
+expression, like this:
+
+<programlisting>
+ buildInputs = [ perl ];</programlisting>
+
+The <varname>perl</varname> attribute can then be removed, and the
+builder becomes even shorter:
+
+<programlisting>
+source $stdenv/setup
+genericBuild</programlisting>
+
+In fact, <varname>mkDerivation</varname> provides a default builder
+that looks exactly like that, so it is actually possible to omit the
+builder for Hello entirely.</para>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/language-constructs.xml b/doc/manual/expressions/language-constructs.xml
new file mode 100644
index 000000000..ddb349894
--- /dev/null
+++ b/doc/manual/expressions/language-constructs.xml
@@ -0,0 +1,344 @@
+<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-constructs">
+
+<title>Language Constructs</title>
+
+<simplesect><title>Recursive sets</title>
+
+<para>Recursive sets are just normal sets, but the attributes can
+refer to each other. For example,
+
+<programlisting>
+rec {
+ x = y;
+ y = 123;
+}.x
+</programlisting>
+
+evaluates to <literal>123</literal>. Note that without
+<literal>rec</literal> the binding <literal>x = y;</literal> would
+refer to the variable <varname>y</varname> in the surrounding scope,
+if one exists, and would be invalid if no such variable exists. That
+is, in a normal (non-recursive) set, attributes are not added to the
+lexical scope; in a recursive set, they are.</para>
+
+<para>Recursive sets of course introduce the danger of infinite
+recursion. For example,
+
+<programlisting>
+rec {
+ x = y;
+ y = x;
+}.x</programlisting>
+
+does not terminate<footnote><para>Actually, Nix detects infinite
+recursion in this case and aborts (<quote>infinite recursion
+encountered</quote>).</para></footnote>.</para>
+
+</simplesect>
+
+
+<simplesect><title>Let-expressions</title>
+
+<para>A let-expression allows you define local variables for an
+expression. For instance,
+
+<programlisting>
+let
+ x = "foo";
+ y = "bar";
+in x + y</programlisting>
+
+evaluates to <literal>"foobar"</literal>.
+
+</para>
+
+</simplesect>
+
+
+<simplesect><title>Inheriting attributes</title>
+
+<para>When defining a set it is often convenient to copy variables
+from the surrounding lexical scope (e.g., when you want to propagate
+attributes). This can be shortened using the
+<literal>inherit</literal> keyword. For instance,
+
+<programlisting>
+let x = 123; in
+{ inherit x;
+ y = 456;
+}</programlisting>
+
+evaluates to <literal>{ x = 123; y = 456; }</literal>. (Note that
+this works because <varname>x</varname> is added to the lexical scope
+by the <literal>let</literal> construct.) It is also possible to
+inherit attributes from another set. For instance, in this fragment
+from <filename>all-packages.nix</filename>,
+
+<programlisting>
+ graphviz = (import ../tools/graphics/graphviz) {
+ inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
+ inherit (xlibs) libXaw;
+ };
+
+ xlibs = {
+ libX11 = ...;
+ libXaw = ...;
+ ...
+ }
+
+ libpng = ...;
+ libjpg = ...;
+ ...</programlisting>
+
+the set used in the function call to the function defined in
+<filename>../tools/graphics/graphviz</filename> inherits a number of
+variables from the surrounding scope (<varname>fetchurl</varname>
+... <varname>yacc</varname>), but also inherits
+<varname>libXaw</varname> (the X Athena Widgets) from the
+<varname>xlibs</varname> (X11 client-side libraries) set.</para>
+
+</simplesect>
+
+
+<simplesect xml:id="ss-functions"><title>Functions</title>
+
+<para>Functions have the following form:
+
+<programlisting>
+<replaceable>pattern</replaceable>: <replaceable>body</replaceable></programlisting>
+
+The pattern specifies what the argument of the function must look
+like, and binds variables in the body to (parts of) the
+argument. There are three kinds of patterns:</para>
+
+<itemizedlist>
+
+
+ <listitem><para>If a pattern is a single identifier, then the
+ function matches any argument. Example:
+
+ <programlisting>
+let negate = x: !x;
+ concat = x: y: x + y;
+in if negate true then concat "foo" "bar" else ""</programlisting>
+
+ Note that <function>concat</function> is a function that takes one
+ argument and returns a function that takes another argument. This
+ allows partial parameterisation (i.e., only filling some of the
+ arguments of a function); e.g.,
+
+ <programlisting>
+map (concat "foo") [ "bar" "bla" "abc" ]</programlisting>
+
+ evaluates to <literal>[ "foobar" "foobla"
+ "fooabc" ]</literal>.</para></listitem>
+
+
+ <listitem><para>A <emphasis>set pattern</emphasis> of the form
+ <literal>{ name1, name2, …, nameN }</literal> matches a set
+ containing the listed attributes, and binds the values of those
+ attributes to variables in the function body. For example, the
+ function
+
+<programlisting>
+{ x, y, z }: z + y + x</programlisting>
+
+ can only be called with a set containing exactly the attributes
+ <varname>x</varname>, <varname>y</varname> and
+ <varname>z</varname>. No other attributes are allowed. If you want
+ to allow additional arguments, you can use an ellipsis
+ (<literal>...</literal>):
+
+<programlisting>
+{ x, y, z, ... }: z + y + x</programlisting>
+
+ This works on any set that contains at least the three named
+ attributes.</para>
+
+ <para>It is possible to provide <emphasis>default values</emphasis>
+ for attributes, in which case they are allowed to be missing. A
+ default value is specified by writing
+ <literal><replaceable>name</replaceable> ?
+ <replaceable>e</replaceable></literal>, where
+ <replaceable>e</replaceable> is an arbitrary expression. For example,
+
+<programlisting>
+{ x, y ? "foo", z ? "bar" }: z + y + x</programlisting>
+
+ specifies a function that only requires an attribute named
+ <varname>x</varname>, but optionally accepts <varname>y</varname>
+ and <varname>z</varname>.</para></listitem>
+
+
+ <listitem><para>An <literal>@</literal>-pattern provides a means of referring
+ to the whole value being matched:
+
+<programlisting>
+args@{ x, y, z, ... }: z + y + x + args.a</programlisting>
+
+ Here <varname>args</varname> is bound to the entire argument, which
+ is further matched against the pattern <literal>{ x, y, z,
+ ... }</literal>.</para></listitem>
+
+
+</itemizedlist>
+
+<para>Note that functions do not have names. If you want to give them
+a name, you can bind them to an attribute, e.g.,
+
+<programlisting>
+let concat = { x, y }: x + y;
+in concat { x = "foo"; y = "bar"; }</programlisting>
+
+</para>
+
+</simplesect>
+
+
+<simplesect><title>Conditionals</title>
+
+<para>Conditionals look like this:
+
+<programlisting>
+if <replaceable>e1</replaceable> then <replaceable>e2</replaceable> else <replaceable>e3</replaceable></programlisting>
+
+where <replaceable>e1</replaceable> is an expression that should
+evaluate to a Boolean value (<literal>true</literal> or
+<literal>false</literal>).</para>
+
+</simplesect>
+
+
+<simplesect><title>Assertions</title>
+
+<para>Assertions are generally used to check that certain requirements
+on or between features and dependencies hold. They look like this:
+
+<programlisting>
+assert <replaceable>e1</replaceable>; <replaceable>e2</replaceable></programlisting>
+
+where <replaceable>e1</replaceable> is an expression that should
+evaluate to a Boolean value. If it evaluates to
+<literal>true</literal>, <replaceable>e2</replaceable> is returned;
+otherwise expression evaluation is aborted and a backtrace is printed.</para>
+
+<example xml:id='ex-subversion-nix'><title>Nix expression for Subversion</title>
+<programlisting>
+{ localServer ? false
+, httpServer ? false
+, sslSupport ? false
+, pythonBindings ? false
+, javaSwigBindings ? false
+, javahlBindings ? false
+, stdenv, fetchurl
+, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
+}:
+
+assert localServer -> db4 != null; <co xml:id='ex-subversion-nix-co-1' />
+assert httpServer -> httpd != null &amp;&amp; httpd.expat == expat; <co xml:id='ex-subversion-nix-co-2' />
+assert sslSupport -> openssl != null &amp;&amp; (httpServer -> httpd.openssl == openssl); <co xml:id='ex-subversion-nix-co-3' />
+assert pythonBindings -> swig != null &amp;&amp; swig.pythonSupport;
+assert javaSwigBindings -> swig != null &amp;&amp; swig.javaSupport;
+assert javahlBindings -> j2sdk != null;
+
+stdenv.mkDerivation {
+ name = "subversion-1.1.1";
+ ...
+ openssl = if sslSupport then openssl else null; <co xml:id='ex-subversion-nix-co-4' />
+ ...
+}</programlisting>
+</example>
+
+<para><xref linkend='ex-subversion-nix' /> show how assertions are
+used in the Nix expression for Subversion.</para>
+
+<calloutlist>
+
+ <callout arearefs='ex-subversion-nix-co-1'>
+ <para>This assertion states that if Subversion is to have support
+ for local repositories, then Berkeley DB is needed. So if the
+ Subversion function is called with the
+ <varname>localServer</varname> argument set to
+ <literal>true</literal> but the <varname>db4</varname> argument
+ set to <literal>null</literal>, then the evaluation fails.</para>
+ </callout>
+
+ <callout arearefs='ex-subversion-nix-co-2'>
+ <para>This is a more subtle condition: if Subversion is built with
+ Apache (<literal>httpServer</literal>) support, then the Expat
+ library (an XML library) used by Subversion should be same as the
+ one used by Apache. This is because in this configuration
+ Subversion code ends up being linked with Apache code, and if the
+ Expat libraries do not match, a build- or runtime link error or
+ incompatibility might occur.</para>
+ </callout>
+
+ <callout arearefs='ex-subversion-nix-co-3'>
+ <para>This assertion says that in order for Subversion to have SSL
+ support (so that it can access <literal>https</literal> URLs), an
+ OpenSSL library must be passed. Additionally, it says that
+ <emphasis>if</emphasis> Apache support is enabled, then Apache's
+ OpenSSL should match Subversion's. (Note that if Apache support
+ is not enabled, we don't care about Apache's OpenSSL.)</para>
+ </callout>
+
+ <callout arearefs='ex-subversion-nix-co-4'>
+ <para>The conditional here is not really related to assertions,
+ but is worth pointing out: it ensures that if SSL support is
+ disabled, then the Subversion derivation is not dependent on
+ OpenSSL, even if a non-<literal>null</literal> value was passed.
+ This prevents an unnecessary rebuild of Subversion if OpenSSL
+ changes.</para>
+ </callout>
+
+</calloutlist>
+
+</simplesect>
+
+
+
+<simplesect><title>With-expressions</title>
+
+<para>A <emphasis>with-expression</emphasis>,
+
+<programlisting>
+with <replaceable>e1</replaceable>; <replaceable>e2</replaceable></programlisting>
+
+introduces the set <replaceable>e1</replaceable> into the lexical
+scope of the expression <replaceable>e2</replaceable>. For instance,
+
+<programlisting>
+let as = { x = "foo"; y = "bar"; };
+in with as; x + y</programlisting>
+
+evaluates to <literal>"foobar"</literal> since the
+<literal>with</literal> adds the <varname>x</varname> and
+<varname>y</varname> attributes of <varname>as</varname> to the
+lexical scope in the expression <literal>x + y</literal>. The most
+common use of <literal>with</literal> is in conjunction with the
+<function>import</function> function. E.g.,
+
+<programlisting>
+with (import ./definitions.nix); ...</programlisting>
+
+makes all attributes defined in the file
+<filename>definitions.nix</filename> available as if they were defined
+locally in a <literal>rec</literal>-expression.</para>
+
+</simplesect>
+
+
+<simplesect><title>Comments</title>
+
+<para>Comments can be single-line, started with a <literal>#</literal>
+character, or inline/multi-line, enclosed within <literal>/*
+... */</literal>.</para>
+
+</simplesect>
+
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/language-operators.xml b/doc/manual/expressions/language-operators.xml
new file mode 100644
index 000000000..a3323ced4
--- /dev/null
+++ b/doc/manual/expressions/language-operators.xml
@@ -0,0 +1,113 @@
+<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-language-operators">
+
+<title>Operators</title>
+
+<para><xref linkend='table-operators' /> lists the operators in the
+Nix expression language, in order of precedence (from strongest to
+weakest binding).</para>
+
+<table xml:id='table-operators'>
+ <title>Operators</title>
+ <tgroup cols='3'>
+ <thead>
+ <row>
+ <entry>Syntax</entry>
+ <entry>Associativity</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><replaceable>e</replaceable> <literal>.</literal>
+ <replaceable>attrpath</replaceable>
+ [ <literal>or</literal> <replaceable>def</replaceable> ]
+ </entry>
+ <entry>none</entry>
+ <entry>Select attribute denoted by the attribute path
+ <replaceable>attrpath</replaceable> from set
+ <replaceable>e</replaceable>. (An attribute path is a
+ dot-separated list of attribute names.) If the attribute
+ doesn’t exist, return <replaceable>def</replaceable> if
+ provided, otherwise abort evaluation.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <replaceable>e2</replaceable></entry>
+ <entry>left</entry>
+ <entry>Call function <replaceable>e1</replaceable> with
+ argument <replaceable>e2</replaceable>.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e</replaceable> <literal>?</literal>
+ <replaceable>attrpath</replaceable></entry>
+ <entry>none</entry>
+ <entry>Test whether set <replaceable>e</replaceable> contains
+ the attribute denoted by <replaceable>attrpath</replaceable>;
+ return <literal>true</literal> or
+ <literal>false</literal>.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>++</literal> <replaceable>e2</replaceable></entry>
+ <entry>right</entry>
+ <entry>List concatenation.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>+</literal> <replaceable>e2</replaceable></entry>
+ <entry>left</entry>
+ <entry>String or path concatenation.</entry>
+ </row>
+ <row>
+ <entry><literal>!</literal> <replaceable>e</replaceable></entry>
+ <entry>left</entry>
+ <entry>Boolean negation.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>//</literal>
+ <replaceable>e2</replaceable></entry>
+ <entry>right</entry>
+ <entry>Return a set consisting of the attributes in
+ <replaceable>e1</replaceable> and
+ <replaceable>e2</replaceable> (with the latter taking
+ precedence over the former in case of equally named
+ attributes).</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>==</literal>
+ <replaceable>e2</replaceable></entry>
+ <entry>none</entry>
+ <entry>Equality.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>!=</literal>
+ <replaceable>e2</replaceable></entry>
+ <entry>none</entry>
+ <entry>Inequality.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>&amp;&amp;</literal>
+ <replaceable>e2</replaceable></entry>
+ <entry>left</entry>
+ <entry>Logical AND.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>||</literal>
+ <replaceable>e2</replaceable></entry>
+ <entry>left</entry>
+ <entry>Logical OR.</entry>
+ </row>
+ <row>
+ <entry><replaceable>e1</replaceable> <literal>-></literal>
+ <replaceable>e2</replaceable></entry>
+ <entry>none</entry>
+ <entry>Logical implication (equivalent to
+ <literal>!<replaceable>e1</replaceable> ||
+ <replaceable>e2</replaceable></literal>).</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/language-values.xml b/doc/manual/expressions/language-values.xml
new file mode 100644
index 000000000..519657f15
--- /dev/null
+++ b/doc/manual/expressions/language-values.xml
@@ -0,0 +1,268 @@
+<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-values'>
+
+<title>Values</title>
+
+
+<simplesect><title>Simple Values</title>
+
+<para>Nix has the following basic data types:
+
+<itemizedlist>
+
+ <listitem>
+
+ <para><emphasis>Strings</emphasis> can be written in three
+ ways.</para>
+
+ <para>The most common way is to enclose the string between double
+ quotes, e.g., <literal>"foo bar"</literal>. Strings can span
+ multiple lines. The special characters <literal>"</literal> and
+ <literal>\</literal> and the character sequence
+ <literal>${</literal> must be escaped by prefixing them with a
+ backslash (<literal>\</literal>). Newlines, carriage returns and
+ tabs can be written as <literal>\n</literal>,
+ <literal>\r</literal> and <literal>\t</literal>,
+ respectively.</para>
+
+ <para>You can include the result of an expression into a string by
+ enclosing it in
+ <literal>${<replaceable>...</replaceable>}</literal>, a feature
+ known as <emphasis>antiquotation</emphasis>. The enclosed
+ expression must evaluate to something that can be coerced into a
+ string (meaning that it must be a string, a path, or a
+ derivation). For instance, rather than writing
+
+<programlisting>
+"--with-freetype2-library=" + freetype + "/lib"</programlisting>
+
+ (where <varname>freetype</varname> is a derivation), you can
+ instead write the more natural
+
+<programlisting>
+"--with-freetype2-library=${freetype}/lib"</programlisting>
+
+ The latter is automatically translated to the former. A more
+ complicated example (from the Nix expression for <link
+ xlink:href='http://www.trolltech.com/products/qt'>Qt</link>):
+
+<programlisting>
+configureFlags = "
+ -system-zlib -system-libpng -system-libjpeg
+ ${if openglSupport then "-dlopen-opengl
+ -L${mesa}/lib -I${mesa}/include
+ -L${libXmu}/lib -I${libXmu}/include" else ""}
+ ${if threadSupport then "-thread" else "-no-thread"}
+";</programlisting>
+
+ Note that Nix expressions and strings can be arbitrarily nested;
+ in this case the outer string contains various antiquotations that
+ themselves contain strings (e.g., <literal>"-thread"</literal>),
+ some of which in turn contain expressions (e.g.,
+ <literal>${mesa}</literal>).</para>
+
+ <para>The second way to write string literals is as an
+ <emphasis>indented string</emphasis>, which is enclosed between
+ pairs of <emphasis>double single-quotes</emphasis>, like so:
+
+<programlisting>
+''
+ This is the first line.
+ This is the second line.
+ This is the third line.
+''</programlisting>
+
+ This kind of string literal intelligently strips indentation from
+ the start of each line. To be precise, it strips from each line a
+ number of spaces equal to the minimal indentation of the string as
+ a whole (disregarding the indentation of empty lines). For
+ instance, the first and second line are indented two space, while
+ the third line is indented four spaces. Thus, two spaces are
+ stripped from each line, so the resulting string is
+
+<programlisting>
+"This is the first line.\nThis is the second line.\n This is the third line.\n"</programlisting>
+
+ </para>
+
+ <para>Note that the whitespace and newline following the opening
+ <literal>''</literal> is ignored if there is no non-whitespace
+ text on the initial line.</para>
+
+ <para>Antiquotation
+ (<literal>${<replaceable>expr</replaceable>}</literal>) is
+ supported in indented strings.</para>
+
+ <para>Since <literal>${</literal> and <literal>''</literal> have
+ special meaning in indented strings, you need a way to quote them.
+ <literal>${</literal> can be escaped by prefixing it with
+ <literal>''</literal> (that is, two single quotes), i.e.,
+ <literal>''${</literal>. <literal>''</literal> can be escaped by
+ prefixing it with <literal>'</literal>, i.e.,
+ <literal>'''</literal>. Finally, linefeed, carriage-return and
+ tab characters can be written as <literal>''\n</literal>,
+ <literal>''\r</literal>, <literal>''\t</literal>.</para>
+
+ <para>Indented strings are primarily useful in that they allow
+ multi-line string literals to follow the indentation of the
+ enclosing Nix expression, and that less escaping is typically
+ necessary for strings representing languages such as shell scripts
+ and configuration files because <literal>''</literal> is much less
+ common than <literal>"</literal>. Example:
+
+<programlisting>
+stdenv.mkDerivation {
+ <replaceable>...</replaceable>
+ postInstall =
+ ''
+ mkdir $out/bin $out/etc
+ cp foo $out/bin
+ echo "Hello World" > $out/etc/foo.conf
+ ${if enableBar then "cp bar $out/bin" else ""}
+ '';
+ <replaceable>...</replaceable>
+}
+</programlisting>
+
+ </para>
+
+ <para>Finally, as a convenience, <emphasis>URIs</emphasis> as
+ defined in appendix B of <link
+ xlink:href='http://www.ietf.org/rfc/rfc2396.txt'>RFC 2396</link>
+ can be written <emphasis>as is</emphasis>, without quotes. For
+ instance, the string
+ <literal>"http://example.org/foo.tar.bz2"</literal>
+ can also be written as
+ <literal>http://example.org/foo.tar.bz2</literal>.</para>
+
+ </listitem>
+
+ <listitem><para><emphasis>Integers</emphasis>, e.g.,
+ <literal>123</literal>.</para></listitem>
+
+ <listitem><para><emphasis>Paths</emphasis>, e.g.,
+ <filename>/bin/sh</filename> or <filename>./builder.sh</filename>.
+ A path must contain at least one slash to be recognised as such; for
+ instance, <filename>builder.sh</filename> is not a
+ path<footnote><para>It's parsed as an expression that selects the
+ attribute <varname>sh</varname> from the variable
+ <varname>builder</varname>.</para></footnote>. If the file name is
+ relative, i.e., if it does not begin with a slash, it is made
+ absolute at parse time relative to the directory of the Nix
+ expression that contained it. For instance, if a Nix expression in
+ <filename>/foo/bar/bla.nix</filename> refers to
+ <filename>../xyzzy/fnord.nix</filename>, the absolute path is
+ <filename>/foo/xyzzy/fnord.nix</filename>.</para></listitem>
+
+ <listitem><para><emphasis>Booleans</emphasis> with values
+ <literal>true</literal> and
+ <literal>false</literal>.</para></listitem>
+
+ <listitem><para>The null value, denoted as
+ <literal>null</literal>.</para></listitem>
+
+</itemizedlist>
+
+</para>
+
+</simplesect>
+
+
+<simplesect><title>Lists</title>
+
+<para>Lists are formed by enclosing a whitespace-separated list of
+values between square brackets. For example,
+
+<programlisting>
+[ 123 ./foo.nix "abc" (f { x = y; }) ]</programlisting>
+
+defines a list of four elements, the last being the result of a call
+to the function <varname>f</varname>. Note that function calls have
+to be enclosed in parentheses. If they had been omitted, e.g.,
+
+<programlisting>
+[ 123 ./foo.nix "abc" f { x = y; } ]</programlisting>
+
+the result would be a list of five elements, the fourth one being a
+function and the fifth being a set.</para>
+
+</simplesect>
+
+
+<simplesect><title>Sets</title>
+
+<para>Sets are really the core of the language, since ultimately the
+Nix language is all about creating derivations, which are really just
+sets of attributes to be passed to build scripts.</para>
+
+<para>Sets are just a list of name/value pairs (called
+<emphasis>attributes</emphasis>) enclosed in curly brackets, where
+each value is an arbitrary expression terminated by a semicolon. For
+example:
+
+<programlisting>
+{ x = 123;
+ text = "Hello";
+ y = f { bla = 456; };
+}</programlisting>
+
+This defines a set with attributes named <varname>x</varname>,
+<varname>text</varname>, <varname>y</varname>. The order of the
+attributes is irrelevant. An attribute name may only occur
+once.</para>
+
+<para>Attributes can be selected from a set using the
+<literal>.</literal> operator. For instance,
+
+<programlisting>
+{ a = "Foo"; b = "Bar"; }.a</programlisting>
+
+evaluates to <literal>"Foo"</literal>. It is possible to provide a
+default value in an attribute selection using the
+<literal>or</literal> keyword. For example,
+
+<programlisting>
+{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"</programlisting>
+
+will evaluate to <literal>"Xyzzy"</literal> because there is no
+<varname>c</varname> attribute in the set.</para>
+
+<para>You can use arbitrary double-quoted strings as attribute
+names:
+
+<programlisting>
+{ "foo ${bar}" = 123; "nix-1.0" = 456; }."foo ${bar}"
+</programlisting>
+
+This will evaluate to <literal>123</literal> (Assuming
+<literal>bar</literal> is antiquotable). In the case where an
+attribute name is just a single antiquotation, the quotes can be
+dropped:
+
+<programlisting>
+{ foo = 123; }.${bar} or 456 </programlisting>
+
+This will evaluate to <literal>123</literal> if
+<literal>bar</literal> evaluates to <literal>"foo"</literal> when
+coerced to a string and <literal>456</literal> otherwise (again
+assuming <literal>bar</literal> is antiquotable).</para>
+
+<para>In the special case where an attribute name inside of a set declaration
+evaluates to <literal>null</literal> (which is normally an error, as
+<literal>null</literal> is not antiquotable), that attribute is simply not
+added to the set:
+
+<programlisting>
+{ ${if foo then "bar" else null} = true; }</programlisting>
+
+This will evaluate to <literal>{}</literal> if <literal>foo</literal>
+evaluates to <literal>false</literal>.</para>
+
+
+</simplesect>
+
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/simple-building-testing.xml b/doc/manual/expressions/simple-building-testing.xml
new file mode 100644
index 000000000..cc90409b5
--- /dev/null
+++ b/doc/manual/expressions/simple-building-testing.xml
@@ -0,0 +1,86 @@
+<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-building-simple'>
+
+<title>Building and Testing</title>
+
+<para>You can now try to build Hello. Of course, you could do
+<literal>nix-env -f pkgs/top-level/all-packages.nix -i hello</literal>,
+but you may not want to install a possibly broken package just yet.
+The best way to test the package is by using the command <command
+linkend="sec-nix-build">nix-build</command>, which builds a Nix
+expression and creates a symlink named <filename>result</filename> in
+the current directory:
+
+<screen>
+$ nix-build pkgs/top-level/all-packages.nix -A hello
+building path `/nix/store/632d2b22514d...-hello-2.1.1'
+hello-2.1.1/
+hello-2.1.1/intl/
+hello-2.1.1/intl/ChangeLog
+<replaceable>...</replaceable>
+
+$ ls -l result
+lrwxrwxrwx ... 2006-09-29 10:43 result -> /nix/store/632d2b22514d...-hello-2.1.1
+
+$ ./result/bin/hello
+Hello, world!</screen>
+
+The <link linkend='opt-attr'><option>-A</option></link> option selects
+the <literal>hello</literal> attribute from
+<filename>all-packages.nix</filename>. This is faster than using the
+symbolic package name specified by the <literal>name</literal>
+attribute (which also happens to be <literal>hello</literal>) and is
+unambiguous (there can be multiple packages with the symbolic name
+<literal>hello</literal>, but there can be only one attribute in a set
+named <literal>hello</literal>).</para>
+
+<para><command>nix-build</command> registers the
+<filename>./result</filename> symlink as a garbage collection root, so
+unless and until you delete the <filename>./result</filename> symlink,
+the output of the build will be safely kept on your system. You can
+use <command>nix-build</command>’s <option
+linkend='opt-out-link'>-o</option> switch to give the symlink another
+name.</para>
+
+<para>Nix has a transactional semantics. Once a build finishes
+successfully, Nix makes a note of this in its database: it registers
+that the path denoted by <envar>out</envar> is now
+<quote>valid</quote>. If you try to build the derivation again, Nix
+will see that the path is already valid and finish immediately. If a
+build fails, either because it returns a non-zero exit code, because
+Nix or the builder are killed, or because the machine crashes, then
+the output paths will not be registered as valid. If you try to build
+the derivation again, Nix will remove the output paths if they exist
+(e.g., because the builder died half-way through <literal>make
+install</literal>) and try again. Note that there is no
+<quote>negative caching</quote>: Nix doesn't remember that a build
+failed, and so a failed build can always be repeated. This is because
+Nix cannot distinguish between permanent failures (e.g., a compiler
+error due to a syntax error in the source) and transient failures
+(e.g., a disk full condition).</para>
+
+<para>Nix also performs locking. If you run multiple Nix builds
+simultaneously, and they try to build the same derivation, the first
+Nix instance that gets there will perform the build, while the others
+block (or perform other derivations if available) until the build
+finishes:
+
+<screen>
+$ nix-build pkgs/top-level/all-packages.nix -A hello
+waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'</screen>
+
+So it is always safe to run multiple instances of Nix in parallel
+(which isn’t the case with, say, <command>make</command>).</para>
+
+<para>If you have a system with multiple CPUs, you may want to have
+Nix build different derivations in parallel (insofar as possible).
+Just pass the option <link linkend='opt-max-jobs'><option>-j
+<replaceable>N</replaceable></option></link>, where
+<replaceable>N</replaceable> is the maximum number of jobs to be run
+in parallel, or set. Typically this should be the number of
+CPUs.</para>
+
+</section> \ No newline at end of file
diff --git a/doc/manual/expressions/simple-expression.xml b/doc/manual/expressions/simple-expression.xml
new file mode 100644
index 000000000..a8eb96f5a
--- /dev/null
+++ b/doc/manual/expressions/simple-expression.xml
@@ -0,0 +1,47 @@
+<chapter 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="ch-simple-expression">
+
+<title>Simple Nix Expression Use-Case</title>
+
+<para>This section shows how to add and test the <link
+xlink:href='http://www.gnu.org/software/hello/hello.html'>GNU Hello
+package</link> to the Nix Packages collection. Hello is a program
+that prints out the text <quote>Hello, world!</quote>.</para>
+
+<para>To add a package to the Nix Packages collection, you generally
+need to do three things:
+
+<orderedlist>
+
+ <listitem><para>Write a Nix expression for the package. This is a
+ file that describes all the inputs involved in building the package,
+ such as dependencies, sources, and so on.</para></listitem>
+
+ <listitem><para>Write a <emphasis>builder</emphasis>. This is a
+ shell script<footnote><para>In fact, it can be written in any
+ language, but typically it's a <command>bash</command> shell
+ script.</para></footnote> that actually builds the package from
+ the inputs.</para></listitem>
+
+ <listitem><para>Add the package to the file
+ <filename>pkgs/top-level/all-packages.nix</filename>. The Nix
+ expression written in the first step is a
+ <emphasis>function</emphasis>; it requires other packages in order
+ to build it. In this step you put it all together, i.e., you call
+ the function with the right arguments to build the actual
+ package.</para></listitem>
+
+</orderedlist>
+
+</para>
+
+<xi:include href="expression-syntax.xml" />
+<xi:include href="build-script.xml" />
+<xi:include href="arguments-variables.xml" />
+<xi:include href="simple-building-testing.xml" />
+<xi:include href="generic-builder.xml" />
+
+</chapter> \ No newline at end of file
diff --git a/doc/manual/expressions/standard-env.xml b/doc/manual/expressions/standard-env.xml
new file mode 100644
index 000000000..2571f43fc
--- /dev/null
+++ b/doc/manual/expressions/standard-env.xml
@@ -0,0 +1,60 @@
+<chapter 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-standard-environment'>
+
+<title>The Standard Environment</title>
+
+
+<para>The standard environment is used by passing it as an input
+called <envar>stdenv</envar> to the derivation, and then doing
+
+<programlisting>
+source $stdenv/setup</programlisting>
+
+at the top of the builder.</para>
+
+<para>Apart from adding the aforementioned commands to the
+<envar>PATH</envar>, <filename>setup</filename> also does the
+following:
+
+<itemizedlist>
+
+ <listitem><para>All input packages specified in the
+ <envar>buildInputs</envar> environment variable have their
+ <filename>/bin</filename> subdirectory added to <envar>PATH</envar>,
+ their <filename>/include</filename> subdirectory added to the C/C++
+ header file search path, and their <filename>/lib</filename>
+ subdirectory added to the linker search path. This can be extended.
+ For instance, when the <command>pkgconfig</command> package is
+ used, the subdirectory <filename>/lib/pkgconfig</filename> of each
+ input is added to the <envar>PKG_CONFIG_PATH</envar> environment
+ variable.</para></listitem>
+
+ <listitem><para>The environment variable
+ <envar>NIX_CFLAGS_STRIP</envar> is set so that the compiler strips
+ debug information from object files. This can be disabled by
+ setting <envar>NIX_STRIP_DEBUG</envar> to
+ <literal>0</literal>.</para></listitem>
+
+</itemizedlist>
+
+</para>
+
+<para>The <filename>setup</filename> script also exports a function
+called <function>genericBuild</function> that knows how to build
+typical Autoconf-style packages. It can be customised to perform
+builds for any type of package. It is advisable to use
+<function>genericBuild</function> since it provides facilities that
+are almost always useful such as unpacking of sources, patching of
+sources, nested logging, etc.</para>
+
+<para>The definitive, up-to-date documentation of the generic builder
+is the source itself, which resides in
+<filename>pkgs/stdenv/generic/setup.sh</filename>.</para>
+
+<xi:include href="custom-builder.xml" />
+<xi:include href="debug-build.xml" />
+
+</chapter> \ No newline at end of file
diff --git a/doc/manual/expressions/writing-nix-expressions.xml b/doc/manual/expressions/writing-nix-expressions.xml
new file mode 100644
index 000000000..6d64f24cd
--- /dev/null
+++ b/doc/manual/expressions/writing-nix-expressions.xml
@@ -0,0 +1,27 @@
+<part 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='chap-writing-nix-expressions'>
+
+<title>Nix Expressions</title>
+
+<partintro>
+<para>This chapter shows you how to write Nix expressions, which
+instruct Nix how to build packages. It starts with a
+simple example (a Nix expression for GNU Hello), and then moves
+on to a more in-depth look at the Nix expression language.</para>
+
+<note><para>This chapter is mostly about the Nix expression language.
+For more extensive information on adding packages to the Nix Packages
+collection (such as functions in the standard environment and coding
+conventions), please consult <link
+xlink:href="http://nixos.org/nixpkgs/manual/">its
+manual</link>.</para></note>
+</partintro>
+
+<xi:include href="simple-expression.xml" />
+<xi:include href="expression-language.xml" />
+<xi:include href="standard-env.xml" />
+
+</part>