From eec21001b0f7961cb84fe40512e8238ec3effb87 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sat, 11 Jan 2025 11:24:30 +0100 Subject: [PATCH] nixos/nixpkgs: pass original system args instead of elaborated Passing the elaborated system defeats what pkgs/top-level/default.nix tries to do: Pass only the original args and let defaults be inferred. The underlying problem is that lib.systems.elaborate can not deal with arbitrary overrides, but will often return an inconsistent system description when partially overriding some values. This becomes most prominent if trying to override an already elaborated system. --- lib/modules.nix | 2 ++ nixos/modules/misc/nixpkgs.nix | 15 ++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/modules.nix b/lib/modules.nix index 79b8f25c2f43..8ec850b59193 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -844,6 +844,8 @@ let in warnDeprecation opt // { value = addErrorContext "while evaluating the option `${showOption loc}':" value; + # raw value before "apply" above + rawValue = addErrorContext "while evaluating the option `${showOption loc}':" res.mergedValue; inherit (res.defsFinal') highestPrio; definitions = map (def: def.value) res.defsFinal; files = map (def: def.file) res.defsFinal; diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix index e1c705eef3b5..f99f75af7659 100644 --- a/nixos/modules/misc/nixpkgs.nix +++ b/nixos/modules/misc/nixpkgs.nix @@ -70,19 +70,24 @@ let ++ lib.optional (opt.localSystem.highestPrio < (lib.mkOptionDefault { }).priority) opt.localSystem ++ lib.optional (opt.crossSystem.highestPrio < (lib.mkOptionDefault { }).priority) opt.crossSystem; + # pkgs/top-level/default.nix takes great strides to pass the *original* localSystem/crossSystem args + # on to nixpkgsFun to create package sets like pkgsStatic, pkgsMusl. This is to be able to infer default + # values again. Since cfg.xxxPlatform and cfg.xxxSystem are elaborated via apply, those can't be passed + # directly. Instead we use the rawValue before the apply/elaboration step, via opt.xxx.rawValue. defaultPkgs = if opt.hostPlatform.isDefined then let + # This compares elaborated systems on purpose, **not** using rawValue. isCross = cfg.buildPlatform != cfg.hostPlatform; systemArgs = if isCross then { - localSystem = cfg.buildPlatform; - crossSystem = cfg.hostPlatform; + localSystem = opt.buildPlatform.rawValue; + crossSystem = opt.hostPlatform.rawValue; } else { - localSystem = cfg.hostPlatform; + localSystem = opt.hostPlatform.rawValue; }; in import ../../.. ( @@ -96,9 +101,9 @@ let inherit (cfg) config overlays - localSystem - crossSystem ; + localSystem = opt.localSystem.rawValue; + crossSystem = opt.crossSystem.rawValue; }; finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;