diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am
index 98d85ecf7..e577be8c6 100644
--- a/doc/manual/Makefile.am
+++ b/doc/manual/Makefile.am
@@ -4,7 +4,8 @@ XMLLINT = $(ENV) $(xmllint) $(xmlflags) --catalogs
XSLTPROC = $(ENV) $(xsltproc) $(xmlflags) --catalogs \
--param section.autolabel 1 \
--param section.label.includes.component.label 1 \
- --param html.stylesheet \'style.css\'
+ --param html.stylesheet \'style.css\' \
+ --param xref.with.number.and.title 0
man1_MANS = nix-env.1 nix-store.1 nix-instantiate.1 \
nix-collect-garbage.1 nix-push.1 nix-pull.1 \
diff --git a/doc/manual/bugs.xml b/doc/manual/bugs.xml
index b479c1354..6097b2aa0 100644
--- a/doc/manual/bugs.xml
+++ b/doc/manual/bugs.xml
@@ -52,17 +52,6 @@
-
-
- The current garbage collector is a hack. It should be
- integrated into nix-store. It should
- delete derivations in an order determined by topologically
- sorting derivations under the points-to relation. This
- ensures that no store paths ever exist that point to
- non-existant store paths.
-
-
-
There are race conditions between the garbage collector and
diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml
index b16d00b92..d3514b625 100644
--- a/doc/manual/writing-nix-expressions.xml
+++ b/doc/manual/writing-nix-expressions.xml
@@ -44,7 +44,8 @@ need to do three things:
The Nix expression
-Nix expression for GNU Hello
+Nix expression for GNU Hello
+(default.nix)
{stdenv, fetchurl, perl}:
@@ -189,24 +190,108 @@ perl = perl;The builder
-Build script for GNU Hello
+Build script for GNU Hello
+(builder.sh)
-. $stdenv/setup
+. $stdenv/setup
-PATH=$perl/bin:$PATH
+PATH=$perl/bin:$PATH
-tar xvfz $src
+tar xvfz $src
cd hello-*
-./configure --prefix=$out
-make
+./configure --prefix=$out
+make
make install shows the builder referenced
from Hello's Nix expression (stored in
-pkgs/applications/misc/hello/ex-1/builder.sh).
+pkgs/applications/misc/hello/ex-1/builder.sh).
+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:
-TODO
+
+
+
+
+ When Nix runs a builder, it initially completely clears the
+ environment. For instance, the PATH variable is
+ emptyActually, it's initialised to
+ /path-not-set to prevent Bash from setting it
+ to a default value.. 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 , but
+ mkDerivation adds it automatically.)
+
+
+
+
+
+ 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 component (since it
+ was passed in as an attribute to the derivation), so
+ $perl/bin is the
+ directory containing the Perl interpreter.
+
+
+
+
+
+ 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.
+
+
+
+
+
+ GNU Hello is a typical Autoconf-based package, so we first
+ have to run its configure script. In Nix
+ every component 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.
+
+
+
+
+
+ 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
@@ -217,6 +302,203 @@ error check.
+Composition
+
+Composing GNU Hello
+(all-packages-generic.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 = ...;
+
+}
+
+
+
+The Nix expression in 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/system/all-packages-generic.nix, where all
+Nix expressions for components are imported and called with the
+appropriate arguments. shows
+some fragments of
+all-packages-generic.nix.
+
+
+
+
+
+ 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 components into each other.
+
+
+
+
+
+ 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 in
+ all-packages-generic.nix at this point. That
+ would be completely equivalent, but it would make the file 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.
+
+
+
+
+
+ This is where the actual composition takes place. Here we
+ call the function imported from
+ ../applications/misc/hello/ex-1 with an
+ attribute 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 ).
+
+
+
+
+
+ Likewise, we have to instantiate Perl,
+ fetchurl, and the standard environment.
+
+
+
+
+
+
+
+
+Testing
+
+You can now try to build Hello. The simplest way to do that is
+by using nix-env:
+
+
+$ nix-env -f pkgs/system/i686-linux.nix -i hello
+installing `hello-2.1.1'
+building path `/nix/store/632d2b22514dcebe704887c3da15448d-hello-2.1.1'
+hello-2.1.1/
+hello-2.1.1/intl/
+hello-2.1.1/intl/ChangeLog
+...
+
+
+This will build Hello and install it into your profile. The file
+i686-linux is just a simple Nix expression that
+imports all-packages-generic.nix and instantiates
+it for Linux on the x86 platform.
+
+Note that the hello argument here refers to
+the symbolic name given to the Hello derivation (the
+name attribute in ),
+not the hello attribute in
+all-packages-generic.nix.
+nix-env simply walks through all derivations
+defined in the latter file, looking for one with a
+name attribute matching the command-line
+argument.
+
+You can test whether it works:
+
+
+$ hello
+Hello, world!
+
+
+
+Generally, however, using nix-env is not the
+best way to test components, since you may not want to install them
+into your profile right away (they might not work properly, after
+all). A better way is to write a short file containging the
+following:
+
+
+(import pkgs/system/i686-linux.nix).hello
+
+Call it test.nix. Then you can build it without
+installing it using the command nix-build:
+
+
+$ nix-build ./test.nix
+...
+/nix/store/632d2b22514dcebe704887c3da15448d-hello-2.1.1
+
+nix-build will build the derivation and print the
+output path. It also creates a symlink to the output path called
+result in the current directory. This is
+convenient for testing the component:
+
+
+$ ./result/bin/hello
+Hello, world!
+
+
+
+Nix has a transactional semantics. Once a build finishes
+succesfully, 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 path will not be registered as valid. If you try to build
+the derivation again, Nix will remove the output path if it exists
+(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. So it is always safe to run multiple instances of Nix in
+parallel (contrary to, say, make).
+
+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 ,
+where N is the maximum number of jobs to be
+run in parallel. Typically this should be the number of CPUs.
+
+
+
+