<section xmlns="http://docbook.org/ns/docbook"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      version="5.0"
      xml:id='sec-generic-builder'>

<title>Generic Builder Syntax</title>

<para>Recall from <xref linkend='ex-hello-builder' /> that the builder
looked something like this:

<programlisting>
PATH=$perl/bin:$PATH
tar xvfz $src
cd hello-*
./configure --prefix=$out
make
make install</programlisting>

The builders for almost all Unix packages look like this — set up some
environment variables, unpack the sources, configure, build, and
install.  For this reason the standard environment provides some Bash
functions that automate the build process.  A builder using the
generic build facilities in shown in <xref linkend='ex-hello-builder2'
/>.</para>

<example xml:id='ex-hello-builder2'><title>Build script using the generic
build functions</title>
<programlisting>
buildInputs="$perl" <co xml:id='ex-hello-builder2-co-1' />

source $stdenv/setup <co xml:id='ex-hello-builder2-co-2' />

genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
</example>

<calloutlist>

  <callout arearefs='ex-hello-builder2-co-1'>

    <para>The <envar>buildInputs</envar> variable tells
    <filename>setup</filename> to use the indicated packages as
    <quote>inputs</quote>.  This means that if a package provides a
    <filename>bin</filename> subdirectory, it's added to
    <envar>PATH</envar>; if it has a <filename>include</filename>
    subdirectory, it's added to GCC's header search path; and so
    on.<footnote><para>How does it work? <filename>setup</filename>
    tries to source the file
    <filename><replaceable>pkg</replaceable>/nix-support/setup-hook</filename>
    of all dependencies.  These “setup hooks” can then set up whatever
    environment variables they want; for instance, the setup hook for
    Perl sets the <envar>PERL5LIB</envar> environment variable to
    contain the <filename>lib/site_perl</filename> directories of all
    inputs.</para></footnote>
    </para>

  </callout>

  <callout arearefs='ex-hello-builder2-co-2'>

    <para>The function <function>genericBuild</function> is defined in
    the file <literal>$stdenv/setup</literal>.</para>

  </callout>

  <callout arearefs='ex-hello-builder2-co-3'>

    <para>The final step calls the shell function
    <function>genericBuild</function>, which performs the steps that
    were done explicitly in <xref linkend='ex-hello-builder' />.  The
    generic builder is smart enough to figure out whether to unpack
    the sources using <command>gzip</command>,
    <command>bzip2</command>, etc.  It can be customised in many ways;
    see the Nixpkgs manual for details.</para>

  </callout>

</calloutlist>

<para>Discerning readers will note that the
<envar>buildInputs</envar> could just as well have been set in the Nix
expression, like this:

<programlisting>
  buildInputs = [ perl ];</programlisting>

The <varname>perl</varname> attribute can then be removed, and the
builder becomes even shorter:

<programlisting>
source $stdenv/setup
genericBuild</programlisting>

In fact, <varname>mkDerivation</varname> provides a default builder
that looks exactly like that, so it is actually possible to omit the
builder for Hello entirely.</para>

</section>
