From 370097ce864f731c6e281ab3970cef1b39dfa06f Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Mon, 25 Sep 2023 16:23:01 +0200 Subject: [PATCH] remove the misleading warning on using `nix-env` for split outputs (#255947) The text was originally added [0] following an apparently incomplete research on how everything plays together. In fact, Nix propagates `outputs` to the corresponding nested derivations, and there is some messy behavior in Nixpkgs that only seems to propagate `meta.outputsToInstall` in `buildEnv`[1]. This change moves the hints on how to use NixOS specifics to NixOS module documentation (which is hopefully easier to find through search.nixos.org), describes the default behavior in Nixpkgs (updating a the link to the source), and removes the confusing mention of `nix-env`. the last of them should not be there to begin with. we don't want beginners to use `nix-env`, as this is known to run them into trouble eventually. [0]: https://github.com/NixOS/nixpkgs/pull/76794 [1]: https://github.com/NixOS/nixpkgs/blob/1774d07242995050d2d8a91cb4da0855eac2e472/pkgs/build-support/buildenv/default.nix#L66 --- doc/stdenv/multiple-output.chapter.md | 44 +++------------------------ nixos/modules/config/system-path.nix | 10 ++++-- 2 files changed, 13 insertions(+), 41 deletions(-) diff --git a/doc/stdenv/multiple-output.chapter.md b/doc/stdenv/multiple-output.chapter.md index c19d497ab61e..1ee063c0c2f4 100644 --- a/doc/stdenv/multiple-output.chapter.md +++ b/doc/stdenv/multiple-output.chapter.md @@ -1,7 +1,5 @@ # Multiple-output packages {#chap-multiple-output} -## Introduction {#sec-multiple-outputs-introduction} - 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. 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. @@ -10,44 +8,12 @@ The main motivation is to save disk space by reducing runtime closure sizes; con 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. ::: -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. +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. -## Installing a split package {#sec-multiple-outputs-installing} - -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. - -### Selecting outputs to install via NixOS {#sec-multiple-outputs-installing-nixos} - -NixOS provides two ways to select the outputs to install for packages listed in `environment.systemPackages`: - -- 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. - -- 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`. - -### Selecting outputs to install via `nix-env` {#sec-multiple-outputs-installing-nix-env} - -`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. - -::: {.warning} -`nix-env` silently disregards the outputs selected by the user, and instead installs the outputs from `meta.outputsToInstall`. For example, - -```ShellSession -$ nix-env -iA nixpkgs.coreutils.info -``` - -installs the `"out"` output (`coreutils.meta.outputsToInstall` is `[ "out" ]`) instead of the requested `"info"`. -::: - -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: - -```nix -self: super: -{ - coreutils = super.coreutils.overrideAttrs (oldAttrs: { - meta = oldAttrs.meta // { outputsToInstall = oldAttrs.meta.outputsToInstall or [ "out" ] ++ [ "info" ]; }; - }); -} -``` +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: +`bin`, or `out`, or the first specified output; as well as `man` if that is specified. ## Using a split package {#sec-multiple-outputs-using-split-packages} diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix index e8bbeac4f720..222da3e02e86 100644 --- a/nixos/modules/config/system-path.nix +++ b/nixos/modules/config/system-path.nix @@ -116,8 +116,14 @@ in extraOutputsToInstall = mkOption { type = types.listOf types.str; default = [ ]; - example = [ "doc" "info" "devdoc" ]; - description = lib.mdDoc "List of additional package outputs to be symlinked into {file}`/run/current-system/sw`."; + example = [ "dev" "info" ]; + description = lib.mdDoc '' + 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`. + + For example, this can be used to install the `dev` and `info` outputs for all packages in the system environment, if they are available. + + To use specific outputs instead of configuring them globally, select the corresponding attribute on the package derivation, e.g. `libxml2.dev` or `coreutils.info`. + ''; }; extraSetup = mkOption {