diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index ef1a4d4a95..28ebb4d155 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -10,7 +10,8 @@ man1_MANS = nix-env.1 nix-store.1 nix-instantiate.1 \ nix-collect-garbage.1 nix-push.1 nix-pull.1 \ nix-prefetch-url.1 -SOURCES = manual.xml introduction.xml installation.xml overview.xml \ +SOURCES = manual.xml introduction.xml installation.xml \ + package-management.xml writing-nix-expressions.xml \ $(man1_MANS:.1=.xml) \ troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml \ quick-start.xml nix-lang-ref.xml style.css images diff --git a/doc/manual/manual.xml b/doc/manual/manual.xml index 930da3a891..d2f19f0309 100644 --- a/doc/manual/manual.xml +++ b/doc/manual/manual.xml @@ -9,7 +9,8 @@ - + + @@ -44,7 +45,8 @@ &introduction; &quick-start; &installation; - &overview; + &package-management; + &writing-nix-expressions; Command Reference diff --git a/doc/manual/overview.xml b/doc/manual/overview.xml deleted file mode 100644 index d3a7e443bd..0000000000 --- a/doc/manual/overview.xml +++ /dev/null @@ -1,450 +0,0 @@ - - Overview - - - This chapter provides a guided tour of Nix. - - - - - - - - Basic package management - - - Let's start from the perspective of an end user. Common operations at - this level are to install and remove packages, ask what packages are - installed or available for installation, and so on. These are operations - on the user environment: the set of packages that a - user sees. In a command line Unix environment, this means - the set of programs that are available through the PATH - environment variable. (In other environments it might mean the set of - programs available on the desktop, through the start menu, and so on.) - - - - The terms installation and uninstallation - are used in this context to denote the act of adding or removing packages - from the user environment. In Nix, these operations are dissociated from - the physical copying or deleting of files. Installation requires that - the files constituting the package are present, but they may be present - beforehand. Likewise, uninstallation does not actually delete any files; - this is done automatically by running a garbage collector. - - - - User environments are manipulated through the nix-env - command. The query operation can be used to see what packages are - currently installed. - - - -$ nix-env -q -MozillaFirebird-0.7 -sylpheed-0.9.7 -pan-0.14.2 - - - ( is actually short for .) The package names are symbolic: they don't have - any particular significance to Nix (as they shouldn't, since they are not - unique—there can be many derivations with the same name). Note that - these packages have many dependencies (e.g., Mozilla uses the - gtk+ package) but these have not been installed in the - user environment, though they are present on the system. Generally, - there is no need to install such packages; only packages containing - programs should be installed. - - - - To install packages, a Nix expression is required - that tells Nix how to build that package. There is a set - of standard of Nix expressions for many common packages. - Assuming that you have downloaded and unpacked these, you can view the - set of available packages: - - - -$ nix-env -qaf pkgs/system/i686-linux.nix -gettext-0.12.1 -sylpheed-0.9.7 -aterm-2.0 -gtk+-1.2.10 -apache-httpd-2.0.48 -pan-0.14.2 -... - - - The Nix expression in the file i686-linux.nix yields - the set of packages for a Linux system running on x86 hardware. For - other platforms, copy and modify this file for your platform as - appropriate. [TODO: improve this] - - - - It is also possible to see the status of available - packages, i.e., whether they are installed into the user environment - and/or present in the system: - - - -$ nix-env -qasf pkgs/system/i686-linux.nix --P gettext-0.12.1 -IP sylpheed-0.9.7 --- aterm-2.0 --P gtk+-1.2.10 - - - This reveals that the sylpheed package is already - installed, or more precisely, that exactly the same instantiation of - sylpheed is installed. This guarantees that the - available package is exactly the same as the installed package with - regard to sources, dependencies, build flags, and so on. Similarly, we - see that the gettext and gtk+ - packages are present but not installed in the user environment, while the - aterm package is not installed or present at all (so, - if we were to install it, it would have to be built or downloaded first). - - - - The install operation is used install available packages from a Nix - environment. To install the pan package (a - newsreader), you would do: - - - -$ nix-env -if pkgs/system/i686-linux.nix pan - - - Since installation may take a long time, depending on whether any - packages need to be built or downloaded, it's a good idea to make - nix-env run verbosely by using the - () option. This option may be repeated to - increase the level of verbosity. A good value is 3 - (). - - - - In fact, if you run this command verbosely you will observe that Nix - starts to build many packages, including large and fundamental ones such - as glibc and gcc. I.e., you are - performing a source installation. This is generally undesirable, since - installation from sources may require large amounts of disk and CPU - resources. Therefore a binary installation is generally - preferable. - - - - Rather than provide different mechanisms to create and perform - the installation of binary packages, Nix supports binary deployment - transparently through a generic mechanism of - substitute expressions. If an request is made to - build some Nix expression, Nix will first try to build any substitutes - for that expression. These substitutes presumably perform an identical - build operation with respect to the result, but require less resources. - For instance, a substitute that downloads a pre-built package from the - network requires less CPU and disk resources, and possibly less time. - - - - Nix's use of cryptographic hashes makes this entirely safe. It is not - possible, for instance, to accidentally substitute a build of some - package for a Solaris or Windows system for a build on a SuSE/x86 system. - - - - While the substitute mechanism is a generic mechanism, Nix provides two - standard tools called nix-pull and - nix-push that maintain and use a shared cache of - prebuilt derivations on some network site (reachable through HTTP). If - you attempt to install some package that someone else has previously - built and pushed into the cache, and you have done a - pull to register substitutes that download these prebuilt - packages, then the installation will automatically use these. - - - - For example, to pull from our cache of - prebuilt packages (at the time of writing, for SuSE Linux/x86), use the - following command: - - - -$ nix-pull http://catamaran.labs.cs.uu.nl/dist/nix/nixpkgs-version/MANIFEST -obtaining list of Nix archives at http://catamaran.labs.cs.uu.nl/dist/nix/nixpkgs-version/MANIFEST... -... - - - If nix-pull is run without any arguments, it will pull - from the URLs specified in the file - prefix/etc/nix/prebuilts.conf. - - - - Assuming that the pan installation produced no errors, - it can be used immediately, that is, it now appears in a directory in the - PATH environment variable. Specifically, - PATH includes the entry - prefix/var/nix/profiles/default/bin, - where - prefix/var/nix/profiles/default - is just a symlink to the current user environment: - - - -$ ls -l /nix/var/nix/profiles/ -... -lrwxrwxrwx 1 eelco ... default-15-link -> /nix/store/1871...12b0-user-environment -lrwxrwxrwx 1 eelco ... default-16-link -> /nix/store/59ba...df6b-user-environment -lrwxrwxrwx 1 eelco ... default -> default-16-link - - - That is, default in this example is a link - to default-16-link, which is the current - user environment. Before the installation, it pointed to - default-15-link. Note that this means that - you can atomically roll-back to the previous user environment by - pointing the symlink default at - default-15-link again. This also shows - that operations such as installation are atomic in the Nix - system: any arbitrarily complex set of installation, - uninstallation, or upgrade actions eventually boil down to the - single operation of pointing a symlink somewhere else (which can - be implemented atomically in Unix). - - - - What's in a user environment? It's just a set of symlinks to the files - that constitute the installed packages. For instance: - - - -$ ls -l /nix/var/nix/profiles/default-16-link/bin -lrwxrwxrwx 1 eelco ... MozillaFirebird -> /nix/store/35f8...4ae6-MozillaFirebird-0.7/bin/MozillaFirebird -lrwxrwxrwx 1 eelco ... svn -> /nix/store/3829...fb5d-subversion-0.32.1/bin/svn -... - - - Note that, e.g., svn = - /nix/var/nix/profiles/default/bin/svn = - /nix/var/nix/profiles/default-16-link/bin/svn = - /nix/store/59ba...df6b-user-environment/bin/svn = - /nix/store/3829...fb5d-subversion-0.32.1/bin/svn. - - - - Naturally, packages can also be uninstalled: - - - -$ nix-env -e pan - - - This means that the package is removed from the user - environment. It is not yet removed from - the system. When a package is uninstalled from a user - environment, it may still be used by other packages, or may - still be present in other user environments. Deleting it under - such conditions would break those other packages or user - environments. To prevent this, packages are only - physically deleted by running the Nix garbage - collector, which searches for all packages in the Nix store that - are no longer reachable from outside the store. - Thus, uninstalling a package is always safe: it cannot break - other packages. - - - - Upgrading packages is easy. Given a Nix expression that - contains newer versions of installed packages (that is, packages - with the same package name, but a higher version number), - nix-env -u will replace the installed package - in the user environment with the newer package. For example, - - -$ nix-env -uf pkgs/system/i686-linux.nix pan - - looks for a newer version of Pan, and installs it if found. - Also useful is the ability to upgrade all - packages: - - -$ nix-env -uf pkgs/system/i686-linux.nix '*' - - The asterisk matches all installed packagesNo, - we don't support arbitrary regular - expressions. Note that * - must be quoted to prevent shell globbing. - - - - - - - - - - Writing Nix expressions - - - A simple Nix expression - - - This section shows how to write simple Nix expressions—the things - that describe how to build a package. - - - - Nix expression for GNU Hello - -{stdenv, fetchurl, perl}: - -derivation { - name = "hello-2.1.1"; - system = stdenv.system; - builder = ./builder.sh; - src = fetchurl { - url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz; - md5 = "70c9ccf9fac07f762c24f2df2290784d"; - }; - stdenv = stdenv; - perl = perl; -} - - - - A simple Nix expression is shown in . It - describes how to the build the GNU Hello - package. This package has several dependencies. First, it - requires a number of other packages, such as a C compiler, standard - Unix shell tools, and Perl. Rather than have this Nix expression refer - to and use specific versions of these packages, it should be generic; - that is, it should be a function that takes the - required packages as inputs and yield a build of the GNU Hello package - as a result. This Nix expression defines a function with three - arguments , namely: - - stdenv, which should be a - standard environment package. The standard - environment is a set of tools and other components that would be - expected in a fairly minimal Unix-like environment: a C compiler - and linker, Unix shell tools, and so on. - - fetchurl, which should be a - function that given parameters url and - md5, will fetch a file from the specified - location and check that this file has the given MD5 hash code. - The hash is required because build operations must be - pure: given the same inputs they should - always yield the same output. Since network resources can change - at any time, we must in some way guarantee what the result will - be. - - perl, which should be a Perl - interpreter. - - - - - - The remainder of the file is the body of the function, which happens to - be a derivation , which is the built-in function - derivation applied to a set of attributes that - encode all the necessary information for building the GNU Hello - package. - - - - Build script (<filename>builder.sh</filename>) for GNU - Hello - -#! /bin/sh - -buildinputs="$perl" -. $stdenv/setup || exit 1 - -tar xvfz $src || exit 1 -cd hello-* || exit 1 -./configure --prefix=$out || exit 1 -make || exit 1 -make install || exit 1 - - - - - - A more complex Nix expression - - - Nix expression for Subversion - -{ localServer ? false -, httpServer ? false -, sslSupport ? false -, swigBindings ? false -, stdenv, fetchurl -, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null -}: - -assert !isNull expat; -assert localServer -> !isNull db4; -assert httpServer -> !isNull httpd && httpd.expat == expat; -assert sslSupport -> !isNull openssl && (httpServer -> httpd.openssl == openssl); -assert swigBindings -> !isNull swig; - -derivation { - name = "subversion-0.32.1"; - system = stdenv.system; - - builder = ./builder.sh; - src = fetchurl { - url = http://svn.collab.net/tarballs/subversion-0.32.1.tar.gz; - md5 = "b06717a8ef50db4b5c4d380af00bd901"; - }; - - localServer = localServer; - httpServer = httpServer; - sslSupport = sslSupport; - swigBindings = swigBindings; - - stdenv = stdenv; - openssl = if sslSupport then openssl else null; - httpd = if httpServer then httpd else null; - expat = expat; - db4 = if localServer then db4 else null; - swig = if swigBindings then swig else null; -} - - - - This example shows several features. Default parameters can be used to simplify call sites: if an - argument that has a default is omitted, its default value is used. - - - - You can use assertions to test whether arguments - satisfy certain constraints. The simple assertion tests whether the - expat argument is not a null value. The more - complex assertion says that if - Subversion is built with Apache support, then httpd - (the Apache package) must not be null and it must have been built using - the same instance of the expat library as was passed - to the Subversion expression. This is since the Subversion code is - dynamically linked against the Apache code and they both use Expat, - they must be linked against the same instance—otherwise a - conflict might occur. - - - - - - - - diff --git a/doc/manual/package-management.xml b/doc/manual/package-management.xml new file mode 100644 index 0000000000..90f8f95b65 --- /dev/null +++ b/doc/manual/package-management.xml @@ -0,0 +1,229 @@ +Package Management + +Let's start from the perspective of an end user. Common +operations at this level are to install and remove packages, ask what +packages are installed or available for installation, and so on. +These are operations on the user environment: the +set of packages that a user sees. In a command line +Unix environment, this means the set of programs that are available +through the PATH environment variable. (In other +environments it might mean the set of programs available on the +desktop, through the start menu, and so on.) + +The terms installation and +uninstallation are used in this context to denote the +act of adding or removing packages from the user environment. In Nix, +these operations are dissociated from the physical copying or deleting +of files. Installation requires that the files constituting the +package are present, but they may be present beforehand. Likewise, +uninstallation does not actually delete any files; this is done +automatically by running a garbage collector. + +User environments are manipulated through the +nix-env command. The query operation can be used +to see what packages are currently installed. + + +$ nix-env -q +MozillaFirebird-0.7 +sylpheed-0.9.7 +pan-0.14.2 + +( is actually short for .) The package names are symbolic: they don't +have any particular significance to Nix (as they shouldn't, since they +are not unique—there can be many derivations with the same +name). Note that these packages have many dependencies (e.g., Mozilla +uses the gtk+ package) but these have not been +installed in the user environment, though they are present on the +system. Generally, there is no need to install such packages; only +packages containing programs should be installed. + +To install packages, a Nix expression is +required that tells Nix how to build that package. There is a set +of standard of Nix expressions for many common packages. +Assuming that you have downloaded and unpacked these, you can view the +set of available packages: + + +$ nix-env -qaf pkgs/system/i686-linux.nix +gettext-0.12.1 +sylpheed-0.9.7 +aterm-2.0 +gtk+-1.2.10 +apache-httpd-2.0.48 +pan-0.14.2 +... + +The Nix expression in the file +i686-linux.nix yields the set of packages for a +Linux system running on x86 hardware. For other platforms, copy and +modify this file for your platform as appropriate. [TODO: improve +this] + +It is also possible to see the status of +available packages, i.e., whether they are installed into the user +environment and/or present in the system: + + +$ nix-env -qasf pkgs/system/i686-linux.nix +-P gettext-0.12.1 +IP sylpheed-0.9.7 +-- aterm-2.0 +-P gtk+-1.2.10 + +This reveals that the sylpheed package is +already installed, or more precisely, that exactly the same +instantiation of sylpheed is installed. This +guarantees that the available package is exactly the same as the +installed package with regard to sources, dependencies, build flags, +and so on. Similarly, we see that the gettext and +gtk+ packages are present but not installed in the +user environment, while the aterm package is not +installed or present at all (so, if we were to install it, it would +have to be built or downloaded first). + +The install operation is used install available packages from a +Nix environment. To install the pan package (a +newsreader), you would do: + + +$ nix-env -if pkgs/system/i686-linux.nix pan + +Since installation may take a long time, depending on whether +any packages need to be built or downloaded, it's a good idea to make +nix-env run verbosely by using the + () option. This option +may be repeated to increase the level of verbosity. A good value is 3 +(). + +In fact, if you run this command verbosely you will observe that +Nix starts to build many packages, including large and fundamental +ones such as glibc and gcc. +I.e., you are performing a source installation. This is generally +undesirable, since installation from sources may require large amounts +of disk and CPU resources. Therefore a binary +installation is generally preferable. + +Rather than provide different mechanisms to create and perform +the installation of binary packages, Nix supports binary deployment +transparently through a generic mechanism of +substitute expressions. If an request is made to +build some Nix expression, Nix will first try to build any substitutes +for that expression. These substitutes presumably perform an +identical build operation with respect to the result, but require less +resources. For instance, a substitute that downloads a pre-built +package from the network requires less CPU and disk resources, and +possibly less time. + +Nix's use of cryptographic hashes makes this entirely safe. It +is not possible, for instance, to accidentally substitute a build of +some package for a Solaris or Windows system for a build on a SuSE/x86 +system. + +While the substitute mechanism is a generic mechanism, Nix +provides two standard tools called nix-pull and +nix-push that maintain and use a shared cache of +prebuilt derivations on some network site (reachable through HTTP). +If you attempt to install some package that someone else has +previously built and pushed into the cache, and you +have done a pull to register substitutes that download +these prebuilt packages, then the installation will automatically use +these. + +For example, to pull from our cache of +prebuilt packages (at the time of writing, for SuSE Linux/x86), use +the following command: + + +$ nix-pull http://catamaran.labs.cs.uu.nl/dist/nix/nixpkgs-version/MANIFEST +obtaining list of Nix archives at http://catamaran.labs.cs.uu.nl/dist/nix/nixpkgs-version/MANIFEST... +... + +If nix-pull is run without any arguments, it +will pull from the URLs specified in the file +prefix/etc/nix/prebuilts.conf. + +Assuming that the pan installation produced +no errors, it can be used immediately, that is, it now appears in a +directory in the PATH environment variable. +Specifically, PATH includes the entry +prefix/var/nix/profiles/default/bin, +where +prefix/var/nix/profiles/default +is just a symlink to the current user environment: + + +$ ls -l /nix/var/nix/profiles/ +... +lrwxrwxrwx 1 eelco ... default-15-link -> /nix/store/1871...12b0-user-environment +lrwxrwxrwx 1 eelco ... default-16-link -> /nix/store/59ba...df6b-user-environment +lrwxrwxrwx 1 eelco ... default -> default-16-link + +That is, default in this example is a link +to default-16-link, which is the current user +environment. Before the installation, it pointed to +default-15-link. Note that this means that you +can atomically roll-back to the previous user environment by pointing +the symlink default at +default-15-link again. This also shows that +operations such as installation are atomic in the Nix system: any +arbitrarily complex set of installation, uninstallation, or upgrade +actions eventually boil down to the single operation of pointing a +symlink somewhere else (which can be implemented atomically in Unix). + +What's in a user environment? It's just a set of symlinks to the +files that constitute the installed packages. For instance: + + +$ ls -l /nix/var/nix/profiles/default-16-link/bin +lrwxrwxrwx 1 eelco ... MozillaFirebird -> /nix/store/35f8...4ae6-MozillaFirebird-0.7/bin/MozillaFirebird +lrwxrwxrwx 1 eelco ... svn -> /nix/store/3829...fb5d-subversion-0.32.1/bin/svn +... + +Note that, e.g., svn = +/nix/var/nix/profiles/default/bin/svn = +/nix/var/nix/profiles/default-16-link/bin/svn = +/nix/store/59ba...df6b-user-environment/bin/svn = +/nix/store/3829...fb5d-subversion-0.32.1/bin/svn. + +Naturally, packages can also be uninstalled: + + +$ nix-env -e pan + +This means that the package is removed from the user +environment. It is not yet removed from the +system. When a package is uninstalled from a user environment, it may +still be used by other packages, or may still be present in other user +environments. Deleting it under such conditions would break those +other packages or user environments. To prevent this, packages are +only physically deleted by running the Nix garbage +collector, which searches for all packages in the Nix store that are +no longer reachable from outside the store. Thus, +uninstalling a package is always safe: it cannot break other +packages. + +Upgrading packages is easy. Given a Nix expression that +contains newer versions of installed packages (that is, packages with +the same package name, but a higher version number), nix-env +-u will replace the installed package in the user +environment with the newer package. For example, + + +$ nix-env -uf pkgs/system/i686-linux.nix pan + +looks for a newer version of Pan, and installs it if found. Also +useful is the ability to upgrade all packages: + + +$ nix-env -uf pkgs/system/i686-linux.nix '*' + +The asterisk matches all installed packagesNo, we +don't support arbitrary regular expressions. Note +that * must be quoted to prevent shell +globbing. + + \ No newline at end of file diff --git a/doc/manual/quick-start.xml b/doc/manual/quick-start.xml index a6ec25514e..2350aed34b 100644 --- a/doc/manual/quick-start.xml +++ b/doc/manual/quick-start.xml @@ -2,8 +2,7 @@ This chapter is for impatient people who don't like reading documentation. For more in-depth information you are kindly referred -to and . +to the following chapters. diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml new file mode 100644 index 0000000000..c4ea5d1f39 --- /dev/null +++ b/doc/manual/writing-nix-expressions.xml @@ -0,0 +1,148 @@ +Writing Nix Expressions + +A simple Nix expression + +This section shows how to write simple Nix expressions—the +things that describe how to build a package. + +Nix expression for GNU Hello + +{stdenv, fetchurl, perl}: + +derivation { + name = "hello-2.1.1"; + system = stdenv.system; + builder = ./builder.sh; + src = fetchurl { + url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz; + md5 = "70c9ccf9fac07f762c24f2df2290784d"; + }; + stdenv = stdenv; + perl = perl; +} + + +A simple Nix expression is shown in . It describes how to the build the GNU Hello +package. This package has several dependencies. First, it +requires a number of other packages, such as a C compiler, standard +Unix shell tools, and Perl. Rather than have this Nix expression +refer to and use specific versions of these packages, it should be +generic; that is, it should be a function that +takes the required packages as inputs and yield a build of the GNU +Hello package as a result. This Nix expression defines a function +with three arguments , namely: + + + stdenv, which should be a + standard environment package. The standard + environment is a set of tools and other components that would be + expected in a fairly minimal Unix-like environment: a C compiler + and linker, Unix shell tools, and so on. + + fetchurl, which should be a + function that given parameters url and + md5, will fetch a file from the specified + location and check that this file has the given MD5 hash code. + The hash is required because build operations must be + pure: given the same inputs they should + always yield the same output. Since network resources can change + at any time, we must in some way guarantee what the result will + be. + + perl, which should be a Perl + interpreter. + + + + +The remainder of the file is the body of the function, which +happens to be a derivation , which is the built-in function +derivation applied to a set of attributes that +encode all the necessary information for building the GNU Hello +package. + +Build script (<filename>builder.sh</filename>) for GNU +Hello + +#! /bin/sh + +buildinputs="$perl" +. $stdenv/setup || exit 1 + +tar xvfz $src || exit 1 +cd hello-* || exit 1 +./configure --prefix=$out || exit 1 +make || exit 1 +make install || exit 1 + + + + + +A more complex Nix expression + +Nix expression for Subversion + +{ localServer ? false +, httpServer ? false +, sslSupport ? false +, swigBindings ? false +, stdenv, fetchurl +, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null +}: + +assert !isNull expat; +assert localServer -> !isNull db4; +assert httpServer -> !isNull httpd && httpd.expat == expat; +assert sslSupport -> !isNull openssl && (httpServer -> httpd.openssl == openssl); +assert swigBindings -> !isNull swig; + +derivation { + name = "subversion-0.32.1"; + system = stdenv.system; + + builder = ./builder.sh; + src = fetchurl { + url = http://svn.collab.net/tarballs/subversion-0.32.1.tar.gz; + md5 = "b06717a8ef50db4b5c4d380af00bd901"; + }; + + localServer = localServer; + httpServer = httpServer; + sslSupport = sslSupport; + swigBindings = swigBindings; + + stdenv = stdenv; + openssl = if sslSupport then openssl else null; + httpd = if httpServer then httpd else null; + expat = expat; + db4 = if localServer then db4 else null; + swig = if swigBindings then swig else null; +} + + +This example shows several features. Default parameters can be used to simplify call sites: if an +argument that has a default is omitted, its default value is +used. + +You can use assertions to test whether +arguments satisfy certain constraints. The simple assertion tests whether the expat +argument is not a null value. The more complex assertion says that if Subversion is built with +Apache support, then httpd (the Apache package) +must not be null and it must have been built using the same instance +of the expat library as was passed to the +Subversion expression. This is since the Subversion code is +dynamically linked against the Apache code and they both use Expat, +they must be linked against the same instance—otherwise a +conflict might occur. + + + + +