From 8e94561d62272983c93f6c635919874f8d19d8f9 Mon Sep 17 00:00:00 2001 From: Adam Dinwoodie Date: Thu, 30 Oct 2025 23:00:45 +0000 Subject: [PATCH] nixpkgs: pass `lib` to config function Nixpkgs config, for defining things like which licenses are permitted, can either be an attrset or a function that is passed a `pkgs` argument. Evaluating that `pkgs` argument requires computing the Nixpkgs fixpoint, which requires checking whether the derivations used in the Nixpkgs bootstrap have valid licenses. This works provided nothing tries to use Nixpkgs functions to validate or merge anything included in the configuration. f5deefd4631e (config: add and document {allow,block}listedLicenses, 2025-08-31), in #437723, added type checking and merging to the lists of permitted/forbidden licenses. That resulted in a recursion loop if a list of licenses included, say, `pkgs.lib.licenses.bsd0`. To allow licenses to be specified from Nixpkgs' library, pass `lib` as well as `pkgs` to any config function. Computing `lib` doesn't require working out the full Nixpkgs fixpoint. The change in #437723 will still break things for some people, but it at least provides a sensible route to getting the config working again. Fixes #456994. --- doc/release-notes/rl-2605.section.md | 26 ++++++++++++++++++++++++++ nixos/modules/misc/nixpkgs.nix | 4 ++-- pkgs/top-level/default.nix | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/doc/release-notes/rl-2605.section.md b/doc/release-notes/rl-2605.section.md index c8fe37231dc0..959936f6173b 100644 --- a/doc/release-notes/rl-2605.section.md +++ b/doc/release-notes/rl-2605.section.md @@ -9,6 +9,32 @@ - Node.js default version has been updated from 22 LTS to 24 LTS. This introduces some breaking changes; Refer to the [upstream migration article](https://nodejs.org/en/blog/migrations/v22-to-v24) for details. +- Nixpkgs configuration, specified for NixOS using `nixpkgs.config`, or using the `config` argument when importing nixpkgs, has learned to accept a `lib` argument as well as `pkgs`, which allows the configuration to be computed without depending on the `pkgs` fixed point. If you are referencing licenses in `lib.licenses` by having this configuration be a function taking a `pkgs` arg, you may wish to change to using `lib` for faster computation and to avoid infinite recursion errors if pkgs depends on parts of the computed configuration in future. + + For example, if you currently have configuration that looks like this: + + { pkgs, ... }: + { + allowlistedLicenses = [ pkgs.lib.licenses.nasa13 ]; + blocklistedLicenses = with pkgs.lib.licenses; [ gpl3Only gpl3Plus ]; + } + + You may wish to update it to something like this: + + { lib, ... }: + { + allowlistedLicenses = [ lib.licenses.nasa13 ]; + blocklistedLicenses = with lib.licenses; [ gpl3Only gpl3Plus ]; + } + + Or, if you need configuration that works with both 26.05 and 25.11: + + { pkgs, lib ? pkgs.lib, ... }: + { + allowlistedLicenses = [ lib.licenses.nasa13 ]; + blocklistedLicenses = with lib.licenses; [ gpl3Only gpl3Plus ]; + } + ## Backward Incompatibilities {#sec-nixpkgs-release-26.05-incompatibilities} diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix index 449a08a97b61..0e7f0f783b7b 100644 --- a/nixos/modules/misc/nixpkgs.nix +++ b/nixos/modules/misc/nixpkgs.nix @@ -16,8 +16,8 @@ let mergeConfig = lhs_: rhs_: let - lhs = optCall lhs_ { inherit pkgs; }; - rhs = optCall rhs_ { inherit pkgs; }; + lhs = optCall lhs_ { inherit lib pkgs; }; + rhs = optCall rhs_ { inherit lib pkgs; }; in lib.recursiveUpdate lhs rhs // lib.optionalAttrs (lhs ? packageOverrides) { diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index ecfef757909e..29da5c93202c 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -109,7 +109,7 @@ let # Allow both: # { /* the config */ } and # { pkgs, ... } : { /* the config */ } - config1 = if lib.isFunction config0 then config0 { inherit pkgs; } else config0; + config1 = if lib.isFunction config0 then config0 { inherit lib pkgs; } else config0; configEval = lib.evalModules { modules = [