<commit_before><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter [
  <!ENTITY ndash "&#x2013;"> <!-- @vcunat likes to use this one ;-) -->
]>
<chapter xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xml:id="chap-multiple-output">
 <title>Multiple-output packages</title>
 <section>
  <title>Introduction</title>

  <para>
   The Nix language allows a derivation to produce multiple outputs, which is
   similar to what is utilized by other Linux distribution packaging systems.
   The outputs reside in separate nix store paths, so they can be mostly
   handled independently of each other, including passing to build inputs,
   garbage collection or binary substitution. The exception is that building
   from source always produces all the outputs.
  </para>

  <para>
   The main motivation is to save disk space by reducing runtime closure sizes;
   consequently also sizes of substituted binaries get reduced. Splitting can
   be used to have more granular runtime dependencies, for example the typical
   reduction is to split away development-only files, as those are typically
   not needed during runtime. As a result, closure sizes of many packages can
   get reduced to a half or even much less.
  </para>

  <note>
   <para>
    The reduction effects could be instead achieved by building the parts in
    completely separate derivations. That would often additionally reduce
    build-time closures, but it tends to be much harder to write such
    derivations, as build systems typically assume all parts are being built at
    once. This compromise approach of single source package producing multiple
    binary packages is also utilized often by rpm and deb.
   </para>
  </note>
 </section>
 <section>
  <title>Installing a split package</title>

  <para>
   When installing a package via <varname>systemPackages</varname> or
   <command>nix-env</command> you have several options:
  </para>

  <itemizedlist>
   <listitem>
    <para>
     You can install particular outputs explicitly, as each is available in the
     Nix language as an attribute of the package. The
     <varname>outputs</varname> attribute contains a list of output names.
    </para>
   </listitem>
   <listitem>
    <para>
     You can let it use the default outputs. These are handled by
     <varname>meta.outputsToInstall</varname> attribute that contains a list of
     output names.
    </para>
    <para>
     TODO: more about tweaking the attribute, etc.
    </para>
   </listitem>
   <listitem>
    <para>
     NixOS provides configuration option
     <varname>environment.extraOutputsToInstall</varname> that allows adding
     extra outputs of <varname>environment.systemPackages</varname> atop the
     default ones. It's mainly meant for documentation and debug symbols, and
     it's also modified by specific options.
    </para>
    <note>
     <para>
      At this moment there is no similar configurability for packages installed
      by <command>nix-env</command>. You can still use approach from
      <xref linkend="sec-modify-via-packageOverrides" /> to override
      <varname>meta.outputsToInstall</varname> attributes, but that's a rather
      inconvenient way.
     </para>
    </note>
   </listitem>
  </itemizedlist>
 </section>
 <section>
  <title>Using a split package</title>

  <para>
   In the Nix language the individual outputs can be reached explicitly as
   attributes, e.g. <varname>coreutils.info</varname>, but the typical case is
   just using packages as build inputs.
  </para>

  <para>
   When a multiple-output derivation gets into a build input of another
   derivation, the <varname>dev</varname> output is added if it exists,
   otherwise the first output is added. In addition to that,
   <varname>propagatedBuildOutputs</varname> of that package which by default
   contain <varname>$outputBin</varname> and <varname>$outputLib</varname> are
   also added. (See <xref linkend="multiple-output-file-type-groups" />.)
  </para>
 </section>
 <section>
  <title>Writing a split derivation</title>

  <para>
   Here you find how to write a derivation that produces multiple outputs.
  </para><commit_msg>manual: mention symlinkJoin in multiple-outputs section<commit_after><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter [
  <!ENTITY ndash "&#x2013;"> <!-- @vcunat likes to use this one ;-) -->
]>
<chapter xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xml:id="chap-multiple-output">
 <title>Multiple-output packages</title>
 <section>
  <title>Introduction</title>

  <para>
   The Nix language allows a derivation to produce multiple outputs, which is
   similar to what is utilized by other Linux distribution packaging systems.
   The outputs reside in separate nix store paths, so they can be mostly
   handled independently of each other, including passing to build inputs,
   garbage collection or binary substitution. The exception is that building
   from source always produces all the outputs.
  </para>

  <para>
   The main motivation is to save disk space by reducing runtime closure sizes;
   consequently also sizes of substituted binaries get reduced. Splitting can
   be used to have more granular runtime dependencies, for example the typical
   reduction is to split away development-only files, as those are typically
   not needed during runtime. As a result, closure sizes of many packages can
   get reduced to a half or even much less.
  </para>

  <note>
   <para>
    The reduction effects could be instead achieved by building the parts in
    completely separate derivations. That would often additionally reduce
    build-time closures, but it tends to be much harder to write such
    derivations, as build systems typically assume all parts are being built at
    once. This compromise approach of single source package producing multiple
    binary packages is also utilized often by rpm and deb.
   </para>
  </note>
 </section>
 <section>
  <title>Installing a split package</title>

  <para>
   When installing a package via <varname>systemPackages</varname> or
   <command>nix-env</command> you have several options:
  </para>

  <itemizedlist>
   <listitem>
    <para>
     You can install particular outputs explicitly, as each is available in the
     Nix language as an attribute of the package. The
     <varname>outputs</varname> attribute contains a list of output names.
    </para>
   </listitem>
   <listitem>
    <para>
     You can let it use the default outputs. These are handled by
     <varname>meta.outputsToInstall</varname> attribute that contains a list of
     output names.
    </para>
    <para>
     TODO: more about tweaking the attribute, etc.
    </para>
   </listitem>
   <listitem>
    <para>
     NixOS provides configuration option
     <varname>environment.extraOutputsToInstall</varname> that allows adding
     extra outputs of <varname>environment.systemPackages</varname> atop the
     default ones. It's mainly meant for documentation and debug symbols, and
     it's also modified by specific options.
    </para>
    <note>
     <para>
      At this moment there is no similar configurability for packages installed
      by <command>nix-env</command>. You can still use approach from
      <xref linkend="sec-modify-via-packageOverrides" /> to override
      <varname>meta.outputsToInstall</varname> attributes, but that's a rather
      inconvenient way.
     </para>
    </note>
   </listitem>
  </itemizedlist>
 </section>
 <section>
  <title>Using a split package</title>

  <para>
   In the Nix language the individual outputs can be reached explicitly as
   attributes, e.g. <varname>coreutils.info</varname>, but the typical case is
   just using packages as build inputs.
  </para>

  <para>
   When a multiple-output derivation gets into a build input of another
   derivation, the <varname>dev</varname> output is added if it exists,
   otherwise the first output is added. In addition to that,
   <varname>propagatedBuildOutputs</varname> of that package which by default
   contain <varname>$outputBin</varname> and <varname>$outputLib</varname> are
   also added. (See <xref linkend="multiple-output-file-type-groups" />.)
  </para>

  <para>
   In some cases it may be desirable to combine different outputs under a
   single store path. A function <literal>symlinkJoin</literal> can be used to
   do this. (Note that it may negate some closure size benefits of using a
   multiple-output package.)
  </para>
 </section>
 <section>
  <title>Writing a split derivation</title>

  <para>
   Here you find how to write a derivation that produces multiple outputs.
  </para>
{'fraction_non_alphanumeric': 0.0816607409106549, 'fraction_numerical': 0.0027526092441793786, 'mean_word_length': 3.5018069179143003, 'pattern_counts': {'":': 0, '<': 179, '<?xml version=': 2, '>': 179, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4589963', 'n_tokens_mistral': 2415, 'n_tokens_neox': 2334, 'n_words': 1019}