<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-advanced-attributes">

<title>Advanced Attributes</title>

<para>Derivations can declare some infrequently used optional
attributes.</para>

<variablelist>

  <varlistentry xml:id="adv-attr-allowedReferences"><term><varname>allowedReferences</varname></term>

    <listitem><para>The optional attribute
    <varname>allowedReferences</varname> specifies a list of legal
    references (dependencies) of the output of the builder.  For
    example,

<programlisting>
allowedReferences = [];
</programlisting>

    enforces that the output of a derivation cannot have any runtime
    dependencies on its inputs.  To allow an output to have a runtime
    dependency on itself, use <literal>"out"</literal> as a list item.
    This is used in NixOS to check that generated files such as
    initial ramdisks for booting Linux don’t have accidental
    dependencies on other paths in the Nix store.</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-allowedRequisites"><term><varname>allowedRequisites</varname></term>

    <listitem><para>This attribute is similar to
    <varname>allowedReferences</varname>, but it specifies the legal
    requisites of the whole closure, so all the dependencies
    recursively.  For example,

<programlisting>
allowedRequisites = [ foobar ];
</programlisting>

    enforces that the output of a derivation cannot have any other
    runtime dependency than <varname>foobar</varname>, and in addition
    it enforces that <varname>foobar</varname> itself doesn't
    introduce any other dependency itself.</para></listitem>

  </varlistentry>

  <varlistentry xml:id="adv-attr-disallowedReferences"><term><varname>disallowedReferences</varname></term>

    <listitem><para>The optional attribute
    <varname>disallowedReferences</varname> specifies a list of illegal
    references (dependencies) of the output of the builder.  For
    example,

<programlisting>
disallowedReferences = [ foo ];
</programlisting>

    enforces that the output of a derivation cannot have a direct runtime
    dependencies on the derivation <varname>foo</varname>.</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-disallowedRequisites"><term><varname>disallowedRequisites</varname></term>

    <listitem><para>This attribute is similar to
    <varname>disallowedReferences</varname>, but it specifies illegal
    requisites for the whole closure, so all the dependencies
    recursively.  For example,

<programlisting>
disallowedRequisites = [ foobar ];
</programlisting>

    enforces that the output of a derivation cannot have any
    runtime dependency on <varname>foobar</varname> or any other derivation
    depending recursively on <varname>foobar</varname>.</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-exportReferencesGraph"><term><varname>exportReferencesGraph</varname></term>

    <listitem><para>This attribute allows builders access to the
    references graph of their inputs.  The attribute is a list of
    inputs in the Nix store whose references graph the builder needs
    to know.  The value of this attribute should be a list of pairs
    <literal>[ <replaceable>name1</replaceable>
    <replaceable>path1</replaceable> <replaceable>name2</replaceable>
    <replaceable>path2</replaceable> <replaceable>...</replaceable>
    ]</literal>.  The references graph of each
    <replaceable>pathN</replaceable> will be stored in a text file
    <replaceable>nameN</replaceable> in the temporary build directory.
    The text files have the format used by <command>nix-store
    --register-validity</command> (with the deriver fields left
    empty).  For example, when the following derivation is built:

<programlisting>
derivation {
  ...
  exportReferencesGraph = [ "libfoo-graph" libfoo ];
};
</programlisting>

    the references graph of <literal>libfoo</literal> is placed in the
    file <filename>libfoo-graph</filename> in the temporary build
    directory.</para>

    <para><varname>exportReferencesGraph</varname> is useful for
    builders that want to do something with the closure of a store
    path.  Examples include the builders in NixOS that generate the
    initial ramdisk for booting Linux (a <command>cpio</command>
    archive containing the closure of the boot script) and the
    ISO-9660 image for the installation CD (which is populated with a
    Nix store containing the closure of a bootable NixOS
    configuration).</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-impureEnvVars"><term><varname>impureEnvVars</varname></term>

    <listitem><para>This attribute allows you to specify a list of
    environment variables that should be passed from the environment
    of the calling user to the builder.  Usually, the environment is
    cleared completely when the builder is executed, but with this
    attribute you can allow specific environment variables to be
    passed unmodified.  For example, <function>fetchurl</function> in
    Nixpkgs has the line

<programlisting>
impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
</programlisting>

    to make it use the proxy server configuration specified by the
    user in the environment variables <envar>http_proxy</envar> and
    friends.</para>

    <para>This attribute is only allowed in <link
    linkend="fixed-output-drvs">fixed-output derivations</link>, where
    impurities such as these are okay since (the hash of) the output
    is known in advance.  It is ignored for all other
    derivations.</para>

    <warning><para><varname>impureEnvVars</varname> implementation takes
    environment variables from the current builder process. When a daemon is
    building its environmental variables are used. Without the daemon, the
    environmental variables come from the environment of the
    <command>nix-build</command>.</para></warning></listitem>

  </varlistentry>


  <varlistentry xml:id="fixed-output-drvs">
    <term xml:id="adv-attr-outputHash"><varname>outputHash</varname></term>
    <term xml:id="adv-attr-outputHashAlgo"><varname>outputHashAlgo</varname></term>
    <term xml:id="adv-attr-outputHashMode"><varname>outputHashMode</varname></term>

    <listitem><para>These attributes declare that the derivation is a
    so-called <emphasis>fixed-output derivation</emphasis>, which
    means that a cryptographic hash of the output is already known in
    advance.  When the build of a fixed-output derivation finishes,
    Nix computes the cryptographic hash of the output and compares it
    to the hash declared with these attributes.  If there is a
    mismatch, the build fails.</para>

    <para>The rationale for fixed-output derivations is derivations
    such as those produced by the <function>fetchurl</function>
    function.  This function downloads a file from a given URL.  To
    ensure that the downloaded file has not been modified, the caller
    must also specify a cryptographic hash of the file.  For example,

<programlisting>
fetchurl {
  url = "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz";
  sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
}
</programlisting>

    It sometimes happens that the URL of the file changes, e.g.,
    because servers are reorganised or no longer available.  We then
    must update the call to <function>fetchurl</function>, e.g.,

<programlisting>
fetchurl {
  url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
  sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
}
</programlisting>

    If a <function>fetchurl</function> derivation was treated like a
    normal derivation, the output paths of the derivation and
    <emphasis>all derivations depending on it</emphasis> would change.
    For instance, if we were to change the URL of the Glibc source
    distribution in Nixpkgs (a package on which almost all other
    packages depend) massive rebuilds would be needed.  This is
    unfortunate for a change which we know cannot have a real effect
    as it propagates upwards through the dependency graph.</para>

    <para>For fixed-output derivations, on the other hand, the name of
    the output path only depends on the <varname>outputHash*</varname>
    and <varname>name</varname> attributes, while all other attributes
    are ignored for the purpose of computing the output path.  (The
    <varname>name</varname> attribute is included because it is part
    of the path.)</para>

    <para>As an example, here is the (simplified) Nix expression for
    <varname>fetchurl</varname>:

<programlisting>
{ stdenv, curl }: # The <command>curl</command> program is used for downloading.

{ url, sha256 }:

stdenv.mkDerivation {
  name = baseNameOf (toString url);
  builder = ./builder.sh;
  buildInputs = [ curl ];

  # This is a fixed-output derivation; the output must be a regular
  # file with SHA256 hash <varname>sha256</varname>.
  outputHashMode = "flat";
  outputHashAlgo = "sha256";
  outputHash = sha256;

  inherit url;
}
</programlisting>

    </para>

    <para>The <varname>outputHashAlgo</varname> attribute specifies
    the hash algorithm used to compute the hash.  It can currently be
    <literal>"sha1"</literal>, <literal>"sha256"</literal> or
    <literal>"sha512"</literal>.</para>

    <para>The <varname>outputHashMode</varname> attribute determines
    how the hash is computed.  It must be one of the following two
    values:

    <variablelist>

      <varlistentry><term><literal>"flat"</literal></term>

        <listitem><para>The output must be a non-executable regular
        file.  If it isn’t, the build fails.  The hash is simply
        computed over the contents of that file (so it’s equal to what
        Unix commands like <command>sha256sum</command> or
        <command>sha1sum</command> produce).</para>

        <para>This is the default.</para></listitem>

      </varlistentry>

      <varlistentry><term><literal>"recursive"</literal></term>

        <listitem><para>The hash is computed over the NAR archive dump
        of the output (i.e., the result of <link
        linkend="refsec-nix-store-dump"><command>nix-store
        --dump</command></link>).  In this case, the output can be
        anything, including a directory tree.</para></listitem>

      </varlistentry>

    </variablelist>

    </para>

    <para>The <varname>outputHash</varname> attribute, finally, must
    be a string containing the hash in either hexadecimal or base-32
    notation.  (See the <link
    linkend="sec-nix-hash"><command>nix-hash</command> command</link>
    for information about converting to and from base-32
    notation.)</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-passAsFile"><term><varname>passAsFile</varname></term>

    <listitem><para>A list of names of attributes that should be
    passed via files rather than environment variables.  For example,
    if you have

    <programlisting>
passAsFile = ["big"];
big = "a very long string";
    </programlisting>

    then when the builder runs, the environment variable
    <envar>bigPath</envar> will contain the absolute path to a
    temporary file containing <literal>a very long
    string</literal>. That is, for any attribute
    <replaceable>x</replaceable> listed in
    <varname>passAsFile</varname>, Nix will pass an environment
    variable <envar><replaceable>x</replaceable>Path</envar> holding
    the path of the file containing the value of attribute
    <replaceable>x</replaceable>. This is useful when you need to pass
    large strings to a builder, since most operating systems impose a
    limit on the size of the environment (typically, a few hundred
    kilobyte).</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-preferLocalBuild"><term><varname>preferLocalBuild</varname></term>

    <listitem><para>If this attribute is set to
    <literal>true</literal> and <link
    linkend="chap-distributed-builds">distributed building is
    enabled</link>, then, if possible, the derivaton will be built
    locally instead of forwarded to a remote machine.  This is
    appropriate for trivial builders where the cost of doing a
    download or remote build would exceed the cost of building
    locally.</para></listitem>

  </varlistentry>


  <varlistentry xml:id="adv-attr-allowSubstitutes"><term><varname>allowSubstitutes</varname></term>

    <listitem>
    <para>If this attribute is set to
    <literal>false</literal>, then Nix will always build this
    derivation; it will not try to substitute its outputs. This is
    useful for very trivial derivations (such as
    <function>writeText</function> in Nixpkgs) that are cheaper to
    build than to substitute from a binary cache.</para>

    <note><para>You need to have a builder configured which satisfies
    the derivation’s <literal>system</literal> attribute, since the
    derivation cannot be substituted. Thus it is usually a good idea
    to align <literal>system</literal> with
    <literal>builtins.currentSystem</literal> when setting
    <literal>allowSubstitutes</literal> to <literal>false</literal>.
    For most trivial derivations this should be the case.
    </para></note>
    </listitem>

  </varlistentry>


</variablelist>

</section>