summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2008-06-19 16:00:37 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2008-06-19 16:00:37 +0000
commit418d5e30810240e95eecaddaac549a9e10757a4e (patch)
tree286b3fabb8f737a4d5f73ad074a6b4575daaecc6
parent69b82f319fd330ee4b512b74fef5cffa01ddb818 (diff)
* More stdenv documentation. Some of it has been moved from the Nix
manual. svn path=/nixpkgs/trunk/; revision=12164
-rw-r--r--doc/manual.xml2
-rw-r--r--doc/outline.txt2
-rw-r--r--doc/stdenv.xml352
3 files changed, 355 insertions, 1 deletions
diff --git a/doc/manual.xml b/doc/manual.xml
index 2ef9516afc12..c4f1128ea77e 100644
--- a/doc/manual.xml
+++ b/doc/manual.xml
@@ -32,4 +32,4 @@
<xi:include href="quick-start.xml" />
<xi:include href="stdenv.xml" />
-</book> \ No newline at end of file
+</book>
diff --git a/doc/outline.txt b/doc/outline.txt
index 78ba0411501b..a7dfc3bdc86c 100644
--- a/doc/outline.txt
+++ b/doc/outline.txt
@@ -43,6 +43,8 @@
- Stdenv bootstrap; how to update the Linux bootstrap binaries
+ - Specific platform notes (Linux, Native, Cygwin, Mingw)
+
- Support for specific languages
diff --git a/doc/stdenv.xml b/doc/stdenv.xml
index d99cdb4dd699..105026f530f5 100644
--- a/doc/stdenv.xml
+++ b/doc/stdenv.xml
@@ -4,7 +4,359 @@
<title>The Standard Environment</title>
+
+<para>The standard build environment in the Nix Packages collection
+provides a environment for building Unix packages that does a lot of
+common build tasks automatically. In fact, for Unix packages that use
+the standard <literal>./configure; make; make install</literal> build
+interface, you don’t need to write a build script at all; the standard
+environment does everything automatically. If
+<literal>stdenv</literal> doesn’t do what you need automatically, you
+can easily customise or override the various build phases.</para>
+
+
+<section><title>Using <literal>stdenv</literal></title>
+
+<para>To build a package with the standard environment, you use the
+function <varname>stdenv.mkDerivation</varname>, instead of the
+primitive built-in function <varname>derivation</varname>, e.g.
+
+<programlisting>
+stdenv.mkDerivation {
+ name = "libfoo-1.2.3";
+ src = fetchurl {
+ url = http://example.org/libfoo-1.2.3.tar.bz2;
+ md5 = "e1ec107956b6ddcb0b8b0679367e9ac9";
+ };
+}</programlisting>
+
+(<varname>stdenv</varname> needs to be in scope, so if you write this
+in a separate Nix expression from
+<filename>pkgs/all-packages.nix</filename>, you need to pass it as a
+function argument.) Specifying a <varname>name</varname> and a
+<varname>src</varname> is the absolute minimum you need to do. Many
+packages have dependencies that are not provided in the standard
+environment. It’s usually sufficient to specify those dependencies in
+the <varname>buildInputs</varname> attribute:
+
+<programlisting>
+stdenv.mkDerivation {
+ name = "libfoo-1.2.3";
+ ...
+ buildInputs = [libbar perl ncurses];
+}</programlisting>
+
+This attribute ensures that the <filename>bin</filename>
+subdirectories of these packages appear in the <envar>PATH</envar>
+environment variable during the build, that their
+<filename>include</filename> subdirectories are searched by the C
+compiler, and so on. (See <xref linkend="ssec-setup-hooks"/> for
+details.)</para>
+
+<para>Often it is necessary to override or modify some aspect of the
+build. To make this easier, the standard environment breaks the
+package build into a number of <emphasis>phases</emphasis>, all of
+which can be overriden or modified individually: unpacking the
+sources, applying patches, configuring, building, and installing.
+(There are some others; see <xref linkend="ssec-stdenv-phases"/>.)
+For instance, a package that doesn’t supply a makefile but instead has
+to be compiled “manually” could be handled like this:
+
+<programlisting>
+stdenv.mkDerivation {
+ name = "fnord-4.5";
+ ...
+ buildPhase = ''
+ gcc foo.c -o foo
+ '';
+ installPhase = ''
+ ensureDir $out/bin
+ cp foo $out/bin
+ '';
+}</programlisting>
+
+(Note the use of <literal>''</literal>-style string literals, which
+are very convenient for large multi-line script fragments because they
+don’t need escaping of <literal>"</literal> and <literal>\</literal>,
+and because indentation is intelligently removed.)</para>
+
+<para>There are many other attributes to customise the build. These
+are listed in <xref linkend="ssec-stdenv-attributes"/>.</para>
+
+<para>While the standard environment provides a generic builder, you
+can still supply your own build script:
+
+<programlisting>
+stdenv.mkDerivation {
+ name = "libfoo-1.2.3";
+ ...
+ builder = ./builder.sh;
+}</programlisting>
+
+where the builder can do anything it wants, but typically starts with
+
+<programlisting>
+source $stdenv/setup
+</programlisting>
+
+to let <literal>stdenv</literal> set up the environment (e.g., process
+the <varname>buildInputs</varname>). If you want, you can still use
+<literal>stdenv</literal>’s generic builder:
+
+<programlisting>
+source $stdenv/setup
+
+buildPhase() {
+ echo "... this is my custom build phase ..."
+ gcc foo.c -o foo
+}
+
+installPhase() {
+ ensureDir $out/bin
+ cp foo $out/bin
+}
+
+genericBuild
+</programlisting>
+
+</para>
+
+</section>
+
+
+<section><title>Tools provided by <literal>stdenv</literal></title>
+
+<para>The standard environment provides the following packages:
+
+<itemizedlist>
+
+ <listitem><para>The GNU C Compiler, configured with C and C++
+ support.</para></listitem>
+
+ <listitem><para>GNU coreutils (contains a few dozen standard Unix
+ commands).</para></listitem>
+
+ <listitem><para>GNU findutils (contains
+ <command>find</command>).</para></listitem>
+
+ <listitem><para>GNU diffutils (contains <command>diff</command>,
+ <command>cmp</command>).</para></listitem>
+
+ <listitem><para>GNU <command>sed</command>.</para></listitem>
+
+ <listitem><para>GNU <command>grep</command>.</para></listitem>
+
+ <listitem><para>GNU <command>awk</command>.</para></listitem>
+
+ <listitem><para>GNU <command>tar</command>.</para></listitem>
+
+ <listitem><para><command>gzip</command> and
+ <command>bzip2</command>.</para></listitem>
+
+ <listitem><para>GNU Make. It has been patched to provide
+ <quote>nested</quote> output that can be fed into the
+ <command>nix-log2xml</command> command and
+ <command>log2html</command> stylesheet to create a structured,
+ readable output of the build steps performed by
+ Make.</para></listitem>
+
+ <listitem><para>Bash. This is the shell used for all builders in
+ the Nix Packages collection. Not using <command>/bin/sh</command>
+ removes a large source of portability problems.</para></listitem>
+
+ <listitem><para>The <command>patch</command>
+ command.</para></listitem>
+
+</itemizedlist>
+
+</para>
+
+<para>On Linux, <literal>stdenv</literal> also includes the
+<command>patchelf</command> utility.</para>
+
+</section>
+
+
+<section xml:id="ssec-stdenv-phases"><title>Build phases</title>
+
+<para>The generic builder has a number of <emphasis>phases</emphasis>.
+Each phase can be overriden in its entirety either by setting the
+environment variable
+<varname><replaceable>name</replaceable>Phase</varname> to a string
+containing some shell commands to be executed, or by redefining the
+shell function
+<varname><replaceable>name</replaceable>Phase</varname>. The former
+is convenient to override a phase from the derivation, while the
+latter is convenient from a build script.</para>
+
+<para>The phases are:
+
+<itemizedlist>
+
+ <listitem>
+
+ <para><function>unpackPhase</function> unpacks the source files
+ listed in the <envar>src</envar> environment variable to the
+ current directory. It supports <filename>tar</filename> files,
+ optionally compressed with <command>gzip</command> or
+ <command>bzip2</command>; Zip files (but note that the
+ <command>unzip</command> command is not a part of the standard
+ environment; you should add it as a build input yourself); and
+ unpacked source trees (i.e., directories; they are copied
+ verbatim). You can add support for other file types by setting
+ the <varname>findUnpacker</varname> hook. This hook should set
+ the variable <varname>unpackCmd</varname> to contain the command
+ to be executed to unpack the file.</para>
+
+ <para>After running <function>unpackPhase</function>, the generic
+ builder changes the current directory to the directory created by
+ unpacking the sources. If there are multiple source directories,
+ you should set <varname>sourceRoot</varname> to the name of the
+ intended directory.</para>
+
+ <para>It also calls the hook <varname>postUnpack</varname> after
+ unpacking.</para>
+
+ </listitem>
+
+ <listitem><para><function>patchPhase</function> calls the
+ <command>patch</command> command with the <option>-p1</option>
+ option (overridable via <envar>patchFlags</envar>) for each patch
+ file listed in the <envar>patches</envar>
+ variable.</para></listitem>
+
+ <listitem>
+
+ <para><function>configurePhase</function> runs the script called
+ <filename>configure</filename> in the current directory with a
+ <option>--prefix</option> set to the output path. You can add
+ additional flags through the <varname>configureFlags</varname>
+ variable. If <filename>configure</filename> does not exist,
+ nothing happens.</para>
+
+ <para>Before and after running <filename>configure</filename>, the
+ hooks <varname>preConfigure</varname> and
+ <varname>postConfigure</varname> are called, respectively.</para>
+
+ </listitem>
+
+ <listitem>
+
+ <para><function>buildPhase</function> calls
+ <command>make</command>. You can set flags for
+ <command>make</command> through the <varname>makeFlags</varname>
+ variable.</para>
+
+ <para>Before and after running <command>make</command>, the hooks
+ <varname>preBuild</varname> and <varname>postBuild</varname> are
+ called, respectively.</para>
+
+ </listitem>
+
+ <listitem><para><function>checkPhase</function> calls <command>make
+ check</command>, but only if the <varname>doCheck</varname> variable
+ is set to <literal>1</literal>. Additional flags can be set through
+ the <varname>checkFlags</varname> variable.</para></listitem>
+
+ <listitem>
+
+ <para><function>installPhase</function> calls <command>make
+ install</command>. Additional flags can be set through the
+ <varname>installFlags</varname> variable.</para>
+
+ <para>Before and after running <command>make install</command>,
+ the hooks <varname>preInstall</varname> and
+ <varname>postInstall</varname> are called, respectively.</para>
+
+ </listitem>
+
+ <listitem>
+ <para><function>fixupPhase</function> cleans up the
+ installed files in various ways:
+
+ <itemizedlist>
+
+ <listitem><para>It moves the <filename>man/</filename>,
+ <filename>doc/</filename> and <filename>info/</filename>
+ subdirectories of <envar>$out</envar> to
+ <filename>share/</filename>.</para></listitem>
+
+ <listitem><para>It strips libraries and executables of debug
+ information.</para></listitem>
+
+ <listitem><para>On Linux, it applies the
+ <command>patchelf</command> command to ELF executables and
+ libraries to remove unused directories from the
+ <literal>RPATH</literal> in order to prevent unnecessary
+ dependencies.</para></listitem>
+
+ <listitem><para>It rewrites the interpreter paths of shell
+ scripts to paths found in <envar>PATH</envar>. E.g.,
+ <filename>/usr/bin/perl</filename> will be rewritten to
+ <filename>/nix/store/<replaceable>some-perl</replaceable>/bin/perl</filename>
+ found in <envar>PATH</envar>.</para></listitem>
+
+ </itemizedlist>
+
+ </para>
+ </listitem>
+
+ <listitem>
+
+ <para><function>distPhase</function> calls <command>make
+ dist</command>, but only if the <varname>doDist</varname> variable
+ is set to <literal>1</literal>. Additional flags can be set
+ through the <varname>distFlags</varname> variable. The resulting
+ tarball is copied to the <filename>/tarballs</filename>
+ subdirectory of the output path.</para>
+
+ <para>Before and after running <command>make dist</command>, the
+ hooks <varname>preDist</varname> and <varname>postDist</varname>
+ are called, respectively.</para>
+
+ </listitem>
+
+</itemizedlist>
+
+</para>
+
+<para>You can change the order in which phases are executed, or add
+new phases, by setting the <varname>phases</varname> variable. The
+default is <literal>patchPhase configurePhase buildPhase checkPhase
+installPhase distPhase</literal>.</para>
+
+</section>
+
+
+<section xml:id="ssec-stdenv-attributes"><title>Attributes</title>
+
<para></para>
+</section>
+
+
+<section xml:id="ssec-setup-hooks"><title>Package setup hooks</title>
+
+<para></para>
+
+</section>
+
+
+<section><title>Purity in Nixpkgs</title>
+
+<para>[measures taken to prevent dependencies on packages outside the
+store, and what you can do to prevent them]</para>
+
+<para>GCC doesn't search in locations such as
+<filename>/usr/include</filename>. In fact, attempts to add such
+directories through the <option>-I</option> flag are filtered out.
+Likewise, the linker (from GNU binutils) doesn't search in standard
+locations such as <filename>/usr/lib</filename>. Programs built on
+Linux are linked against a GNU C Library that likewise doesn't search
+in the default system locations.</para>
+
+</section>
+
+
</chapter>