···1# Multiple-output packages {#chap-multiple-output}
23-## Introduction {#sec-multiple-outputs-introduction}
4-5The 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.
67The 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.
···10The 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.
11:::
1213-A number of attributes can be used to work with a derivation with multiple outputs. The attribute `outputs` is a list of strings, which are the names of the outputs. For each of these names, an identically named attribute is created, corresponding to that output. The attribute `meta.outputsToInstall` is used to determine the default set of outputs to install when using the derivation name unqualified.
14-15-## Installing a split package {#sec-multiple-outputs-installing}
16-17-When installing a package with multiple outputs, the package’s `meta.outputsToInstall` attribute determines which outputs are actually installed. `meta.outputsToInstall` is a list whose [default installs binaries and the associated man pages](https://github.com/NixOS/nixpkgs/blob/f1680774340d5443a1409c3421ced84ac1163ba9/pkgs/stdenv/generic/make-derivation.nix#L310-L320). The following sections describe ways to install different outputs.
18-19-### Selecting outputs to install via NixOS {#sec-multiple-outputs-installing-nixos}
20-21-NixOS provides two ways to select the outputs to install for packages listed in `environment.systemPackages`:
22-23-- The configuration option `environment.extraOutputsToInstall` is appended to each package’s `meta.outputsToInstall` attribute to determine the outputs to install. It can for example be used to install `info` documentation or debug symbols for all packages.
24-25-- The outputs can be listed as packages in `environment.systemPackages`. For example, the `"out"` and `"info"` outputs for the `coreutils` package can be installed by including `coreutils` and `coreutils.info` in `environment.systemPackages`.
26-27-### Selecting outputs to install via `nix-env` {#sec-multiple-outputs-installing-nix-env}
28-29-`nix-env` lacks an easy way to select the outputs to install. When installing a package, `nix-env` always installs the outputs listed in `meta.outputsToInstall`, even when the user explicitly selects an output.
30-31-::: {.warning}
32-`nix-env` silently disregards the outputs selected by the user, and instead installs the outputs from `meta.outputsToInstall`. For example,
33-34-```ShellSession
35-$ nix-env -iA nixpkgs.coreutils.info
36-```
37-38-installs the `"out"` output (`coreutils.meta.outputsToInstall` is `[ "out" ]`) instead of the requested `"info"`.
39-:::
40-41-The only recourse to select an output with `nix-env` is to override the package’s `meta.outputsToInstall`, using the functions described in [](#chap-overrides). For example, the following overlay adds the `"info"` output for the `coreutils` package:
4243-```nix
44-self: super:
45-{
46- coreutils = super.coreutils.overrideAttrs (oldAttrs: {
47- meta = oldAttrs.meta // { outputsToInstall = oldAttrs.meta.outputsToInstall or [ "out" ] ++ [ "info" ]; };
48- });
49-}
50-```
5152## Using a split package {#sec-multiple-outputs-using-split-packages}
53
···1# Multiple-output packages {#chap-multiple-output}
2003The 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.
45The 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.
···8The 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.
9:::
1011+A number of attributes can be used to work with a derivation with multiple outputs.
12+The attribute `outputs` is a list of strings, which are the names of the outputs.
13+For each of these names, an identically named attribute is created, corresponding to that output.
000000000000000000000000001415+The attribute `meta.outputsToInstall` is used to determine the [default set of outputs to install](https://github.com/NixOS/nixpkgs/blob/08c3198f1c6fd89a09f8f0ea09b425028a34de3e/pkgs/stdenv/generic/check-meta.nix#L411-L426) when using the derivation name unqualified:
16+`bin`, or `out`, or the first specified output; as well as `man` if that is specified.
0000001718## Using a split package {#sec-multiple-outputs-using-split-packages}
19
···132133- `himalaya` has been updated to `0.8.0`, which drops the native TLS support (in favor of Rustls) and add OAuth 2.0 support. See the [release note](https://github.com/soywod/himalaya/releases/tag/v0.8.0) for more details.
13400135- The [services.caddy.acmeCA](#opt-services.caddy.acmeCA) option now defaults to `null` instead of `"https://acme-v02.api.letsencrypt.org/directory"`, to use all of Caddy's default ACME CAs and enable Caddy's automatic issuer fallback feature by default, as recommended by upstream.
136137- The default priorities of [`services.nextcloud.phpOptions`](#opt-services.nextcloud.phpOptions) have changed. This means that e.g.
···276- `services.matrix-synapse` has new options to configure worker processes for matrix-synapse using [`services.matrix-synapse.workers`](#opt-services.matrix-synapse.workers). It's also now possible to configure a local redis server using [`services.matrix-synapse.configureRedisLocally`](#opt-services.matrix-synapse.configureRedisLocally).
277278- `services.nginx` gained a `defaultListen` option at server-level with support for PROXY protocol listeners, also `proxyProtocol` is now exposed in `services.nginx.virtualHosts.<name>.listen` option. It is now possible to run PROXY listeners and non-PROXY listeners at a server-level, see [#213510](https://github.com/NixOS/nixpkgs/pull/213510/) for more details.
279-280-- `generic-extlinux-compatible` bootloader (and raspberry pi with uboot) supports appending secrets to the initramfs
281282- `services.restic.backups` now adds wrapper scripts to your system path, which set the same environment variables as the service, so restic operations can easly be run from the command line. This behavior can be disabled by setting `createWrapper` to `false`, per backup configuration.
283
···132133- `himalaya` has been updated to `0.8.0`, which drops the native TLS support (in favor of Rustls) and add OAuth 2.0 support. See the [release note](https://github.com/soywod/himalaya/releases/tag/v0.8.0) for more details.
134135+- `nix-prefetch-git` now ignores global and user git config, to improve reproducibility.
136+137- The [services.caddy.acmeCA](#opt-services.caddy.acmeCA) option now defaults to `null` instead of `"https://acme-v02.api.letsencrypt.org/directory"`, to use all of Caddy's default ACME CAs and enable Caddy's automatic issuer fallback feature by default, as recommended by upstream.
138139- The default priorities of [`services.nextcloud.phpOptions`](#opt-services.nextcloud.phpOptions) have changed. This means that e.g.
···278- `services.matrix-synapse` has new options to configure worker processes for matrix-synapse using [`services.matrix-synapse.workers`](#opt-services.matrix-synapse.workers). It's also now possible to configure a local redis server using [`services.matrix-synapse.configureRedisLocally`](#opt-services.matrix-synapse.configureRedisLocally).
279280- `services.nginx` gained a `defaultListen` option at server-level with support for PROXY protocol listeners, also `proxyProtocol` is now exposed in `services.nginx.virtualHosts.<name>.listen` option. It is now possible to run PROXY listeners and non-PROXY listeners at a server-level, see [#213510](https://github.com/NixOS/nixpkgs/pull/213510/) for more details.
00281282- `services.restic.backups` now adds wrapper scripts to your system path, which set the same environment variables as the service, so restic operations can easly be run from the command line. This behavior can be disabled by setting `createWrapper` to `false`, per backup configuration.
283
+8-2
nixos/modules/config/system-path.nix
···116 extraOutputsToInstall = mkOption {
117 type = types.listOf types.str;
118 default = [ ];
119- example = [ "doc" "info" "devdoc" ];
120- description = lib.mdDoc "List of additional package outputs to be symlinked into {file}`/run/current-system/sw`.";
000000121 };
122123 extraSetup = mkOption {
···116 extraOutputsToInstall = mkOption {
117 type = types.listOf types.str;
118 default = [ ];
119+ example = [ "dev" "info" ];
120+ description = lib.mdDoc ''
121+ Entries listed here will be appended to the `meta.outputsToInstall` attribute for each package in `environment.systemPackages`, and the files from the corresponding derivation outputs symlinked into {file}`/run/current-system/sw`.
122+123+ For example, this can be used to install the `dev` and `info` outputs for all packages in the system environment, if they are available.
124+125+ To use specific outputs instead of configuring them globally, select the corresponding attribute on the package derivation, e.g. `libxml2.dev` or `coreutils.info`.
126+ '';
127 };
128129 extraSetup = mkOption {
···70addEntry() {
71 local path=$(readlink -f "$1")
72 local tag="$2" # Generation number or 'default'
73- local current="$3" # whether this is the current/latest generation
7475 if ! test -e $path/kernel -a -e $path/initrd; then
76 return
77 fi
7879- if test -e "$path/append-initrd-secrets"; then
80- local initrd="$target/nixos/$(basename "$path")-initramfs-with-secrets"
81- cp $(readlink -f "$path/initrd") "$initrd"
82- chmod 600 "${initrd}"
83- chown 0:0 "${initrd}"
84- filesCopied[$initrd]=1
85-86- "$path/append-initrd-secrets" "$initrd" || if test "${current}" = "1"; then
87- echo "failed to create initrd secrets for the current generation." >&2
88- echo "are your \`boot.initrd.secrets\` still in place?" >&2
89- exit 1
90- else
91- echo "warning: failed to create initrd secrets for \"$path\", an older generation" >&2
92- echo "note: this is normal after having removed or renamed a file in \`boot.initrd.secrets\`" >&2
93- fi
94- else
95- copyToKernelsDir "$path/initrd"; initrd=$result
96- fi
97-98 copyToKernelsDir "$path/kernel"; kernel=$result
99-100 dtbDir=$(readlink -m "$path/dtbs")
101 if [ -e "$dtbDir" ]; then
102 copyToKernelsDir "$dtbDir"; dtbs=$result
···150TIMEOUT $timeout
151EOF
152153-addEntry $default default 1 >> $tmpFile
154155if [ "$numGenerations" -gt 0 ]; then
156 # Add up to $numGenerations generations of the system profile to the menu,
157 # in reverse (most recent to least recent) order.
158- current=1
159 for generation in $(
160 (cd /nix/var/nix/profiles && ls -d system-*-link) \
161 | sed 's/system-\([0-9]\+\)-link/\1/' \
162 | sort -n -r \
163 | head -n $numGenerations); do
164 link=/nix/var/nix/profiles/system-$generation-link
165- addEntry $link $generation $current
166- current=0
167 done >> $tmpFile
168fi
169
···70addEntry() {
71 local path=$(readlink -f "$1")
72 local tag="$2" # Generation number or 'default'
07374 if ! test -e $path/kernel -a -e $path/initrd; then
75 return
76 fi
77000000000000000000078 copyToKernelsDir "$path/kernel"; kernel=$result
79+ copyToKernelsDir "$path/initrd"; initrd=$result
80 dtbDir=$(readlink -m "$path/dtbs")
81 if [ -e "$dtbDir" ]; then
82 copyToKernelsDir "$dtbDir"; dtbs=$result
···130TIMEOUT $timeout
131EOF
132133+addEntry $default default >> $tmpFile
134135if [ "$numGenerations" -gt 0 ]; then
136 # Add up to $numGenerations generations of the system profile to the menu,
137 # in reverse (most recent to least recent) order.
0138 for generation in $(
139 (cd /nix/var/nix/profiles && ls -d system-*-link) \
140 | sed 's/system-\([0-9]\+\)-link/\1/' \
141 | sort -n -r \
142 | head -n $numGenerations); do
143 link=/nix/var/nix/profiles/system-$generation-link
144+ addEntry $link $generation
0145 done >> $tmpFile
146fi
147
···610 path the secret should have inside the initrd, the value
611 is the path it should be copied from (or null for the same
612 path inside and out).
613-614- The loader `generic-extlinux-compatible` supports this. Because
615- it is not well know how different implementations react to
616- concatenated cpio archives, this is disabled by default. It can be
617- enabled by setting {option}`boot.loader.supportsInitrdSecrets`
618- to true. If this works for you, please report your findings at
619- https://github.com/NixOS/nixpkgs/issues/247145 .
620 '';
621 example = literalExpression
622 ''
···610 path the secret should have inside the initrd, the value
611 is the path it should be copied from (or null for the same
612 path inside and out).
0000000613 '';
614 example = literalExpression
615 ''
+1
pkgs/applications/editors/mg/default.nix
···31 description = "Micro GNU/emacs, a portable version of the mg maintained by the OpenBSD team";
32 homepage = "https://man.openbsd.org/OpenBSD-current/man1/mg.1";
33 license = licenses.publicDomain;
034 platforms = platforms.all;
35 };
36}
···31 description = "Micro GNU/emacs, a portable version of the mg maintained by the OpenBSD team";
32 homepage = "https://man.openbsd.org/OpenBSD-current/man1/mg.1";
33 license = licenses.publicDomain;
34+ mainProgram = "mg";
35 platforms = platforms.all;
36 };
37}
···6latest_linux_version=$(curl -L --silent https://slack.com/downloads/linux | sed -n 's/.*Version \([0-9\.]\+\).*/\1/p')
7latest_mac_version=$(curl -L --silent https://slack.com/downloads/mac | sed -n 's/.*Version \([0-9\.]\+\).*/\1/p')
89-# Double check that the latest mac and linux versions are in sync.
10-if [[ "$latest_linux_version" != "$latest_mac_version" ]]; then
11- echo "the latest linux ($latest_linux_version) and mac ($latest_mac_version) versions are not the same"
12- exit 1
13-fi
14-15nixpkgs="$(git rev-parse --show-toplevel)"
16slack_nix="$nixpkgs/pkgs/applications/networking/instant-messengers/slack/default.nix"
17nixpkgs_linux_version=$(cat "$slack_nix" | sed -n 's/.*x86_64-linux-version = \"\([0-9\.]\+\)\";.*/\1/p')
···6latest_linux_version=$(curl -L --silent https://slack.com/downloads/linux | sed -n 's/.*Version \([0-9\.]\+\).*/\1/p')
7latest_mac_version=$(curl -L --silent https://slack.com/downloads/mac | sed -n 's/.*Version \([0-9\.]\+\).*/\1/p')
80000009nixpkgs="$(git rev-parse --show-toplevel)"
10slack_nix="$nixpkgs/pkgs/applications/networking/instant-messengers/slack/default.nix"
11nixpkgs_linux_version=$(cat "$slack_nix" | sed -n 's/.*x86_64-linux-version = \"\([0-9\.]\+\)\";.*/\1/p')
···293 local rev="${3:-HEAD}"
294295 if [ -n "$fetchLFS" ]; then
296- tmpHomePath="$(mktemp -d "${TMPDIR:-/tmp}/nix-prefetch-git-tmp-home-XXXXXXXXXX")"
297- exit_handlers+=(remove_tmpHomePath)
298- HOME="$tmpHomePath"
299 clean_git lfs install
300 fi
301···416if test -z "$branchName"; then
417 branchName=fetchgit
418fi
000000419420if test -n "$builder"; then
421 test -n "$out" -a -n "$url" -a -n "$rev" || usage
···293 local rev="${3:-HEAD}"
294295 if [ -n "$fetchLFS" ]; then
000296 clean_git lfs install
297 fi
298···413if test -z "$branchName"; then
414 branchName=fetchgit
415fi
416+417+tmpHomePath="$(mktemp -d "${TMPDIR:-/tmp}/nix-prefetch-git-tmp-home-XXXXXXXXXX")"
418+exit_handlers+=(remove_tmpHomePath)
419+HOME="$tmpHomePath"
420+unset XDG_CONFIG_HOME
421+export GIT_CONFIG_NOSYSTEM=1
422423if test -n "$builder"; then
424 test -n "$out" -a -n "$url" -a -n "$rev" || usage
···5}:
6crystal.buildCrystalPackage rec {
7 pname = "gi-crystal";
8- version = "0.17.0";
910 src = fetchFromGitHub {
11 owner = "hugopl";
12 repo = "gi-crystal";
13 rev = "v${version}";
14- hash = "sha256-DIH8L8P8lkWzzVUj1Tbf9oTUvu9X7OT66APyUHiDkYk=";
15 };
1617 # Make sure gi-crystal picks up the name of the so or dylib and not the leading nix store path
···5}:
6crystal.buildCrystalPackage rec {
7 pname = "gi-crystal";
8+ version = "0.18.0";
910 src = fetchFromGitHub {
11 owner = "hugopl";
12 repo = "gi-crystal";
13 rev = "v${version}";
14+ hash = "sha256-9px6JRdVzsUoU5wlO+blH1OBGKskozF3WvqLV/EYiiA=";
15 };
1617 # Make sure gi-crystal picks up the name of the so or dylib and not the leading nix store path