aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/src/expressions
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-09-15 20:33:44 +0200
committerGitHub <noreply@github.com>2021-09-15 20:33:44 +0200
commit79152e307e7eef667c3de9c21571d017654a7c32 (patch)
tree67fd413bcf0b42c5ada7eddc41a04f7bd99df3a8 /doc/manual/src/expressions
parent7349f257da8278af9aae35544b15c9a204e2a57b (diff)
parent3b82c1a5fef521ebadea5df12384390c8c24100c (diff)
Merge pull request #5212 from mkenigs/auto-uid-allocation
Merge master into #3600
Diffstat (limited to 'doc/manual/src/expressions')
-rw-r--r--doc/manual/src/expressions/advanced-attributes.md257
-rw-r--r--doc/manual/src/expressions/arguments-variables.md80
-rw-r--r--doc/manual/src/expressions/build-script.md70
-rw-r--r--doc/manual/src/expressions/builtin-constants.md20
-rw-r--r--doc/manual/src/expressions/builtins-prefix.md16
-rw-r--r--doc/manual/src/expressions/builtins-suffix.md1
-rw-r--r--doc/manual/src/expressions/derivations.md161
-rw-r--r--doc/manual/src/expressions/expression-language.md12
-rw-r--r--doc/manual/src/expressions/expression-syntax.md93
-rw-r--r--doc/manual/src/expressions/generic-builder.md66
-rw-r--r--doc/manual/src/expressions/language-constructs.md350
-rw-r--r--doc/manual/src/expressions/language-operators.md28
-rw-r--r--doc/manual/src/expressions/language-values.md251
-rw-r--r--doc/manual/src/expressions/simple-building-testing.md61
-rw-r--r--doc/manual/src/expressions/simple-expression.md23
-rw-r--r--doc/manual/src/expressions/writing-nix-expressions.md12
16 files changed, 1501 insertions, 0 deletions
diff --git a/doc/manual/src/expressions/advanced-attributes.md b/doc/manual/src/expressions/advanced-attributes.md
new file mode 100644
index 000000000..5b208df67
--- /dev/null
+++ b/doc/manual/src/expressions/advanced-attributes.md
@@ -0,0 +1,257 @@
+# Advanced Attributes
+
+Derivations can declare some infrequently used optional attributes.
+
+ - `allowedReferences`\
+ The optional attribute `allowedReferences` specifies a list of legal
+ references (dependencies) of the output of the builder. For example,
+
+ ```nix
+ allowedReferences = [];
+ ```
+
+ 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 `"out"` 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.
+
+ - `allowedRequisites`\
+ This attribute is similar to `allowedReferences`, but it specifies
+ the legal requisites of the whole closure, so all the dependencies
+ recursively. For example,
+
+ ```nix
+ allowedRequisites = [ foobar ];
+ ```
+
+ enforces that the output of a derivation cannot have any other
+ runtime dependency than `foobar`, and in addition it enforces that
+ `foobar` itself doesn't introduce any other dependency itself.
+
+ - `disallowedReferences`\
+ The optional attribute `disallowedReferences` specifies a list of
+ illegal references (dependencies) of the output of the builder. For
+ example,
+
+ ```nix
+ disallowedReferences = [ foo ];
+ ```
+
+ enforces that the output of a derivation cannot have a direct
+ runtime dependencies on the derivation `foo`.
+
+ - `disallowedRequisites`\
+ This attribute is similar to `disallowedReferences`, but it
+ specifies illegal requisites for the whole closure, so all the
+ dependencies recursively. For example,
+
+ ```nix
+ disallowedRequisites = [ foobar ];
+ ```
+
+ enforces that the output of a derivation cannot have any runtime
+ dependency on `foobar` or any other derivation depending recursively
+ on `foobar`.
+
+ - `exportReferencesGraph`\
+ 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 `[ name1 path1 name2
+ path2 ... ]`. The references graph of each *pathN* will be stored
+ in a text file *nameN* in the temporary build directory. The text
+ files have the format used by `nix-store --register-validity`
+ (with the deriver fields left empty). For example, when the
+ following derivation is built:
+
+ ```nix
+ derivation {
+ ...
+ exportReferencesGraph = [ "libfoo-graph" libfoo ];
+ };
+ ```
+
+ the references graph of `libfoo` is placed in the file
+ `libfoo-graph` in the temporary build directory.
+
+ `exportReferencesGraph` 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 `cpio` 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).
+
+ - `impureEnvVars`\
+ 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,
+ `fetchurl` in Nixpkgs has the line
+
+ ```nix
+ impureEnvVars = [ "http_proxy" "https_proxy" ... ];
+ ```
+
+ to make it use the proxy server configuration specified by the user
+ in the environment variables `http_proxy` and friends.
+
+ This attribute is only allowed in *fixed-output derivations* (see
+ below), where impurities such as these are okay since (the hash
+ of) the output is known in advance. It is ignored for all other
+ derivations.
+
+ > **Warning**
+ >
+ > `impureEnvVars` implementation takes environment variables from
+ > the current builder process. When a daemon is building its
+ > environmental variables are used. Without the daemon, the
+ > environmental variables come from the environment of the
+ > `nix-build`.
+
+ - `outputHash`; `outputHashAlgo`; `outputHashMode`\
+ These attributes declare that the derivation is a so-called
+ *fixed-output derivation*, 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.
+
+ The rationale for fixed-output derivations is derivations such as
+ those produced by the `fetchurl` 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,
+
+ ```nix
+ fetchurl {
+ url = "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ }
+ ```
+
+ 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 `fetchurl`, e.g.,
+
+ ```nix
+ fetchurl {
+ url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ }
+ ```
+
+ If a `fetchurl` derivation was treated like a normal derivation, the
+ output paths of the derivation and *all derivations depending on it*
+ 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.
+
+ For fixed-output derivations, on the other hand, the name of the
+ output path only depends on the `outputHash*` and `name` attributes,
+ while all other attributes are ignored for the purpose of computing
+ the output path. (The `name` attribute is included because it is
+ part of the path.)
+
+ As an example, here is the (simplified) Nix expression for
+ `fetchurl`:
+
+ ```nix
+ { stdenv, curl }: # The curl program is used for downloading.
+
+ { url, sha256 }:
+
+ 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 SHA256 hash sha256.
+ outputHashMode = "flat";
+ outputHashAlgo = "sha256";
+ outputHash = sha256;
+
+ inherit url;
+ }
+ ```
+
+ The `outputHashAlgo` attribute specifies the hash algorithm used to
+ compute the hash. It can currently be `"sha1"`, `"sha256"` or
+ `"sha512"`.
+
+ The `outputHashMode` attribute determines how the hash is computed.
+ It must be one of the following two values:
+
+ - `"flat"`\
+ 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
+ `sha256sum` or `sha1sum` produce).
+
+ This is the default.
+
+ - `"recursive"`\
+ The hash is computed over the NAR archive dump of the output
+ (i.e., the result of [`nix-store
+ --dump`](../command-ref/nix-store.md#operation---dump)). In
+ this case, the output can be anything, including a directory
+ tree.
+
+ The `outputHash` attribute, finally, must be a string containing
+ the hash in either hexadecimal or base-32 notation. (See the
+ [`nix-hash` command](../command-ref/nix-hash.md) for information
+ about converting to and from base-32 notation.)
+
+ - `__contentAddressed`
+ If this **experimental** attribute is set to true, then the derivation
+ outputs will be stored in a content-addressed location rather than the
+ traditional input-addressed one.
+ This only has an effect if the `ca-derivation` experimental feature is enabled.
+
+ Setting this attribute also requires setting `outputHashMode` and `outputHashAlgo` like for *fixed-output derivations* (see above).
+
+ - `passAsFile`\
+ A list of names of attributes that should be passed via files rather
+ than environment variables. For example, if you have
+
+ ```nix
+ passAsFile = ["big"];
+ big = "a very long string";
+ ```
+
+ then when the builder runs, the environment variable `bigPath`
+ will contain the absolute path to a temporary file containing `a
+ very long string`. That is, for any attribute *x* listed in
+ `passAsFile`, Nix will pass an environment variable `xPath`
+ holding the path of the file containing the value of attribute
+ *x*. This is useful when you need to pass large strings to a
+ builder, since most operating systems impose a limit on the size
+ of the environment (typically, a few hundred kilobyte).
+
+ - `preferLocalBuild`\
+ If this attribute is set to `true` and [distributed building is
+ enabled](../advanced-topics/distributed-builds.md), 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.
+
+ - `allowSubstitutes`\
+ If this attribute is set to `false`, then Nix will always build this
+ derivation; it will not try to substitute its outputs. This is
+ useful for very trivial derivations (such as `writeText` in Nixpkgs)
+ that are cheaper to build than to substitute from a binary cache.
+
+ > **Note**
+ >
+ > You need to have a builder configured which satisfies the
+ > derivation’s `system` attribute, since the derivation cannot be
+ > substituted. Thus it is usually a good idea to align `system` with
+ > `builtins.currentSystem` when setting `allowSubstitutes` to
+ > `false`. For most trivial derivations this should be the case.
diff --git a/doc/manual/src/expressions/arguments-variables.md b/doc/manual/src/expressions/arguments-variables.md
new file mode 100644
index 000000000..12198c879
--- /dev/null
+++ b/doc/manual/src/expressions/arguments-variables.md
@@ -0,0 +1,80 @@
+# Arguments and Variables
+
+The [Nix expression for GNU Hello](expression-syntax.md) 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
+`pkgs/top-level/all-packages.nix`, where all Nix expressions for
+packages are imported and called with the appropriate arguments. Here
+are some fragments of `all-packages.nix`, with annotations of what
+they mean:
+
+```nix
+...
+
+rec { ①
+
+ hello = import ../applications/misc/hello/ex-1 ② { ③
+ inherit fetchurl stdenv perl;
+ };
+
+ perl = import ../development/interpreters/perl { ④
+ inherit fetchurl stdenv;
+ };
+
+ fetchurl = import ../build-support/fetchurl {
+ inherit stdenv; ...
+ };
+
+ stdenv = ...;
+
+}
+```
+
+1. This file defines a set of attributes, all of which are concrete
+ derivations (i.e., not functions). In fact, we define a *mutually
+ recursive* set of attributes. That is, the attributes can refer to
+ each other. This is precisely what we want since we want to “plug”
+ the various packages into each other.
+
+2. Here we *import* 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 the Nix expression
+ for GNU Hello in `all-packages.nix` at this point. That would be
+ completely equivalent, but it would make `all-packages.nix` rather
+ bulky.
+
+ Note that we refer to `../applications/misc/hello/ex-1`, not
+ `../applications/misc/hello/ex-1/default.nix`. When you try to
+ import a directory, Nix automatically appends `/default.nix` to the
+ file name.
+
+3. This is where the actual composition takes place. Here we *call* the
+ function imported from `../applications/misc/hello/ex-1` with a set
+ containing the things that the function expects, namely `fetchurl`,
+ `stdenv`, and `perl`. We use inherit again to use the attributes
+ defined in the surrounding scope (we could also have written
+ `fetchurl = fetchurl;`, etc.).
+
+ 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 `stdenv.mkDerivation`
+ in the [Nix expression for GNU Hello](expression-syntax.md)).
+
+ > **Note**
+ >
+ > Nixpkgs has a convenience function `callPackage` that imports and
+ > calls a function, filling in any missing arguments by passing the
+ > corresponding attribute from the Nixpkgs set, like this:
+ >
+ > ```nix
+ > hello = callPackage ../applications/misc/hello/ex-1 { };
+ > ```
+ >
+ > If necessary, you can set or override arguments:
+ >
+ > ```nix
+ > hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
+ > ```
+
+4. Likewise, we have to instantiate Perl, `fetchurl`, and the standard
+ environment.
diff --git a/doc/manual/src/expressions/build-script.md b/doc/manual/src/expressions/build-script.md
new file mode 100644
index 000000000..b1eacae88
--- /dev/null
+++ b/doc/manual/src/expressions/build-script.md
@@ -0,0 +1,70 @@
+# Build Script
+
+Here is the builder referenced from Hello's Nix expression (stored in
+`pkgs/applications/misc/hello/ex-1/builder.sh`):
+
+```bash
+source $stdenv/setup ①
+
+PATH=$perl/bin:$PATH ②
+
+tar xvfz $src ③
+cd hello-*
+./configure --prefix=$out ④
+make ⑤
+make install
+```
+
+The builder can actually be made a lot shorter by using the *generic
+builder* functions provided by `stdenv`, but here we write out the build
+steps to elucidate what a builder does. It performs the following steps:
+
+1. When Nix runs a builder, it initially completely clears the
+ environment (except for the attributes declared in the derivation).
+ This is done to prevent undeclared inputs from being used in the
+ build process. If for example the `PATH` contained `/usr/bin`, then
+ you might accidentally use `/usr/bin/gcc`.
+
+ So the first step is to set up the environment. This is done by
+ calling the `setup` script of the standard environment. The
+ environment variable `stdenv` points to the location of the
+ standard environment being used. (It wasn't specified explicitly
+ as an attribute in Hello's Nix expression, but `mkDerivation` adds
+ it automatically.)
+
+2. Since Hello needs Perl, we have to make sure that Perl is in the
+ `PATH`. The `perl` environment variable points to the location of
+ the Perl package (since it was passed in as an attribute to the
+ derivation), so `$perl/bin` is the directory containing the Perl
+ interpreter.
+
+3. Now we have to unpack the sources. The `src` attribute was bound to
+ the result of fetching the Hello source tarball from the network, so
+ the `src` environment variable points to the location in the Nix
+ store to which the tarball was downloaded. After unpacking, we `cd`
+ to the resulting source directory.
+
+ The whole build is performed in a temporary directory created in
+ `/tmp`, 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.
+
+4. GNU Hello is a typical Autoconf-based package, so we first have to
+ run its `configure` script. In Nix every package is stored in a
+ separate location in the Nix store, for instance
+ `/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1`. Nix
+ computes this path by cryptographically hashing all attributes of
+ the derivation. The path is passed to the builder through the `out`
+ environment variable. So here we give `configure` the parameter
+ `--prefix=$out` to cause Hello to be installed in the expected
+ location.
+
+5. Finally we build Hello (`make`) and install it into the location
+ specified by `out` (`make install`).
+
+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 `-e` option, which causes the script to
+be aborted if any command fails without an error check.
diff --git a/doc/manual/src/expressions/builtin-constants.md b/doc/manual/src/expressions/builtin-constants.md
new file mode 100644
index 000000000..1404289e5
--- /dev/null
+++ b/doc/manual/src/expressions/builtin-constants.md
@@ -0,0 +1,20 @@
+# Built-in Constants
+
+Here are the constants built into the Nix expression evaluator:
+
+ - `builtins`\
+ The set `builtins` contains all the built-in functions and values.
+ You can use `builtins` to test for the availability of features in
+ the Nix installation, e.g.,
+
+ ```nix
+ if builtins ? getEnv then builtins.getEnv "PATH" else ""
+ ```
+
+ This allows a Nix expression to fall back gracefully on older Nix
+ installations that don’t have the desired built-in function.
+
+ - `builtins.currentSystem`\
+ The built-in value `currentSystem` evaluates to the Nix platform
+ identifier for the Nix installation on which the expression is being
+ evaluated, such as `"i686-linux"` or `"x86_64-darwin"`.
diff --git a/doc/manual/src/expressions/builtins-prefix.md b/doc/manual/src/expressions/builtins-prefix.md
new file mode 100644
index 000000000..87127de2a
--- /dev/null
+++ b/doc/manual/src/expressions/builtins-prefix.md
@@ -0,0 +1,16 @@
+# Built-in Functions
+
+This section lists the functions built into the Nix expression
+evaluator. (The built-in function `derivation` is discussed above.)
+Some built-ins, such as `derivation`, 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 `builtins` built-in
+value, which is a set that contains all built-in functions and values.
+For instance, `derivation` is also available as `builtins.derivation`.
+
+<dl>
+ <dt><code>derivation <var>attrs</var></code>;
+ <code>builtins.derivation <var>attrs</var></code></dt>
+ <dd><p><var>derivation</var> in described in
+ <a href="derivations.md">its own section</a>.</p></dd>
diff --git a/doc/manual/src/expressions/builtins-suffix.md b/doc/manual/src/expressions/builtins-suffix.md
new file mode 100644
index 000000000..a74db2857
--- /dev/null
+++ b/doc/manual/src/expressions/builtins-suffix.md
@@ -0,0 +1 @@
+</dl>
diff --git a/doc/manual/src/expressions/derivations.md b/doc/manual/src/expressions/derivations.md
new file mode 100644
index 000000000..d26a33b7f
--- /dev/null
+++ b/doc/manual/src/expressions/derivations.md
@@ -0,0 +1,161 @@
+# Derivations
+
+The most important built-in function is `derivation`, 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.
+
+ - There must be an attribute named `system` whose value must be a
+ string specifying a Nix system type, such as `"i686-linux"` or
+ `"x86_64-darwin"`. (To figure out your system type, run `nix -vv
+ --version`.) The build can only be performed on a machine and
+ operating system matching the system type. (Nix can automatically
+ [forward builds for other
+ platforms](../advanced-topics/distributed-builds.md) by forwarding
+ them to other machines.)
+
+ - There must be an attribute named `name` whose value must be a
+ string. This is used as a symbolic name for the package by
+ `nix-env`, and it is appended to the output paths of the derivation.
+
+ - There must be an attribute named `builder` 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.,
+ `./builder.sh`).
+
+ - Every attribute is passed as an environment variable to the builder.
+ Attribute values are translated to environment variables as follows:
+
+ - Strings and numbers are just passed verbatim.
+
+ - A *path* (e.g., `../foo/sources.tar`) 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.
+
+ - A *derivation* causes that derivation to be built prior to the
+ present derivation; its default output path is put in the
+ environment variable.
+
+ - Lists of the previous types are also allowed. They are simply
+ concatenated, separated by spaces.
+
+ - `true` is passed as the string `1`, `false` and `null` are
+ passed as an empty string.
+
+ - The optional attribute `args` specifies command-line arguments to be
+ passed to the builder. It should be a list.
+
+ - The optional attribute `outputs` specifies a list of symbolic
+ outputs of the derivation. By default, a derivation produces a
+ single output path, denoted as `out`. 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:
+
+ ```nix
+ outputs = [ "lib" "headers" "doc" ];
+ ```
+
+ This will cause Nix to pass environment variables `lib`, `headers`
+ and `doc` to the builder containing the intended store paths of each
+ output. The builder would typically do something like
+
+ ```bash
+ ./configure \
+ --libdir=$lib/lib \
+ --includedir=$headers/include \
+ --docdir=$doc/share/doc
+ ```
+
+ for an Autoconf-style package. You can refer to each output of a
+ derivation by selecting it as an attribute, e.g.
+
+ ```nix
+ buildInputs = [ pkg.lib pkg.headers ];
+ ```
+
+ The first element of `outputs` determines the *default output*.
+ Thus, you could also write
+
+ ```nix
+ buildInputs = [ pkg pkg.headers ];
+ ```
+
+ since `pkg` is equivalent to `pkg.lib`.
+
+The function `mkDerivation` in the Nixpkgs standard environment is a
+wrapper around `derivation` that adds a default value for `system` and
+always uses Bash as the builder, to which the supplied builder is passed
+as a command-line argument. See the Nixpkgs manual for details.
+
+The builder is executed as follows:
+
+ - A temporary directory is created under the directory specified by
+ `TMPDIR` (default `/tmp`) where the build will take place. The
+ current directory is changed to this directory.
+
+ - The environment is cleared and set to the derivation attributes, as
+ specified above.
+
+ - In addition, the following variables are set:
+
+ - `NIX_BUILD_TOP` contains the path of the temporary directory for
+ this build.
+
+ - Also, `TMPDIR`, `TEMPDIR`, `TMP`, `TEMP` 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.
+
+ - `PATH` is set to `/path-not-set` to prevent shells from
+ initialising it to their built-in default value.
+
+ - `HOME` is set to `/homeless-shelter` to prevent programs from
+ using `/etc/passwd` or the like to find the user's home
+ directory, which could cause impurity. Usually, when `HOME` is
+ set, it is used as the location of the home directory, even if
+ it points to a non-existent path.
+
+ - `NIX_STORE` is set to the path of the top-level Nix store
+ directory (typically, `/nix/store`).
+
+ - For each output declared in `outputs`, 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 `name`
+ attribute and the output name. (The output name is omitted if
+ it’s `out`.)
+
+ - 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.
+
+ - A log of the combined standard output and error is written to
+ `/nix/var/log/nix`.
+
+ - The builder is executed with the arguments specified by the
+ attribute `args`. If it exits with exit code 0, it is considered to
+ have succeeded.
+
+ - The temporary directory is removed (unless the `-K` option was
+ specified).
+
+ - 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.
+
+ - 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 `setuid` and `setgid`
+ 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.
diff --git a/doc/manual/src/expressions/expression-language.md b/doc/manual/src/expressions/expression-language.md
new file mode 100644
index 000000000..267fcb983
--- /dev/null
+++ b/doc/manual/src/expressions/expression-language.md
@@ -0,0 +1,12 @@
+# Nix Expression Language
+
+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 “normal” 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.
+
+This section presents the various features of the language.
diff --git a/doc/manual/src/expressions/expression-syntax.md b/doc/manual/src/expressions/expression-syntax.md
new file mode 100644
index 000000000..2a1306e32
--- /dev/null
+++ b/doc/manual/src/expressions/expression-syntax.md
@@ -0,0 +1,93 @@
+# Expression Syntax
+
+Here is a Nix expression for GNU Hello:
+
+```nix
+{ stdenv, fetchurl, perl }: ①
+
+stdenv.mkDerivation { ②
+ name = "hello-2.1.1"; ③
+ builder = ./builder.sh; ④
+ src = fetchurl { ⑤
+ url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ };
+ inherit perl; ⑥
+}
+```
+
+This file is actually already in the Nix Packages collection in
+`pkgs/applications/misc/hello/ex-1/default.nix`. It is customary to
+place each package in a separate directory and call the single Nix
+expression in that directory `default.nix`. The file has the following
+elements (referenced from the figure by number):
+
+1. This states that the expression is a *function* that expects to be
+ called with three arguments: `stdenv`, `fetchurl`, and `perl`. They
+ are needed to build Hello, but we don't know how to build them here;
+ that's why they are function arguments. `stdenv` is a package that
+ is used by almost all Nix Packages packages; it provides a
+ “standard” 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 `cp`, `grep`, `tar`,
+ etc. `fetchurl` is a function that downloads files. `perl` is the
+ Perl interpreter.
+
+ Nix functions generally have the form `{ x, y, ..., z }: e` where
+ `x`, `y`, etc. are the names of the expected arguments, and where
+ *e* 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.
+
+2. So we have to build a package. Building something from other stuff
+ is called a *derivation* in Nix (as opposed to sources, which are
+ built by humans instead of computers). We perform a derivation by
+ calling `stdenv.mkDerivation`. `mkDerivation` is a function
+ provided by `stdenv` that builds a package from a set of
+ *attributes*. 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 `{ name1 = expr1; ...
+ nameN = exprN; }`.
+
+3. The attribute `name` specifies the symbolic name and version of
+ the package. Nix doesn't really care about these things, but they
+ are used by for instance `nix-env -q` to show a “human-readable”
+ name for packages. This attribute is required by `mkDerivation`.
+
+4. The attribute `builder` specifies the builder. This attribute can
+ sometimes be omitted, in which case `mkDerivation` will fill in a
+ default builder (which does a `configure; make; make install`, 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 `./builder.sh` refers to the
+ shell script shown in the [next section](build-script.md),
+ discussed below.
+
+5. The builder has to know what the sources of the package are. Here,
+ the attribute `src` is bound to the result of a call to the
+ `fetchurl` function. Given a URL and a SHA-256 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.
+
+ Instead of `src` any other name could have been used, and in fact
+ there can be any number of sources (bound to different attributes).
+ However, `src` is customary, and it's also expected by the default
+ builder (which we don't use in this example).
+
+6. Since the derivation requires Perl, we have to pass the value of the
+ `perl` function argument to the builder. All attributes in the set
+ are actually passed as environment variables to the builder, so
+ declaring an attribute
+
+ ```nix
+ perl = perl;
+ ```
+
+ will do the trick: it binds an attribute `perl` to the function
+ argument which also happens to be called `perl`. However, it looks a
+ bit silly, so there is a shorter syntax. The `inherit` keyword
+ causes the specified attributes to be bound to whatever variables
+ with the same name happen to be in scope.
diff --git a/doc/manual/src/expressions/generic-builder.md b/doc/manual/src/expressions/generic-builder.md
new file mode 100644
index 000000000..cf26b5f82
--- /dev/null
+++ b/doc/manual/src/expressions/generic-builder.md
@@ -0,0 +1,66 @@
+# Generic Builder Syntax
+
+Recall that the [build script for GNU Hello](build-script.md) looked
+something like this:
+
+```bash
+PATH=$perl/bin:$PATH
+tar xvfz $src
+cd hello-*
+./configure --prefix=$out
+make
+make install
+```
+
+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. Here is what a builder using
+the generic build facilities looks like:
+
+```bash
+buildInputs="$perl" ①
+
+source $stdenv/setup ②
+
+genericBuild ③
+```
+
+Here is what each line means:
+
+1. The `buildInputs` variable tells `setup` to use the indicated
+ packages as “inputs”. This means that if a package provides a `bin`
+ subdirectory, it's added to `PATH`; if it has a `include`
+ subdirectory, it's added to GCC's header search path; and so on.
+ (This is implemented in a modular way: `setup` tries to source the
+ file `pkg/nix-support/setup-hook` of all dependencies. These “setup
+ hooks” can then set up whatever environment variables they want; for
+ instance, the setup hook for Perl sets the `PERL5LIB` environment
+ variable to contain the `lib/site_perl` directories of all inputs.)
+
+2. The function `genericBuild` is defined in the file `$stdenv/setup`.
+
+3. The final step calls the shell function `genericBuild`, which
+ performs the steps that were done explicitly in the previous build
+ script. The generic builder is smart enough to figure out whether
+ to unpack the sources using `gzip`, `bzip2`, etc. It can be
+ customised in many ways; see the Nixpkgs manual for details.
+
+Discerning readers will note that the `buildInputs` could just as well
+have been set in the Nix expression, like this:
+
+```nix
+ buildInputs = [ perl ];
+```
+
+The `perl` attribute can then be removed, and the builder becomes even
+shorter:
+
+```bash
+source $stdenv/setup
+genericBuild
+```
+
+In fact, `mkDerivation` provides a default builder that looks exactly
+like that, so it is actually possible to omit the builder for Hello
+entirely.
diff --git a/doc/manual/src/expressions/language-constructs.md b/doc/manual/src/expressions/language-constructs.md
new file mode 100644
index 000000000..cb0169239
--- /dev/null
+++ b/doc/manual/src/expressions/language-constructs.md
@@ -0,0 +1,350 @@
+# Language Constructs
+
+## Recursive sets
+
+Recursive sets are just normal sets, but the attributes can refer to
+each other. For example,
+
+```nix
+rec {
+ x = y;
+ y = 123;
+}.x
+```
+
+evaluates to `123`. Note that without `rec` the binding `x = y;` would
+refer to the variable `y` 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.
+
+Recursive sets of course introduce the danger of infinite recursion. For
+example, the expression
+
+```nix
+rec {
+ x = y;
+ y = x;
+}.x
+```
+
+will crash with an `infinite recursion encountered` error message.
+
+## Let-expressions
+
+A let-expression allows you to define local variables for an expression.
+For instance,
+
+```nix
+let
+ x = "foo";
+ y = "bar";
+in x + y
+```
+
+evaluates to `"foobar"`.
+
+## Inheriting attributes
+
+When defining a set or in a let-expression 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 `inherit`
+keyword. For instance,
+
+```nix
+let x = 123; in
+{ inherit x;
+ y = 456;
+}
+```
+
+is equivalent to
+
+```nix
+let x = 123; in
+{ x = x;
+ y = 456;
+}
+```
+
+and both evaluate to `{ x = 123; y = 456; }`. (Note that this works
+because `x` is added to the lexical scope by the `let` construct.) It is
+also possible to inherit attributes from another set. For instance, in
+this fragment from `all-packages.nix`,
+
+```nix
+graphviz = (import ../tools/graphics/graphviz) {
+ inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
+ inherit (xlibs) libXaw;
+};
+
+xlibs = {
+ libX11 = ...;
+ libXaw = ...;
+ ...
+}
+
+libpng = ...;
+libjpg = ...;
+...
+```
+
+the set used in the function call to the function defined in
+`../tools/graphics/graphviz` inherits a number of variables from the
+surrounding scope (`fetchurl` ... `yacc`), but also inherits `libXaw`
+(the X Athena Widgets) from the `xlibs` (X11 client-side libraries) set.
+
+Summarizing the fragment
+
+```nix
+...
+inherit x y z;
+inherit (src-set) a b c;
+...
+```
+
+is equivalent to
+
+```nix
+...
+x = x; y = y; z = z;
+a = src-set.a; b = src-set.b; c = src-set.c;
+...
+```
+
+when used while defining local variables in a let-expression or while
+defining a set.
+
+## Functions
+
+Functions have the following form:
+
+```nix
+pattern: body
+```
+
+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:
+
+ - If a pattern is a single identifier, then the function matches any
+ argument. Example:
+
+ ```nix
+ let negate = x: !x;
+ concat = x: y: x + y;
+ in if negate true then concat "foo" "bar" else ""
+ ```
+
+ Note that `concat` 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.,
+
+ ```nix
+ map (concat "foo") [ "bar" "bla" "abc" ]
+ ```
+
+ evaluates to `[ "foobar" "foobla" "fooabc" ]`.
+
+ - A *set pattern* of the form `{ name1, name2, …, nameN }` matches a
+ set containing the listed attributes, and binds the values of those
+ attributes to variables in the function body. For example, the
+ function
+
+ ```nix
+ { x, y, z }: z + y + x
+ ```
+
+ can only be called with a set containing exactly the attributes `x`,
+ `y` and `z`. No other attributes are allowed. If you want to allow
+ additional arguments, you can use an ellipsis (`...`):
+
+ ```nix
+ { x, y, z, ... }: z + y + x
+ ```
+
+ This works on any set that contains at least the three named
+ attributes.
+
+ It is possible to provide *default values* for attributes, in
+ which case they are allowed to be missing. A default value is
+ specified by writing `name ? e`, where *e* is an arbitrary
+ expression. For example,
+
+ ```nix
+ { x, y ? "foo", z ? "bar" }: z + y + x
+ ```
+
+ specifies a function that only requires an attribute named `x`, but
+ optionally accepts `y` and `z`.
+
+ - An `@`-pattern provides a means of referring to the whole value
+ being matched:
+
+ ```nix
+ args@{ x, y, z, ... }: z + y + x + args.a
+ ```
+
+ but can also be written as:
+
+ ```nix
+ { x, y, z, ... } @ args: z + y + x + args.a
+ ```
+
+ Here `args` is bound to the entire argument, which is further
+ matched against the pattern `{ x, y, z,
+ ... }`. `@`-pattern makes mainly sense with an ellipsis(`...`) as
+ you can access attribute names as `a`, using `args.a`, which was
+ given as an additional attribute to the function.
+
+ > **Warning**
+ >
+ > The `args@` expression is bound to the argument passed to the
+ > function which means that attributes with defaults that aren't
+ > explicitly specified in the function call won't cause an
+ > evaluation error, but won't exist in `args`.
+ >
+ > For instance
+ >
+ > ```nix
+ > let
+ > function = args@{ a ? 23, ... }: args;
+ > in
+ > function {}
+ > ````
+ >
+ > will evaluate to an empty attribute set.
+
+Note that functions do not have names. If you want to give them a name,
+you can bind them to an attribute, e.g.,
+
+```nix
+let concat = { x, y }: x + y;
+in concat { x = "foo"; y = "bar"; }
+```
+
+## Conditionals
+
+Conditionals look like this:
+
+```nix
+if e1 then e2 else e3
+```
+
+where *e1* is an expression that should evaluate to a Boolean value
+(`true` or `false`).
+
+## Assertions
+
+Assertions are generally used to check that certain requirements on or
+between features and dependencies hold. They look like this:
+
+```nix
+assert e1; e2
+```
+
+where *e1* is an expression that should evaluate to a Boolean value. If
+it evaluates to `true`, *e2* is returned; otherwise expression
+evaluation is aborted and a backtrace is printed.
+
+Here is a Nix expression for the Subversion package that shows how
+assertions can be used:.
+
+```nix
+{ 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; ①
+assert httpServer -> httpd != null && httpd.expat == expat; ②
+assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); ③
+assert pythonBindings -> swig != null && swig.pythonSupport;
+assert javaSwigBindings -> swig != null && swig.javaSupport;
+assert javahlBindings -> j2sdk != null;
+
+stdenv.mkDerivation {
+ name = "subversion-1.1.1";
+ ...
+ openssl = if sslSupport then openssl else null; ④
+ ...
+}
+```
+
+The points of interest are:
+
+1. 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 `localServer` argument set to `true` but
+ the `db4` argument set to `null`, then the evaluation fails.
+
+2. This is a more subtle condition: if Subversion is built with Apache
+ (`httpServer`) 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.
+
+3. This assertion says that in order for Subversion to have SSL support
+ (so that it can access `https` URLs), an OpenSSL library must be
+ passed. Additionally, it says that *if* 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.)
+
+4. 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-`null` value was passed. This prevents an unnecessary rebuild of
+ Subversion if OpenSSL changes.
+
+## With-expressions
+
+A *with-expression*,
+
+```nix
+with e1; e2
+```
+
+introduces the set *e1* into the lexical scope of the expression *e2*.
+For instance,
+
+```nix
+let as = { x = "foo"; y = "bar"; };
+in with as; x + y
+```
+
+evaluates to `"foobar"` since the `with` adds the `x` and `y` attributes
+of `as` to the lexical scope in the expression `x + y`. The most common
+use of `with` is in conjunction with the `import` function. E.g.,
+
+```nix
+with (import ./definitions.nix); ...
+```
+
+makes all attributes defined in the file `definitions.nix` available as
+if they were defined locally in a `let`-expression.
+
+The bindings introduced by `with` do not shadow bindings introduced by
+other means, e.g.
+
+```nix
+let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...
+```
+
+establishes the same scope as
+
+```nix
+let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...
+```
+
+## Comments
+
+Comments can be single-line, started with a `#` character, or
+inline/multi-line, enclosed within `/* ... */`.
diff --git a/doc/manual/src/expressions/language-operators.md b/doc/manual/src/expressions/language-operators.md
new file mode 100644
index 000000000..b7fd6f4c6
--- /dev/null
+++ b/doc/manual/src/expressions/language-operators.md
@@ -0,0 +1,28 @@
+# Operators
+
+The table below lists the operators in the Nix expression language, in
+order of precedence (from strongest to weakest binding).
+
+| Name | Syntax | Associativity | Description | Precedence |
+| ------------------------ | ----------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| Select | *e* `.` *attrpath* \[ `or` *def* \] | none | Select attribute denoted by the attribute path *attrpath* from set *e*. (An attribute path is a dot-separated list of attribute names.) If the attribute doesn’t exist, return *def* if provided, otherwise abort evaluation. | 1 |
+| Application | *e1* *e2* | left | Call function *e1* with argument *e2*. | 2 |
+| Arithmetic Negation | `-` *e* | none | Arithmetic negation. | 3 |
+| Has Attribute | *e* `?` *attrpath* | none | Test whether set *e* contains the attribute denoted by *attrpath*; return `true` or `false`. | 4 |
+| List Concatenation | *e1* `++` *e2* | right | List concatenation. | 5 |
+| Multiplication | *e1* `*` *e2*, | left | Arithmetic multiplication. | 6 |
+| Division | *e1* `/` *e2* | left | Arithmetic division. | 6 |
+| Addition | *e1* `+` *e2* | left | Arithmetic addition. | 7 |
+| Subtraction | *e1* `-` *e2* | left | Arithmetic subtraction. | 7 |
+| String Concatenation | *string1* `+` *string2* | left | String concatenation. | 7 |
+| Not | `!` *e* | none | Boolean negation. | 8 |
+| Update | *e1* `//` *e2* | right | Return a set consisting of the attributes in *e1* and *e2* (with the latter taking precedence over the former in case of equally named attributes). | 9 |
+| Less Than | *e1* `<` *e2*, | none | Arithmetic comparison. | 10 |
+| Less Than or Equal To | *e1* `<=` *e2* | none | Arithmetic comparison. | 10 |
+| Greater Than | *e1* `>` *e2* | none | Arithmetic comparison. | 10 |
+| Greater Than or Equal To | *e1* `>=` *e2* | none | Arithmetic comparison. | 10 |
+| Equality | *e1* `==` *e2* | none | Equality. | 11 |
+| Inequality | *e1* `!=` *e2* | none | Inequality. | 11 |
+| Logical AND | *e1* `&&` *e2* | left | Logical AND. | 12 |
+| Logical OR | *e1* `\|\|` *e2* | left | Logical OR. | 13 |
+| Logical Implication | *e1* `->` *e2* | none | Logical implication (equivalent to `!e1 \|\| e2`). | 14 |
diff --git a/doc/manual/src/expressions/language-values.md b/doc/manual/src/expressions/language-values.md
new file mode 100644
index 000000000..28fa23b58
--- /dev/null
+++ b/doc/manual/src/expressions/language-values.md
@@ -0,0 +1,251 @@
+# Values
+
+## Simple Values
+
+Nix has the following basic data types:
+
+ - *Strings* can be written in three ways.
+
+ The most common way is to enclose the string between double quotes,
+ e.g., `"foo bar"`. Strings can span multiple lines. The special
+ characters `"` and `\` and the character sequence `${` must be
+ escaped by prefixing them with a backslash (`\`). Newlines, carriage
+ returns and tabs can be written as `\n`, `\r` and `\t`,
+ respectively.
+
+ You can include the result of an expression into a string by
+ enclosing it in `${...}`, a feature known as *antiquotation*. 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
+
+ ```nix
+ "--with-freetype2-library=" + freetype + "/lib"
+ ```
+
+ (where `freetype` is a derivation), you can instead write the more
+ natural
+
+ ```nix
+ "--with-freetype2-library=${freetype}/lib"
+ ```
+
+ The latter is automatically translated to the former. A more
+ complicated example (from the Nix expression for
+ [Qt](http://www.trolltech.com/products/qt)):
+
+ ```nix
+ 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"}
+ ";
+ ```
+
+ 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., `"-thread"`), some of which in
+ turn contain expressions (e.g., `${mesa}`).
+
+ The second way to write string literals is as an *indented string*,
+ which is enclosed between pairs of *double single-quotes*, like so:
+
+ ```nix
+ ''
+ This is the first line.
+ This is the second line.
+ This is the third line.
+ ''
+ ```
+
+ 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
+
+ ```nix
+ "This is the first line.\nThis is the second line.\n This is the third line.\n"
+ ```
+
+ Note that the whitespace and newline following the opening `''` is
+ ignored if there is no non-whitespace text on the initial line.
+
+ Antiquotation (`${expr}`) is supported in indented strings.
+
+ Since `${` and `''` have special meaning in indented strings, you
+ need a way to quote them. `$` can be escaped by prefixing it with
+ `''` (that is, two single quotes), i.e., `''$`. `''` can be escaped
+ by prefixing it with `'`, i.e., `'''`. `$` removes any special
+ meaning from the following `$`. Linefeed, carriage-return and tab
+ characters can be written as `''\n`, `''\r`, `''\t`, and `''\`
+ escapes any other character.
+
+ 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 `''` is much less common than `"`.
+ Example:
+
+ ```nix
+ stdenv.mkDerivation {
+ ...
+ 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 ""}
+ '';
+ ...
+ }
+ ```
+
+ Finally, as a convenience, *URIs* as defined in appendix B of
+ [RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
+ is*, without quotes. For instance, the string
+ `"http://example.org/foo.tar.bz2"` can also be written as
+ `http://example.org/foo.tar.bz2`.
+
+ - Numbers, which can be *integers* (like `123`) or *floating point*
+ (like `123.43` or `.27e13`).
+
+ Numbers are type-compatible: pure integer operations will always
+ return integers, whereas any operation involving at least one
+ floating point number will have a floating point number as a result.
+
+ - *Paths*, e.g., `/bin/sh` or `./builder.sh`. A path must contain at
+ least one slash to be recognised as such. For instance, `builder.sh`
+ is not a path: it's parsed as an expression that selects the
+ attribute `sh` from the variable `builder`. 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
+ `/foo/bar/bla.nix` refers to `../xyzzy/fnord.nix`, the absolute path
+ is `/foo/xyzzy/fnord.nix`.
+
+ If the first component of a path is a `~`, it is interpreted as if
+ the rest of the path were relative to the user's home directory.
+ e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
+ whose home directory is `/home/edolstra`.
+
+ Paths can also be specified between angle brackets, e.g.
+ `<nixpkgs>`. This means that the directories listed in the
+ environment variable `NIX_PATH` will be searched for the given file
+ or directory name.
+
+ Antiquotation is supported in any paths except those in angle brackets.
+ `./${foo}-${bar}.nix` is a more convenient way of writing
+ `./. + "/" + foo + "-" + bar + ".nix"` or `./. + "/${foo}-${bar}.nix"`. At
+ least one slash must appear *before* any antiquotations for this to be
+ recognized as a path. `a.${foo}/b.${bar}` is a syntactically valid division
+ operation. `./a.${foo}/b.${bar}` is a path.
+
+ - *Booleans* with values `true` and `false`.
+
+ - The null value, denoted as `null`.
+
+## Lists
+
+Lists are formed by enclosing a whitespace-separated list of values
+between square brackets. For example,
+
+```nix
+[ 123 ./foo.nix "abc" (f { x = y; }) ]
+```
+
+defines a list of four elements, the last being the result of a call to
+the function `f`. Note that function calls have to be enclosed in
+parentheses. If they had been omitted, e.g.,
+
+```nix
+[ 123 ./foo.nix "abc" f { x = y; } ]
+```
+
+the result would be a list of five elements, the fourth one being a
+function and the fifth being a set.
+
+Note that lists are only lazy in values, and they are strict in length.
+
+## Sets
+
+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.
+
+Sets are just a list of name/value pairs (called *attributes*) enclosed
+in curly brackets, where each value is an arbitrary expression
+terminated by a semicolon. For example:
+
+```nix
+{ x = 123;
+ text = "Hello";
+ y = f { bla = 456; };
+}
+```
+
+This defines a set with attributes named `x`, `text`, `y`. The order of
+the attributes is irrelevant. An attribute name may only occur once.
+
+Attributes can be selected from a set using the `.` operator. For
+instance,
+
+```nix
+{ a = "Foo"; b = "Bar"; }.a
+```
+
+evaluates to `"Foo"`. It is possible to provide a default value in an
+attribute selection using the `or` keyword. For example,
+
+```nix
+{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
+```
+
+will evaluate to `"Xyzzy"` because there is no `c` attribute in the set.
+
+You can use arbitrary double-quoted strings as attribute names:
+
+```nix
+{ "foo ${bar}" = 123; "nix-1.0" = 456; }."foo ${bar}"
+```
+
+This will evaluate to `123` (Assuming `bar` is antiquotable). In the
+case where an attribute name is just a single antiquotation, the quotes
+can be dropped:
+
+```nix
+{ foo = 123; }.${bar} or 456
+```
+
+This will evaluate to `123` if `bar` evaluates to `"foo"` when coerced
+to a string and `456` otherwise (again assuming `bar` is antiquotable).
+
+In the special case where an attribute name inside of a set declaration
+evaluates to `null` (which is normally an error, as `null` is not
+antiquotable), that attribute is simply not added to the set:
+
+```nix
+{ ${if foo then "bar" else null} = true; }
+```
+
+This will evaluate to `{}` if `foo` evaluates to `false`.
+
+A set that has a `__functor` attribute whose value is callable (i.e. is
+itself a function or a set with a `__functor` attribute whose value is
+callable) can be applied as if it were a function, with the set itself
+passed in first , e.g.,
+
+```nix
+let add = { __functor = self: x: x + self.x; };
+ inc = add // { x = 1; };
+in inc 1
+```
+
+evaluates to `2`. This can be used to attach metadata to a function
+without the caller needing to treat it specially, or to implement a form
+of object-oriented programming, for example.
diff --git a/doc/manual/src/expressions/simple-building-testing.md b/doc/manual/src/expressions/simple-building-testing.md
new file mode 100644
index 000000000..6f730a936
--- /dev/null
+++ b/doc/manual/src/expressions/simple-building-testing.md
@@ -0,0 +1,61 @@
+# Building and Testing
+
+You can now try to build Hello. Of course, you could do `nix-env -i
+hello`, 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
+`nix-build`, which builds a Nix expression and creates a symlink named
+`result` in the current directory:
+
+```console
+$ nix-build -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
+...
+
+$ ls -l result
+lrwxrwxrwx ... 2006-09-29 10:43 result -> /nix/store/632d2b22514d...-hello-2.1.1
+
+$ ./result/bin/hello
+Hello, world!
+```
+
+The `-A` option selects the `hello` attribute. This is faster than
+using the symbolic package name specified by the `name` attribute
+(which also happens to be `hello`) and is unambiguous (there can be
+multiple packages with the symbolic name `hello`, but there can be
+only one attribute in a set named `hello`).
+
+`nix-build` registers the `./result` symlink as a garbage collection
+root, so unless and until you delete the `./result` symlink, the output
+of the build will be safely kept on your system. You can use
+`nix-build`’s `-o` switch to give the symlink another name.
+
+Nix has transactional semantics. Once a build finishes successfully, Nix
+makes a note of this in its database: it registers that the path denoted
+by `out` is now “valid”. 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 `make
+install`) and try again. Note that there is no “negative caching”: 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).
+
+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:
+
+```console
+$ nix-build -A hello
+waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'
+```
+
+So it is always safe to run multiple instances of Nix in parallel (which
+isn’t the case with, say, `make`).
diff --git a/doc/manual/src/expressions/simple-expression.md b/doc/manual/src/expressions/simple-expression.md
new file mode 100644
index 000000000..857f71b9b
--- /dev/null
+++ b/doc/manual/src/expressions/simple-expression.md
@@ -0,0 +1,23 @@
+# A Simple Nix Expression
+
+This section shows how to add and test the [GNU Hello
+package](http://www.gnu.org/software/hello/hello.html) to the Nix
+Packages collection. Hello is a program that prints out the text “Hello,
+world\!”.
+
+To add a package to the Nix Packages collection, you generally need to
+do three things:
+
+1. 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.
+
+2. Write a *builder*. This is a shell script that builds the package
+ from the inputs. (In fact, it can be written in any language, but
+ typically it's a `bash` shell script.)
+
+3. Add the package to the file `pkgs/top-level/all-packages.nix`. The
+ Nix expression written in the first step is a *function*; 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.
diff --git a/doc/manual/src/expressions/writing-nix-expressions.md b/doc/manual/src/expressions/writing-nix-expressions.md
new file mode 100644
index 000000000..5664108e7
--- /dev/null
+++ b/doc/manual/src/expressions/writing-nix-expressions.md
@@ -0,0 +1,12 @@
+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.
+
+> **Note**
+>
+> 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 [its
+> manual](http://nixos.org/nixpkgs/manual/).