mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-26 07:46:21 +02:00
Get rid of callouts since Markdown doesn't support them
This commit is contained in:
parent
efff6cf163
commit
13df1faf25
12 changed files with 233 additions and 251 deletions
|
@ -6,20 +6,25 @@
|
||||||
|
|
||||||
<title>Arguments and Variables</title>
|
<title>Arguments and Variables</title>
|
||||||
|
|
||||||
<example xml:id='ex-hello-composition'>
|
<para>The Nix expression in <xref linkend='ex-hello-nix' /> is a
|
||||||
|
function; it is missing some arguments that have to be filled in
|
||||||
|
somewhere. In the Nix Packages collection this is done in the file
|
||||||
|
<filename>pkgs/top-level/all-packages.nix</filename>, where all Nix
|
||||||
|
expressions for packages are imported and called with the appropriate
|
||||||
|
arguments. Here are some fragments of
|
||||||
|
<filename>all-packages.nix</filename>, with annotations of what they
|
||||||
|
mean:</para>
|
||||||
|
|
||||||
<title>Composing GNU Hello
|
|
||||||
(<filename>all-packages.nix</filename>)</title>
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
...
|
...
|
||||||
|
|
||||||
rec { <co xml:id='ex-hello-composition-co-1' />
|
rec { ①
|
||||||
|
|
||||||
hello = import ../applications/misc/hello/ex-1 <co xml:id='ex-hello-composition-co-2' /> { <co xml:id='ex-hello-composition-co-3' />
|
hello = import ../applications/misc/hello/ex-1 ② { ③
|
||||||
inherit fetchurl stdenv perl;
|
inherit fetchurl stdenv perl;
|
||||||
};
|
};
|
||||||
|
|
||||||
perl = import ../development/interpreters/perl { <co xml:id='ex-hello-composition-co-4' />
|
perl = import ../development/interpreters/perl { ④
|
||||||
inherit fetchurl stdenv;
|
inherit fetchurl stdenv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,31 +36,19 @@ rec { <co xml:id='ex-hello-composition-co-1' />
|
||||||
|
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>The Nix expression in <xref linkend='ex-hello-nix' /> is a
|
<orderedlist>
|
||||||
function; it is missing some arguments that have to be filled in
|
|
||||||
somewhere. In the Nix Packages collection this is done in the file
|
|
||||||
<filename>pkgs/top-level/all-packages.nix</filename>, where all
|
|
||||||
Nix expressions for packages are imported and called with the
|
|
||||||
appropriate arguments. <xref linkend='ex-hello-composition' /> shows
|
|
||||||
some fragments of
|
|
||||||
<filename>all-packages.nix</filename>.</para>
|
|
||||||
|
|
||||||
<calloutlist>
|
|
||||||
|
|
||||||
<callout arearefs='ex-hello-composition-co-1'>
|
|
||||||
|
|
||||||
|
<listitem>
|
||||||
<para>This file defines a set of attributes, all of which are
|
<para>This file defines a set of attributes, all of which are
|
||||||
concrete derivations (i.e., not functions). In fact, we define a
|
concrete derivations (i.e., not functions). In fact, we define a
|
||||||
<emphasis>mutually recursive</emphasis> set of attributes. That
|
<emphasis>mutually recursive</emphasis> set of attributes. That
|
||||||
is, the attributes can refer to each other. This is precisely
|
is, the attributes can refer to each other. This is precisely
|
||||||
what we want since we want to <quote>plug</quote> the
|
what we want since we want to <quote>plug</quote> the
|
||||||
various packages into each other.</para>
|
various packages into each other.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
</callout>
|
<listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-composition-co-2'>
|
|
||||||
|
|
||||||
<para>Here we <emphasis>import</emphasis> the Nix expression for
|
<para>Here we <emphasis>import</emphasis> the Nix expression for
|
||||||
GNU Hello. The import operation just loads and returns the
|
GNU Hello. The import operation just loads and returns the
|
||||||
|
@ -71,9 +64,9 @@ some fragments of
|
||||||
When you try to import a directory, Nix automatically appends
|
When you try to import a directory, Nix automatically appends
|
||||||
<filename>/default.nix</filename> to the file name.</para>
|
<filename>/default.nix</filename> to the file name.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-composition-co-3'>
|
<listitem>
|
||||||
|
|
||||||
<para>This is where the actual composition takes place. Here we
|
<para>This is where the actual composition takes place. Here we
|
||||||
<emphasis>call</emphasis> the function imported from
|
<emphasis>call</emphasis> the function imported from
|
||||||
|
@ -107,15 +100,15 @@ hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
|
||||||
|
|
||||||
</para></note>
|
</para></note>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-composition-co-4'>
|
<listitem>
|
||||||
|
|
||||||
<para>Likewise, we have to instantiate Perl,
|
<para>Likewise, we have to instantiate Perl,
|
||||||
<varname>fetchurl</varname>, and the standard environment.</para>
|
<varname>fetchurl</varname>, and the standard environment.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
</calloutlist>
|
</orderedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -6,32 +6,30 @@
|
||||||
|
|
||||||
<title>Build Script</title>
|
<title>Build Script</title>
|
||||||
|
|
||||||
<example xml:id='ex-hello-builder'><title>Build script for GNU Hello
|
<para>Here is the builder referenced
|
||||||
(<filename>builder.sh</filename>)</title>
|
|
||||||
<programlisting>
|
|
||||||
source $stdenv/setup <co xml:id='ex-hello-builder-co-1' />
|
|
||||||
|
|
||||||
PATH=$perl/bin:$PATH <co xml:id='ex-hello-builder-co-2' />
|
|
||||||
|
|
||||||
tar xvfz $src <co xml:id='ex-hello-builder-co-3' />
|
|
||||||
cd hello-*
|
|
||||||
./configure --prefix=$out <co xml:id='ex-hello-builder-co-4' />
|
|
||||||
make <co xml:id='ex-hello-builder-co-5' />
|
|
||||||
make install</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para><xref linkend='ex-hello-builder' /> shows the builder referenced
|
|
||||||
from Hello's Nix expression (stored in
|
from Hello's Nix expression (stored in
|
||||||
<filename>pkgs/applications/misc/hello/ex-1/builder.sh</filename>).
|
<filename>pkgs/applications/misc/hello/ex-1/builder.sh</filename>):</para>
|
||||||
The builder can actually be made a lot shorter by using the
|
|
||||||
|
<programlisting>
|
||||||
|
source $stdenv/setup ①
|
||||||
|
|
||||||
|
PATH=$perl/bin:$PATH ②
|
||||||
|
|
||||||
|
tar xvfz $src ③
|
||||||
|
cd hello-*
|
||||||
|
./configure --prefix=$out ④
|
||||||
|
make ⑤
|
||||||
|
make install</programlisting>
|
||||||
|
|
||||||
|
<para>The builder can actually be made a lot shorter by using the
|
||||||
<emphasis>generic builder</emphasis> functions provided by
|
<emphasis>generic builder</emphasis> functions provided by
|
||||||
<varname>stdenv</varname>, but here we write out the build steps to
|
<varname>stdenv</varname>, but here we write out the build steps to
|
||||||
elucidate what a builder does. It performs the following
|
elucidate what a builder does. It performs the following
|
||||||
steps:</para>
|
steps:</para>
|
||||||
|
|
||||||
<calloutlist>
|
<orderedlist>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder-co-1'>
|
<listitem>
|
||||||
|
|
||||||
<para>When Nix runs a builder, it initially completely clears the
|
<para>When Nix runs a builder, it initially completely clears the
|
||||||
environment (except for the attributes declared in the
|
environment (except for the attributes declared in the
|
||||||
|
@ -52,9 +50,9 @@ steps:</para>
|
||||||
attribute in <xref linkend='ex-hello-nix' />, but
|
attribute in <xref linkend='ex-hello-nix' />, but
|
||||||
<varname>mkDerivation</varname> adds it automatically.)</para>
|
<varname>mkDerivation</varname> adds it automatically.)</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder-co-2'>
|
<listitem>
|
||||||
|
|
||||||
<para>Since Hello needs Perl, we have to make sure that Perl is in
|
<para>Since Hello needs Perl, we have to make sure that Perl is in
|
||||||
the <literal>PATH</literal>. The <literal>perl</literal> environment
|
the <literal>PATH</literal>. The <literal>perl</literal> environment
|
||||||
|
@ -63,9 +61,9 @@ steps:</para>
|
||||||
<filename><replaceable>$perl</replaceable>/bin</filename> is the
|
<filename><replaceable>$perl</replaceable>/bin</filename> is the
|
||||||
directory containing the Perl interpreter.</para>
|
directory containing the Perl interpreter.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder-co-3'>
|
<listitem>
|
||||||
|
|
||||||
<para>Now we have to unpack the sources. The
|
<para>Now we have to unpack the sources. The
|
||||||
<varname>src</varname> attribute was bound to the result of
|
<varname>src</varname> attribute was bound to the result of
|
||||||
|
@ -82,9 +80,9 @@ steps:</para>
|
||||||
always newly created, so you don't have to worry about files from
|
always newly created, so you don't have to worry about files from
|
||||||
previous builds interfering with the current build.</para>
|
previous builds interfering with the current build.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder-co-4'>
|
<listitem>
|
||||||
|
|
||||||
<para>GNU Hello is a typical Autoconf-based package, so we first
|
<para>GNU Hello is a typical Autoconf-based package, so we first
|
||||||
have to run its <filename>configure</filename> script. In Nix
|
have to run its <filename>configure</filename> script. In Nix
|
||||||
|
@ -98,17 +96,17 @@ steps:</para>
|
||||||
<literal>--prefix=$out</literal> to cause Hello to be installed in
|
<literal>--prefix=$out</literal> to cause Hello to be installed in
|
||||||
the expected location.</para>
|
the expected location.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder-co-5'>
|
<listitem>
|
||||||
|
|
||||||
<para>Finally we build Hello (<literal>make</literal>) and install
|
<para>Finally we build Hello (<literal>make</literal>) and install
|
||||||
it into the location specified by <literal>out</literal>
|
it into the location specified by <literal>out</literal>
|
||||||
(<literal>make install</literal>).</para>
|
(<literal>make install</literal>).</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
</calloutlist>
|
</orderedlist>
|
||||||
|
|
||||||
<para>If you are wondering about the absence of error checking on the
|
<para>If you are wondering about the absence of error checking on the
|
||||||
result of various commands called in the builder: this is because the
|
result of various commands called in the builder: this is because the
|
||||||
|
@ -116,4 +114,4 @@ shell script is evaluated with Bash's <option>-e</option> option,
|
||||||
which causes the script to be aborted if any command fails without an
|
which causes the script to be aborted if any command fails without an
|
||||||
error check.</para>
|
error check.</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1511,39 +1511,9 @@ in foo</programlisting>
|
||||||
<!-- TODO: more formally describe the schema of the XML
|
<!-- TODO: more formally describe the schema of the XML
|
||||||
representation -->
|
representation -->
|
||||||
|
|
||||||
<para><xref linkend='ex-toxml' /> shows an example where this is
|
<para>Here is an example where this is
|
||||||
the case. The builder is supposed to generate the configuration
|
the case:
|
||||||
file for a <link xlink:href='http://jetty.mortbay.org/'>Jetty
|
</para>
|
||||||
servlet container</link>. A servlet container contains a number
|
|
||||||
of servlets (<filename>*.war</filename> files) each exported under
|
|
||||||
a specific URI prefix. So the servlet configuration is a list of
|
|
||||||
sets containing the <varname>path</varname> and
|
|
||||||
<varname>war</varname> of the servlet (<xref
|
|
||||||
linkend='ex-toxml-co-servlets' />). This kind of information is
|
|
||||||
difficult to communicate with the normal method of passing
|
|
||||||
information through an environment variable, which just
|
|
||||||
concatenates everything together into a string (which might just
|
|
||||||
work in this case, but wouldn’t work if fields are optional or
|
|
||||||
contain lists themselves). Instead the Nix expression is
|
|
||||||
converted to an XML representation with
|
|
||||||
<function>toXML</function>, which is unambiguous and can easily be
|
|
||||||
processed with the appropriate tools. For instance, in the
|
|
||||||
example an XSLT stylesheet (<xref linkend='ex-toxml-co-stylesheet'
|
|
||||||
/>) is applied to it (<xref linkend='ex-toxml-co-apply' />) to
|
|
||||||
generate the XML configuration file for the Jetty server. The XML
|
|
||||||
representation produced from <xref linkend='ex-toxml-co-servlets'
|
|
||||||
/> by <function>toXML</function> is shown in <xref
|
|
||||||
linkend='ex-toxml-result' />.</para>
|
|
||||||
|
|
||||||
<para>Note that <xref linkend='ex-toxml' /> uses the <function
|
|
||||||
linkend='builtin-toFile'>toFile</function> built-in to write the
|
|
||||||
builder and the stylesheet “inline” in the Nix expression. The
|
|
||||||
path of the stylesheet is spliced into the builder at
|
|
||||||
<literal>xsltproc ${stylesheet}
|
|
||||||
<replaceable>...</replaceable></literal>.</para>
|
|
||||||
|
|
||||||
<example xml:id='ex-toxml'><title>Passing information to a builder
|
|
||||||
using <function>toXML</function></title>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[
|
<programlisting><![CDATA[
|
||||||
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
|
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
|
||||||
|
@ -1556,10 +1526,10 @@ stdenv.mkDerivation (rec {
|
||||||
builder = builtins.toFile "builder.sh" "
|
builder = builtins.toFile "builder.sh" "
|
||||||
source $stdenv/setup
|
source $stdenv/setup
|
||||||
mkdir $out
|
mkdir $out
|
||||||
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml]]> <co xml:id='ex-toxml-co-apply' /> <![CDATA[
|
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml]]> ① <![CDATA[
|
||||||
";
|
";
|
||||||
|
|
||||||
stylesheet = builtins.toFile "stylesheet.xsl"]]> <co xml:id='ex-toxml-co-stylesheet' /> <![CDATA[
|
stylesheet = builtins.toFile "stylesheet.xsl"]]> ② <![CDATA[
|
||||||
"<?xml version='1.0' encoding='UTF-8'?>
|
"<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
||||||
<xsl:template match='/'>
|
<xsl:template match='/'>
|
||||||
|
@ -1575,16 +1545,32 @@ stdenv.mkDerivation (rec {
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
";
|
";
|
||||||
|
|
||||||
servlets = builtins.toXML []]> <co xml:id='ex-toxml-co-servlets' /> <![CDATA[
|
servlets = builtins.toXML []]> ③ <![CDATA[
|
||||||
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
|
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
|
||||||
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
|
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
|
||||||
];
|
];
|
||||||
})]]></programlisting>
|
})]]></programlisting>
|
||||||
|
|
||||||
</example>
|
<para>The builder is supposed to generate the configuration file
|
||||||
|
for a <link xlink:href='http://jetty.mortbay.org/'>Jetty servlet
|
||||||
<example xml:id='ex-toxml-result'><title>XML representation produced by
|
container</link>. A servlet container contains a number of
|
||||||
<function>toXML</function></title>
|
servlets (<filename>*.war</filename> files) each exported under a
|
||||||
|
specific URI prefix. So the servlet configuration is a list of
|
||||||
|
sets containing the <varname>path</varname> and
|
||||||
|
<varname>war</varname> of the servlet (<xref
|
||||||
|
linkend='ex-toxml-co-servlets' />). This kind of information is
|
||||||
|
difficult to communicate with the normal method of passing
|
||||||
|
information through an environment variable, which just
|
||||||
|
concatenates everything together into a string (which might just
|
||||||
|
work in this case, but wouldn’t work if fields are optional or
|
||||||
|
contain lists themselves). Instead the Nix expression is
|
||||||
|
converted to an XML representation with
|
||||||
|
<function>toXML</function>, which is unambiguous and can easily be
|
||||||
|
processed with the appropriate tools. For instance, in the
|
||||||
|
example an XSLT stylesheet (at point ②) is applied to it (at point
|
||||||
|
①) to generate the XML configuration file for the Jetty server.
|
||||||
|
The XML representation produced at point ③ by
|
||||||
|
<function>toXML</function> is as follows:</para>
|
||||||
|
|
||||||
<programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
|
<programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
|
||||||
<expr>
|
<expr>
|
||||||
|
@ -1608,7 +1594,11 @@ stdenv.mkDerivation (rec {
|
||||||
</list>
|
</list>
|
||||||
</expr>]]></programlisting>
|
</expr>]]></programlisting>
|
||||||
|
|
||||||
</example>
|
<para>Note that <xref linkend='ex-toxml' /> uses the <function
|
||||||
|
linkend='builtin-toFile'>toFile</function> built-in to write the
|
||||||
|
builder and the stylesheet “inline” in the Nix expression. The
|
||||||
|
path of the stylesheet is spliced into the builder using the
|
||||||
|
syntax <literal>xsltproc ${stylesheet}</literal>.</para>
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
|
|
@ -6,33 +6,31 @@
|
||||||
|
|
||||||
<title>Expression Syntax</title>
|
<title>Expression Syntax</title>
|
||||||
|
|
||||||
<example xml:id='ex-hello-nix'><title>Nix expression for GNU Hello
|
<para>Here is a Nix expression for GNU Hello:</para>
|
||||||
(<filename>default.nix</filename>)</title>
|
|
||||||
<programlisting>
|
|
||||||
{ stdenv, fetchurl, perl }: <co xml:id='ex-hello-nix-co-1' />
|
|
||||||
|
|
||||||
stdenv.mkDerivation { <co xml:id='ex-hello-nix-co-2' />
|
<programlisting>
|
||||||
name = "hello-2.1.1"; <co xml:id='ex-hello-nix-co-3' />
|
{ stdenv, fetchurl, perl }: ①
|
||||||
builder = ./builder.sh; <co xml:id='ex-hello-nix-co-4' />
|
|
||||||
src = fetchurl { <co xml:id='ex-hello-nix-co-5' />
|
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";
|
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||||
};
|
};
|
||||||
inherit perl; <co xml:id='ex-hello-nix-co-6' />
|
inherit perl; ⑥
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</example>
|
|
||||||
|
|
||||||
<para><xref linkend='ex-hello-nix' /> shows a Nix expression for GNU
|
<para>This file is actually already in the Nix Packages collection in
|
||||||
Hello. It's actually already in the Nix Packages collection in
|
|
||||||
<filename>pkgs/applications/misc/hello/ex-1/default.nix</filename>.
|
<filename>pkgs/applications/misc/hello/ex-1/default.nix</filename>.
|
||||||
It is customary to place each package in a separate directory and call
|
It is customary to place each package in a separate directory and call
|
||||||
the single Nix expression in that directory
|
the single Nix expression in that directory
|
||||||
<filename>default.nix</filename>. The file has the following elements
|
<filename>default.nix</filename>. The file has the following elements
|
||||||
(referenced from the figure by number):
|
(referenced from the figure by number):
|
||||||
|
|
||||||
<calloutlist>
|
<orderedlist>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-nix-co-1'>
|
<listitem>
|
||||||
|
|
||||||
<para>This states that the expression is a
|
<para>This states that the expression is a
|
||||||
<emphasis>function</emphasis> that expects to be called with three
|
<emphasis>function</emphasis> that expects to be called with three
|
||||||
|
@ -57,9 +55,9 @@ the single Nix expression in that directory
|
||||||
function; when given the required arguments, the body should
|
function; when given the required arguments, the body should
|
||||||
describe how to build an instance of the Hello package.</para>
|
describe how to build an instance of the Hello package.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-nix-co-2'>
|
<listitem>
|
||||||
|
|
||||||
<para>So we have to build a package. Building something from
|
<para>So we have to build a package. Building something from
|
||||||
other stuff is called a <emphasis>derivation</emphasis> in Nix (as
|
other stuff is called a <emphasis>derivation</emphasis> in Nix (as
|
||||||
|
@ -76,9 +74,9 @@ the single Nix expression in that directory
|
||||||
<replaceable>nameN</replaceable> =
|
<replaceable>nameN</replaceable> =
|
||||||
<replaceable>exprN</replaceable>; }</literal>.</para>
|
<replaceable>exprN</replaceable>; }</literal>.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-nix-co-3'>
|
<listitem>
|
||||||
|
|
||||||
<para>The attribute <varname>name</varname> specifies the symbolic
|
<para>The attribute <varname>name</varname> specifies the symbolic
|
||||||
name and version of the package. Nix doesn't really care about
|
name and version of the package. Nix doesn't really care about
|
||||||
|
@ -87,9 +85,9 @@ the single Nix expression in that directory
|
||||||
packages. This attribute is required by
|
packages. This attribute is required by
|
||||||
<varname>mkDerivation</varname>.</para>
|
<varname>mkDerivation</varname>.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-nix-co-4'>
|
<listitem>
|
||||||
|
|
||||||
<para>The attribute <varname>builder</varname> specifies the
|
<para>The attribute <varname>builder</varname> specifies the
|
||||||
builder. This attribute can sometimes be omitted, in which case
|
builder. This attribute can sometimes be omitted, in which case
|
||||||
|
@ -101,9 +99,9 @@ the single Nix expression in that directory
|
||||||
<command>./builder.sh</command> refers to the shell script shown
|
<command>./builder.sh</command> refers to the shell script shown
|
||||||
in <xref linkend='ex-hello-builder' />, discussed below.</para>
|
in <xref linkend='ex-hello-builder' />, discussed below.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-nix-co-5'>
|
<listitem>
|
||||||
|
|
||||||
<para>The builder has to know what the sources of the package
|
<para>The builder has to know what the sources of the package
|
||||||
are. Here, the attribute <varname>src</varname> is bound to the
|
are. Here, the attribute <varname>src</varname> is bound to the
|
||||||
|
@ -120,9 +118,9 @@ the single Nix expression in that directory
|
||||||
customary, and it's also expected by the default builder (which we
|
customary, and it's also expected by the default builder (which we
|
||||||
don't use in this example).</para>
|
don't use in this example).</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-nix-co-6'>
|
<listitem>
|
||||||
|
|
||||||
<para>Since the derivation requires Perl, we have to pass the
|
<para>Since the derivation requires Perl, we have to pass the
|
||||||
value of the <varname>perl</varname> function argument to the
|
value of the <varname>perl</varname> function argument to the
|
||||||
|
@ -139,9 +137,9 @@ perl = perl;</programlisting>
|
||||||
causes the specified attributes to be bound to whatever variables
|
causes the specified attributes to be bound to whatever variables
|
||||||
with the same name happen to be in scope.</para>
|
with the same name happen to be in scope.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
</calloutlist>
|
</orderedlist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
|
@ -20,23 +20,21 @@ make install</programlisting>
|
||||||
The builders for almost all Unix packages look like this — set up some
|
The builders for almost all Unix packages look like this — set up some
|
||||||
environment variables, unpack the sources, configure, build, and
|
environment variables, unpack the sources, configure, build, and
|
||||||
install. For this reason the standard environment provides some Bash
|
install. For this reason the standard environment provides some Bash
|
||||||
functions that automate the build process. A builder using the
|
functions that automate the build process. Here is what a builder
|
||||||
generic build facilities in shown in <xref linkend='ex-hello-builder2'
|
using the generic build facilities looks like:</para>
|
||||||
/>.</para>
|
|
||||||
|
|
||||||
<example xml:id='ex-hello-builder2'><title>Build script using the generic
|
|
||||||
build functions</title>
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
buildInputs="$perl" <co xml:id='ex-hello-builder2-co-1' />
|
buildInputs="$perl" ①
|
||||||
|
|
||||||
source $stdenv/setup <co xml:id='ex-hello-builder2-co-2' />
|
source $stdenv/setup ②
|
||||||
|
|
||||||
genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
|
genericBuild ③</programlisting>
|
||||||
</example>
|
|
||||||
|
|
||||||
<calloutlist>
|
<para>Here is what each line means:
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder2-co-1'>
|
<orderedlist>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
|
||||||
<para>The <literal>buildInputs</literal> variable tells
|
<para>The <literal>buildInputs</literal> variable tells
|
||||||
<filename>setup</filename> to use the indicated packages as
|
<filename>setup</filename> to use the indicated packages as
|
||||||
|
@ -54,16 +52,16 @@ genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
|
||||||
inputs.</para></footnote>
|
inputs.</para></footnote>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder2-co-2'>
|
<listitem arearefs='ex-hello-builder2-co-2'>
|
||||||
|
|
||||||
<para>The function <function>genericBuild</function> is defined in
|
<para>The function <function>genericBuild</function> is defined in
|
||||||
the file <literal>$stdenv/setup</literal>.</para>
|
the file <literal>$stdenv/setup</literal>.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-hello-builder2-co-3'>
|
<listitem arearefs='ex-hello-builder2-co-3'>
|
||||||
|
|
||||||
<para>The final step calls the shell function
|
<para>The final step calls the shell function
|
||||||
<function>genericBuild</function>, which performs the steps that
|
<function>genericBuild</function>, which performs the steps that
|
||||||
|
@ -73,9 +71,11 @@ genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
|
||||||
<command>bzip2</command>, etc. It can be customised in many ways;
|
<command>bzip2</command>, etc. It can be customised in many ways;
|
||||||
see the Nixpkgs manual for details.</para>
|
see the Nixpkgs manual for details.</para>
|
||||||
|
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
</calloutlist>
|
</orderedlist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>Discerning readers will note that the
|
<para>Discerning readers will note that the
|
||||||
<literal>buildInputs</literal> could just as well have been set in the Nix
|
<literal>buildInputs</literal> could just as well have been set in the Nix
|
||||||
|
|
|
@ -278,7 +278,9 @@ evaluate to a Boolean value. If it evaluates to
|
||||||
<literal>true</literal>, <replaceable>e2</replaceable> is returned;
|
<literal>true</literal>, <replaceable>e2</replaceable> is returned;
|
||||||
otherwise expression evaluation is aborted and a backtrace is printed.</para>
|
otherwise expression evaluation is aborted and a backtrace is printed.</para>
|
||||||
|
|
||||||
<example xml:id='ex-subversion-nix'><title>Nix expression for Subversion</title>
|
<para>Here is a Nix expression for the Subversion package that shows
|
||||||
|
how assertions can be used:.</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ localServer ? false
|
{ localServer ? false
|
||||||
, httpServer ? false
|
, httpServer ? false
|
||||||
|
@ -290,9 +292,9 @@ otherwise expression evaluation is aborted and a backtrace is printed.</para>
|
||||||
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
|
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
|
||||||
}:
|
}:
|
||||||
|
|
||||||
assert localServer -> db4 != null; <co xml:id='ex-subversion-nix-co-1' />
|
assert localServer -> db4 != null; ①
|
||||||
assert httpServer -> httpd != null && httpd.expat == expat; <co xml:id='ex-subversion-nix-co-2' />
|
assert httpServer -> httpd != null && httpd.expat == expat; ②
|
||||||
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); <co xml:id='ex-subversion-nix-co-3' />
|
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); ③
|
||||||
assert pythonBindings -> swig != null && swig.pythonSupport;
|
assert pythonBindings -> swig != null && swig.pythonSupport;
|
||||||
assert javaSwigBindings -> swig != null && swig.javaSupport;
|
assert javaSwigBindings -> swig != null && swig.javaSupport;
|
||||||
assert javahlBindings -> j2sdk != null;
|
assert javahlBindings -> j2sdk != null;
|
||||||
|
@ -300,26 +302,24 @@ assert javahlBindings -> j2sdk != null;
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "subversion-1.1.1";
|
name = "subversion-1.1.1";
|
||||||
...
|
...
|
||||||
openssl = if sslSupport then openssl else null; <co xml:id='ex-subversion-nix-co-4' />
|
openssl = if sslSupport then openssl else null; ④
|
||||||
...
|
...
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</example>
|
|
||||||
|
|
||||||
<para><xref linkend='ex-subversion-nix' /> show how assertions are
|
<para>The points of interest are:</para>
|
||||||
used in the Nix expression for Subversion.</para>
|
|
||||||
|
|
||||||
<calloutlist>
|
<orderedlist>
|
||||||
|
|
||||||
<callout arearefs='ex-subversion-nix-co-1'>
|
<listitem>
|
||||||
<para>This assertion states that if Subversion is to have support
|
<para>This assertion states that if Subversion is to have support
|
||||||
for local repositories, then Berkeley DB is needed. So if the
|
for local repositories, then Berkeley DB is needed. So if the
|
||||||
Subversion function is called with the
|
Subversion function is called with the
|
||||||
<varname>localServer</varname> argument set to
|
<varname>localServer</varname> argument set to
|
||||||
<literal>true</literal> but the <varname>db4</varname> argument
|
<literal>true</literal> but the <varname>db4</varname> argument
|
||||||
set to <literal>null</literal>, then the evaluation fails.</para>
|
set to <literal>null</literal>, then the evaluation fails.</para>
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-subversion-nix-co-2'>
|
<listitem>
|
||||||
<para>This is a more subtle condition: if Subversion is built with
|
<para>This is a more subtle condition: if Subversion is built with
|
||||||
Apache (<literal>httpServer</literal>) support, then the Expat
|
Apache (<literal>httpServer</literal>) support, then the Expat
|
||||||
library (an XML library) used by Subversion should be same as the
|
library (an XML library) used by Subversion should be same as the
|
||||||
|
@ -327,27 +327,27 @@ used in the Nix expression for Subversion.</para>
|
||||||
Subversion code ends up being linked with Apache code, and if the
|
Subversion code ends up being linked with Apache code, and if the
|
||||||
Expat libraries do not match, a build- or runtime link error or
|
Expat libraries do not match, a build- or runtime link error or
|
||||||
incompatibility might occur.</para>
|
incompatibility might occur.</para>
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-subversion-nix-co-3'>
|
<listitem>
|
||||||
<para>This assertion says that in order for Subversion to have SSL
|
<para>This assertion says that in order for Subversion to have SSL
|
||||||
support (so that it can access <literal>https</literal> URLs), an
|
support (so that it can access <literal>https</literal> URLs), an
|
||||||
OpenSSL library must be passed. Additionally, it says that
|
OpenSSL library must be passed. Additionally, it says that
|
||||||
<emphasis>if</emphasis> Apache support is enabled, then Apache's
|
<emphasis>if</emphasis> Apache support is enabled, then Apache's
|
||||||
OpenSSL should match Subversion's. (Note that if Apache support
|
OpenSSL should match Subversion's. (Note that if Apache support
|
||||||
is not enabled, we don't care about Apache's OpenSSL.)</para>
|
is not enabled, we don't care about Apache's OpenSSL.)</para>
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
<callout arearefs='ex-subversion-nix-co-4'>
|
<listitem>
|
||||||
<para>The conditional here is not really related to assertions,
|
<para>The conditional here is not really related to assertions,
|
||||||
but is worth pointing out: it ensures that if SSL support is
|
but is worth pointing out: it ensures that if SSL support is
|
||||||
disabled, then the Subversion derivation is not dependent on
|
disabled, then the Subversion derivation is not dependent on
|
||||||
OpenSSL, even if a non-<literal>null</literal> value was passed.
|
OpenSSL, even if a non-<literal>null</literal> value was passed.
|
||||||
This prevents an unnecessary rebuild of Subversion if OpenSSL
|
This prevents an unnecessary rebuild of Subversion if OpenSSL
|
||||||
changes.</para>
|
changes.</para>
|
||||||
</callout>
|
</listitem>
|
||||||
|
|
||||||
</calloutlist>
|
</orderedlist>
|
||||||
|
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
# Arguments and Variables
|
# Arguments and Variables
|
||||||
|
|
||||||
|
The Nix expression in [???](#ex-hello-nix) is a function; it is missing
|
||||||
|
some arguments that have to be filled in somewhere. In the Nix Packages
|
||||||
|
collection this is done in the file `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:
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
rec {
|
rec { ①
|
||||||
|
|
||||||
hello = import ../applications/misc/hello/ex-1 {
|
hello = import ../applications/misc/hello/ex-1 ② { ③
|
||||||
inherit fetchurl stdenv perl;
|
inherit fetchurl stdenv perl;
|
||||||
};
|
};
|
||||||
|
|
||||||
perl = import ../development/interpreters/perl {
|
perl = import ../development/interpreters/perl { ④
|
||||||
inherit fetchurl stdenv;
|
inherit fetchurl stdenv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,20 +27,13 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
The Nix expression in [???](#ex-hello-nix) is a function; it is missing
|
1. This file defines a set of attributes, all of which are concrete
|
||||||
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. [example\_title](#ex-hello-composition) shows
|
|
||||||
some fragments of `all-packages.nix`.
|
|
||||||
|
|
||||||
- This file defines a set of attributes, all of which are concrete
|
|
||||||
derivations (i.e., not functions). In fact, we define a *mutually
|
derivations (i.e., not functions). In fact, we define a *mutually
|
||||||
recursive* set of attributes. That is, the attributes can refer to
|
recursive* set of attributes. That is, the attributes can refer to
|
||||||
each other. This is precisely what we want since we want to “plug”
|
each other. This is precisely what we want since we want to “plug”
|
||||||
the various packages into each other.
|
the various packages into each other.
|
||||||
|
|
||||||
- Here we *import* the Nix expression for GNU Hello. The import
|
2. Here we *import* the Nix expression for GNU Hello. The import
|
||||||
operation just loads and returns the specified Nix expression. In
|
operation just loads and returns the specified Nix expression. In
|
||||||
fact, we could just have put the contents of [???](#ex-hello-nix) in
|
fact, we could just have put the contents of [???](#ex-hello-nix) in
|
||||||
`all-packages.nix` at this point. That would be completely
|
`all-packages.nix` at this point. That would be completely
|
||||||
|
@ -44,7 +44,7 @@ some fragments of `all-packages.nix`.
|
||||||
import a directory, Nix automatically appends `/default.nix` to the
|
import a directory, Nix automatically appends `/default.nix` to the
|
||||||
file name.
|
file name.
|
||||||
|
|
||||||
- This is where the actual composition takes place. Here we *call* the
|
3. This is where the actual composition takes place. Here we *call* the
|
||||||
function imported from `../applications/misc/hello/ex-1` with a set
|
function imported from `../applications/misc/hello/ex-1` with a set
|
||||||
containing the things that the function expects, namely `fetchurl`,
|
containing the things that the function expects, namely `fetchurl`,
|
||||||
`stdenv`, and `perl`. We use inherit again to use the attributes
|
`stdenv`, and `perl`. We use inherit again to use the attributes
|
||||||
|
@ -68,5 +68,5 @@ some fragments of `all-packages.nix`.
|
||||||
>
|
>
|
||||||
> hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
|
> hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
|
||||||
|
|
||||||
- Likewise, we have to instantiate Perl, `fetchurl`, and the standard
|
4. Likewise, we have to instantiate Perl, `fetchurl`, and the standard
|
||||||
environment.
|
environment.
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
# Build Script
|
# Build Script
|
||||||
|
|
||||||
source $stdenv/setup
|
Here is the builder referenced from Hello's Nix expression (stored in
|
||||||
|
`pkgs/applications/misc/hello/ex-1/builder.sh`):
|
||||||
|
|
||||||
|
source $stdenv/setup ①
|
||||||
|
|
||||||
PATH=$perl/bin:$PATH
|
PATH=$perl/bin:$PATH ②
|
||||||
|
|
||||||
tar xvfz $src
|
tar xvfz $src ③
|
||||||
cd hello-*
|
cd hello-*
|
||||||
./configure --prefix=$out
|
./configure --prefix=$out ④
|
||||||
make
|
make ⑤
|
||||||
make install
|
make install
|
||||||
|
|
||||||
[example\_title](#ex-hello-builder) shows the builder referenced from
|
The builder can actually be made a lot shorter by using the *generic
|
||||||
Hello's Nix expression (stored in
|
builder* functions provided by `stdenv`, but here we write out the build
|
||||||
`pkgs/applications/misc/hello/ex-1/builder.sh`). The builder can
|
steps to elucidate what a builder does. It performs the following steps:
|
||||||
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:
|
|
||||||
|
|
||||||
- When Nix runs a builder, it initially completely clears the
|
1. When Nix runs a builder, it initially completely clears the
|
||||||
environment (except for the attributes declared in the derivation).
|
environment (except for the attributes declared in the derivation).
|
||||||
For instance, the `PATH` variable is empty\[1\]. This is done to
|
For instance, the `PATH` variable is empty\[1\]. This is done to
|
||||||
prevent undeclared inputs from being used in the build process. If
|
prevent undeclared inputs from being used in the build process. If
|
||||||
|
@ -31,13 +31,13 @@ what a builder does. It performs the following steps:
|
||||||
attribute in [???](#ex-hello-nix), but `mkDerivation` adds it
|
attribute in [???](#ex-hello-nix), but `mkDerivation` adds it
|
||||||
automatically.)
|
automatically.)
|
||||||
|
|
||||||
- Since Hello needs Perl, we have to make sure that Perl is in the
|
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
|
`PATH`. The `perl` environment variable points to the location of
|
||||||
the Perl package (since it was passed in as an attribute to the
|
the Perl package (since it was passed in as an attribute to the
|
||||||
derivation), so `$perl/bin` is the directory containing the Perl
|
derivation), so `$perl/bin` is the directory containing the Perl
|
||||||
interpreter.
|
interpreter.
|
||||||
|
|
||||||
- Now we have to unpack the sources. The `src` attribute was bound to
|
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 result of fetching the Hello source tarball from the network, so
|
||||||
the `src` environment variable points to the location in the Nix
|
the `src` environment variable points to the location in the Nix
|
||||||
store to which the tarball was downloaded. After unpacking, we `cd`
|
store to which the tarball was downloaded. After unpacking, we `cd`
|
||||||
|
@ -50,7 +50,7 @@ what a builder does. It performs the following steps:
|
||||||
have to worry about files from previous builds interfering with the
|
have to worry about files from previous builds interfering with the
|
||||||
current build.
|
current build.
|
||||||
|
|
||||||
- GNU Hello is a typical Autoconf-based package, so we first have to
|
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
|
run its `configure` script. In Nix every package is stored in a
|
||||||
separate location in the Nix store, for instance
|
separate location in the Nix store, for instance
|
||||||
`/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1`. Nix
|
`/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1`. Nix
|
||||||
|
@ -60,7 +60,7 @@ what a builder does. It performs the following steps:
|
||||||
`--prefix=$out` to cause Hello to be installed in the expected
|
`--prefix=$out` to cause Hello to be installed in the expected
|
||||||
location.
|
location.
|
||||||
|
|
||||||
- Finally we build Hello (`make`) and install it into the location
|
5. Finally we build Hello (`make`) and install it into the location
|
||||||
specified by `out` (`make install`).
|
specified by `out` (`make install`).
|
||||||
|
|
||||||
If you are wondering about the absence of error checking on the result
|
If you are wondering about the absence of error checking on the result
|
||||||
|
|
|
@ -735,31 +735,7 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
||||||
builder in a more structured format than plain environment
|
builder in a more structured format than plain environment
|
||||||
variables.
|
variables.
|
||||||
|
|
||||||
[example\_title](#ex-toxml) shows an example where this is the case.
|
Here is an example where this is the case:
|
||||||
The builder is supposed to generate the configuration file for a
|
|
||||||
[Jetty servlet container](http://jetty.mortbay.org/). A servlet
|
|
||||||
container contains a number of servlets (`*.war` files) each
|
|
||||||
exported under a specific URI prefix. So the servlet configuration
|
|
||||||
is a list of sets containing the `path` and `war` of the servlet
|
|
||||||
([co\_title](#ex-toxml-co-servlets)). This kind of information is
|
|
||||||
difficult to communicate with the normal method of passing
|
|
||||||
information through an environment variable, which just concatenates
|
|
||||||
everything together into a string (which might just work in this
|
|
||||||
case, but wouldn’t work if fields are optional or contain lists
|
|
||||||
themselves). Instead the Nix expression is converted to an XML
|
|
||||||
representation with `toXML`, which is unambiguous and can easily be
|
|
||||||
processed with the appropriate tools. For instance, in the example
|
|
||||||
an XSLT stylesheet ([co\_title](#ex-toxml-co-stylesheet)) is applied
|
|
||||||
to it ([co\_title](#ex-toxml-co-apply)) to generate the XML
|
|
||||||
configuration file for the Jetty server. The XML representation
|
|
||||||
produced from [co\_title](#ex-toxml-co-servlets) by `toXML` is shown
|
|
||||||
in [example\_title](#ex-toxml-result).
|
|
||||||
|
|
||||||
Note that [example\_title](#ex-toxml) uses the `toFile` built-in to
|
|
||||||
write the builder and the stylesheet “inline” in the Nix expression.
|
|
||||||
The path of the stylesheet is spliced into the builder at `xsltproc
|
|
||||||
${stylesheet}
|
|
||||||
...`.
|
|
||||||
|
|
||||||
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
|
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
|
||||||
|
|
||||||
|
@ -771,10 +747,10 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
||||||
builder = builtins.toFile "builder.sh" "
|
builder = builtins.toFile "builder.sh" "
|
||||||
source $stdenv/setup
|
source $stdenv/setup
|
||||||
mkdir $out
|
mkdir $out
|
||||||
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml
|
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml ①
|
||||||
";
|
";
|
||||||
|
|
||||||
stylesheet = builtins.toFile "stylesheet.xsl"
|
stylesheet = builtins.toFile "stylesheet.xsl" ②
|
||||||
"<?xml version='1.0' encoding='UTF-8'?>
|
"<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
|
||||||
<xsl:template match='/'>
|
<xsl:template match='/'>
|
||||||
|
@ -790,12 +766,29 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
";
|
";
|
||||||
|
|
||||||
servlets = builtins.toXML [
|
servlets = builtins.toXML [ ③
|
||||||
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
|
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
|
||||||
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
|
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
The builder is supposed to generate the configuration file for a
|
||||||
|
[Jetty servlet container](http://jetty.mortbay.org/). A servlet
|
||||||
|
container contains a number of servlets (`*.war` files) each
|
||||||
|
exported under a specific URI prefix. So the servlet configuration
|
||||||
|
is a list of sets containing the `path` and `war` of the servlet
|
||||||
|
([???](#ex-toxml-co-servlets)). This kind of information is
|
||||||
|
difficult to communicate with the normal method of passing
|
||||||
|
information through an environment variable, which just concatenates
|
||||||
|
everything together into a string (which might just work in this
|
||||||
|
case, but wouldn’t work if fields are optional or contain lists
|
||||||
|
themselves). Instead the Nix expression is converted to an XML
|
||||||
|
representation with `toXML`, which is unambiguous and can easily be
|
||||||
|
processed with the appropriate tools. For instance, in the example
|
||||||
|
an XSLT stylesheet (at point ②) is applied to it (at point ①) to
|
||||||
|
generate the XML configuration file for the Jetty server. The XML
|
||||||
|
representation produced at point ③ by `toXML` is as follows:
|
||||||
|
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<expr>
|
<expr>
|
||||||
<list>
|
<list>
|
||||||
|
@ -817,6 +810,11 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
||||||
</attrs>
|
</attrs>
|
||||||
</list>
|
</list>
|
||||||
</expr>
|
</expr>
|
||||||
|
|
||||||
|
Note that [???](#ex-toxml) uses the `toFile` built-in to write the
|
||||||
|
builder and the stylesheet “inline” in the Nix expression. The path
|
||||||
|
of the stylesheet is spliced into the builder using the syntax
|
||||||
|
`xsltproc ${stylesheet}`.
|
||||||
|
|
||||||
- `builtins.trace` e1 e2
|
- `builtins.trace` e1 e2
|
||||||
Evaluate e1 and print its abstract syntax representation on standard
|
Evaluate e1 and print its abstract syntax representation on standard
|
||||||
|
|
|
@ -1,25 +1,26 @@
|
||||||
# Expression Syntax
|
# Expression Syntax
|
||||||
|
|
||||||
{ stdenv, fetchurl, perl }:
|
Here is a Nix expression for GNU Hello:
|
||||||
|
|
||||||
|
{ stdenv, fetchurl, perl }: ①
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation { ②
|
||||||
name = "hello-2.1.1";
|
name = "hello-2.1.1"; ③
|
||||||
builder = ./builder.sh;
|
builder = ./builder.sh; ④
|
||||||
src = fetchurl {
|
src = fetchurl { ⑤
|
||||||
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||||
};
|
};
|
||||||
inherit perl;
|
inherit perl; ⑥
|
||||||
}
|
}
|
||||||
|
|
||||||
[example\_title](#ex-hello-nix) shows a Nix expression for GNU Hello.
|
This file is actually already in the Nix Packages collection in
|
||||||
It's actually already in the Nix Packages collection in
|
|
||||||
`pkgs/applications/misc/hello/ex-1/default.nix`. It is customary to
|
`pkgs/applications/misc/hello/ex-1/default.nix`. It is customary to
|
||||||
place each package in a separate directory and call the single Nix
|
place each package in a separate directory and call the single Nix
|
||||||
expression in that directory `default.nix`. The file has the following
|
expression in that directory `default.nix`. The file has the following
|
||||||
elements (referenced from the figure by number):
|
elements (referenced from the figure by number):
|
||||||
|
|
||||||
- This states that the expression is a *function* that expects to be
|
1. This states that the expression is a *function* that expects to be
|
||||||
called with three arguments: `stdenv`, `fetchurl`, and `perl`. They
|
called with three arguments: `stdenv`, `fetchurl`, and `perl`. They
|
||||||
are needed to build Hello, but we don't know how to build them here;
|
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
|
that's why they are function arguments. `stdenv` is a package that
|
||||||
|
@ -37,7 +38,7 @@ elements (referenced from the figure by number):
|
||||||
the required arguments, the body should describe how to build an
|
the required arguments, the body should describe how to build an
|
||||||
instance of the Hello package.
|
instance of the Hello package.
|
||||||
|
|
||||||
- So we have to build a package. Building something from other stuff
|
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
|
is called a *derivation* in Nix (as opposed to sources, which are
|
||||||
built by humans instead of computers). We perform a derivation by
|
built by humans instead of computers). We perform a derivation by
|
||||||
calling `stdenv.mkDerivation`. `mkDerivation` is a function provided
|
calling `stdenv.mkDerivation`. `mkDerivation` is a function provided
|
||||||
|
@ -50,13 +51,13 @@ elements (referenced from the figure by number):
|
||||||
nameN =
|
nameN =
|
||||||
exprN; }`.
|
exprN; }`.
|
||||||
|
|
||||||
- The attribute `name` specifies the symbolic name and version of the
|
3. The attribute `name` specifies the symbolic name and version of the
|
||||||
package. Nix doesn't really care about these things, but they are
|
package. Nix doesn't really care about these things, but they are
|
||||||
used by for instance `nix-env
|
used by for instance `nix-env
|
||||||
-q` to show a “human-readable” name for packages. This attribute is
|
-q` to show a “human-readable” name for packages. This attribute is
|
||||||
required by `mkDerivation`.
|
required by `mkDerivation`.
|
||||||
|
|
||||||
- The attribute `builder` specifies the builder. This attribute can
|
4. The attribute `builder` specifies the builder. This attribute can
|
||||||
sometimes be omitted, in which case `mkDerivation` will fill in a
|
sometimes be omitted, in which case `mkDerivation` will fill in a
|
||||||
default builder (which does a `configure; make; make install`, in
|
default builder (which does a `configure; make; make install`, in
|
||||||
essence). Hello is sufficiently simple that the default builder
|
essence). Hello is sufficiently simple that the default builder
|
||||||
|
@ -64,7 +65,7 @@ elements (referenced from the figure by number):
|
||||||
educational purposes. The value `./builder.sh` refers to the shell
|
educational purposes. The value `./builder.sh` refers to the shell
|
||||||
script shown in [???](#ex-hello-builder), discussed below.
|
script shown in [???](#ex-hello-builder), discussed below.
|
||||||
|
|
||||||
- The builder has to know what the sources of the package are. Here,
|
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
|
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
|
`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
|
contents of the file at that URL, this function builds a derivation
|
||||||
|
@ -77,7 +78,7 @@ elements (referenced from the figure by number):
|
||||||
However, `src` is customary, and it's also expected by the default
|
However, `src` is customary, and it's also expected by the default
|
||||||
builder (which we don't use in this example).
|
builder (which we don't use in this example).
|
||||||
|
|
||||||
- Since the derivation requires Perl, we have to pass the value of the
|
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
|
`perl` function argument to the builder. All attributes in the set
|
||||||
are actually passed as environment variables to the builder, so
|
are actually passed as environment variables to the builder, so
|
||||||
declaring an attribute
|
declaring an attribute
|
||||||
|
|
|
@ -13,24 +13,26 @@ like this:
|
||||||
The builders for almost all Unix packages look like this — set up some
|
The builders for almost all Unix packages look like this — set up some
|
||||||
environment variables, unpack the sources, configure, build, and
|
environment variables, unpack the sources, configure, build, and
|
||||||
install. For this reason the standard environment provides some Bash
|
install. For this reason the standard environment provides some Bash
|
||||||
functions that automate the build process. A builder using the generic
|
functions that automate the build process. Here is what a builder using
|
||||||
build facilities in shown in [example\_title](#ex-hello-builder2).
|
the generic build facilities looks like:
|
||||||
|
|
||||||
buildInputs="$perl"
|
buildInputs="$perl" ①
|
||||||
|
|
||||||
source $stdenv/setup
|
source $stdenv/setup ②
|
||||||
|
|
||||||
genericBuild
|
genericBuild ③
|
||||||
|
|
||||||
- The `buildInputs` variable tells `setup` to use the indicated
|
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`
|
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 `PATH`; if it has a `include`
|
||||||
subdirectory, it's added to GCC's header search path; and so
|
subdirectory, it's added to GCC's header search path; and so
|
||||||
on.\[1\]
|
on.\[1\]
|
||||||
|
|
||||||
- The function `genericBuild` is defined in the file `$stdenv/setup`.
|
2. The function `genericBuild` is defined in the file `$stdenv/setup`.
|
||||||
|
|
||||||
- The final step calls the shell function `genericBuild`, which
|
3. The final step calls the shell function `genericBuild`, which
|
||||||
performs the steps that were done explicitly in
|
performs the steps that were done explicitly in
|
||||||
[???](#ex-hello-builder). The generic builder is smart enough to
|
[???](#ex-hello-builder). The generic builder is smart enough to
|
||||||
figure out whether to unpack the sources using `gzip`, `bzip2`, etc.
|
figure out whether to unpack the sources using `gzip`, `bzip2`, etc.
|
||||||
|
|
|
@ -203,6 +203,9 @@ where e1 is an expression that should evaluate to a Boolean value. If it
|
||||||
evaluates to `true`, e2 is returned; otherwise expression evaluation is
|
evaluates to `true`, e2 is returned; otherwise expression evaluation is
|
||||||
aborted and a backtrace is printed.
|
aborted and a backtrace is printed.
|
||||||
|
|
||||||
|
Here is a Nix expression for the Subversion package that shows how
|
||||||
|
assertions can be used:.
|
||||||
|
|
||||||
{ localServer ? false
|
{ localServer ? false
|
||||||
, httpServer ? false
|
, httpServer ? false
|
||||||
, sslSupport ? false
|
, sslSupport ? false
|
||||||
|
@ -213,9 +216,9 @@ aborted and a backtrace is printed.
|
||||||
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
|
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
|
||||||
}:
|
}:
|
||||||
|
|
||||||
assert localServer -> db4 != null;
|
assert localServer -> db4 != null; ①
|
||||||
assert httpServer -> httpd != null && httpd.expat == expat;
|
assert httpServer -> httpd != null && httpd.expat == expat; ②
|
||||||
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);
|
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); ③
|
||||||
assert pythonBindings -> swig != null && swig.pythonSupport;
|
assert pythonBindings -> swig != null && swig.pythonSupport;
|
||||||
assert javaSwigBindings -> swig != null && swig.javaSupport;
|
assert javaSwigBindings -> swig != null && swig.javaSupport;
|
||||||
assert javahlBindings -> j2sdk != null;
|
assert javahlBindings -> j2sdk != null;
|
||||||
|
@ -223,33 +226,32 @@ aborted and a backtrace is printed.
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "subversion-1.1.1";
|
name = "subversion-1.1.1";
|
||||||
...
|
...
|
||||||
openssl = if sslSupport then openssl else null;
|
openssl = if sslSupport then openssl else null; ④
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
[example\_title](#ex-subversion-nix) show how assertions are used in the
|
The points of interest are:
|
||||||
Nix expression for Subversion.
|
|
||||||
|
|
||||||
- This assertion states that if Subversion is to have support for
|
1. This assertion states that if Subversion is to have support for
|
||||||
local repositories, then Berkeley DB is needed. So if the Subversion
|
local repositories, then Berkeley DB is needed. So if the Subversion
|
||||||
function is called with the `localServer` argument set to `true` but
|
function is called with the `localServer` argument set to `true` but
|
||||||
the `db4` argument set to `null`, then the evaluation fails.
|
the `db4` argument set to `null`, then the evaluation fails.
|
||||||
|
|
||||||
- This is a more subtle condition: if Subversion is built with Apache
|
2. This is a more subtle condition: if Subversion is built with Apache
|
||||||
(`httpServer`) support, then the Expat library (an XML library) used
|
(`httpServer`) support, then the Expat library (an XML library) used
|
||||||
by Subversion should be same as the one used by Apache. This is
|
by Subversion should be same as the one used by Apache. This is
|
||||||
because in this configuration Subversion code ends up being linked
|
because in this configuration Subversion code ends up being linked
|
||||||
with Apache code, and if the Expat libraries do not match, a build-
|
with Apache code, and if the Expat libraries do not match, a build-
|
||||||
or runtime link error or incompatibility might occur.
|
or runtime link error or incompatibility might occur.
|
||||||
|
|
||||||
- This assertion says that in order for Subversion to have SSL support
|
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
|
(so that it can access `https` URLs), an OpenSSL library must be
|
||||||
passed. Additionally, it says that *if* Apache support is enabled,
|
passed. Additionally, it says that *if* Apache support is enabled,
|
||||||
then Apache's OpenSSL should match Subversion's. (Note that if
|
then Apache's OpenSSL should match Subversion's. (Note that if
|
||||||
Apache support is not enabled, we don't care about Apache's
|
Apache support is not enabled, we don't care about Apache's
|
||||||
OpenSSL.)
|
OpenSSL.)
|
||||||
|
|
||||||
- The conditional here is not really related to assertions, but is
|
4. The conditional here is not really related to assertions, but is
|
||||||
worth pointing out: it ensures that if SSL support is disabled, then
|
worth pointing out: it ensures that if SSL support is disabled, then
|
||||||
the Subversion derivation is not dependent on OpenSSL, even if a
|
the Subversion derivation is not dependent on OpenSSL, even if a
|
||||||
non-`null` value was passed. This prevents an unnecessary rebuild of
|
non-`null` value was passed. This prevents an unnecessary rebuild of
|
||||||
|
|
Loading…
Reference in a new issue