1 { config, options, lib, pkgs, ... }:
10 builtins.isAttrs x || lib.isFunction x;
17 mergeConfig = lhs_: rhs_:
19 lhs = optCall lhs_ { inherit pkgs; };
20 rhs = optCall rhs_ { inherit pkgs; };
22 recursiveUpdate lhs rhs //
23 optionalAttrs (lhs ? packageOverrides) {
24 packageOverrides = pkgs:
25 optCall lhs.packageOverrides pkgs //
26 optCall (attrByPath [ "packageOverrides" ] { } rhs) pkgs;
28 optionalAttrs (lhs ? perlPackageOverrides) {
29 perlPackageOverrides = pkgs:
30 optCall lhs.perlPackageOverrides pkgs //
31 optCall (attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
34 configType = mkOptionType {
35 name = "nixpkgs-config";
36 description = "nixpkgs config";
40 else lib.traceSeqN 1 x false;
41 in traceXIfNot isConfig;
42 merge = args: foldr (def: mergeConfig def.value) {};
45 overlayType = mkOptionType {
46 name = "nixpkgs-overlay";
47 description = "nixpkgs overlay";
48 check = lib.isFunction;
49 merge = lib.mergeOneOption;
52 pkgsType = types.pkgs // {
53 # This type is only used by itself, so let's elaborate the description a bit
54 # for the purpose of documentation.
55 description = "An evaluation of Nixpkgs; the top level attribute set of packages";
58 hasBuildPlatform = opt.buildPlatform.highestPrio < (mkOptionDefault {}).priority;
59 hasHostPlatform = opt.hostPlatform.isDefined;
60 hasPlatform = hasHostPlatform || hasBuildPlatform;
62 # Context for messages
63 hostPlatformLine = optionalString hasHostPlatform "${showOptionWithDefLocs opt.hostPlatform}";
64 buildPlatformLine = optionalString hasBuildPlatform "${showOptionWithDefLocs opt.buildPlatform}";
66 legacyOptionsDefined =
67 optional (opt.localSystem.highestPrio < (mkDefault {}).priority) opt.system
68 ++ optional (opt.localSystem.highestPrio < (mkOptionDefault {}).priority) opt.localSystem
69 ++ optional (opt.crossSystem.highestPrio < (mkOptionDefault {}).priority) opt.crossSystem
73 if opt.hostPlatform.isDefined
75 let isCross = cfg.buildPlatform != cfg.hostPlatform;
79 localSystem = cfg.buildPlatform;
80 crossSystem = cfg.hostPlatform;
83 localSystem = cfg.hostPlatform;
87 inherit (cfg) config overlays;
91 inherit (cfg) config overlays localSystem crossSystem;
94 finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;
102 (mkRemovedOptionModule [ "nixpkgs" "initialSystem" ] "The NixOS options `nesting.clone` and `nesting.children` have been deleted, and replaced with named specialisation. Therefore `nixpgks.initialSystem` has no effect anymore.")
108 defaultText = literalExpression ''
109 import "''${nixos}/.." {
110 inherit (cfg) config overlays localSystem crossSystem;
114 example = literalExpression "import <nixpkgs> {}";
115 description = lib.mdDoc ''
116 If set, the pkgs argument to all NixOS modules is the value of
117 this option, extended with `nixpkgs.overlays`, if
118 that is also set. Either `nixpkgs.crossSystem` or
119 `nixpkgs.localSystem` will be used in an assertion
120 to check that the NixOS and Nixpkgs architectures match. Any
121 other options in `nixpkgs.*`, notably `config`,
124 If unset, the pkgs argument to all NixOS modules is determined
125 as shown in the default value for this option.
127 The default value imports the Nixpkgs source files
128 relative to the location of this NixOS module, because
129 NixOS and Nixpkgs are distributed together for consistency,
130 so the `nixos` in the default value is in fact a
131 relative path. The `config`, `overlays`,
132 `localSystem`, and `crossSystem` come
133 from this option's siblings.
135 This option can be used by applications like NixOps to increase
136 the performance of evaluation, or to create packages that depend
137 on a container that should be built with the exact same evaluation
138 of Nixpkgs, for example. Applications like this should set
139 their default value using `lib.mkDefault`, so
140 user-provided configuration can override it without using
143 Note that using a distinct version of Nixpkgs with NixOS may
144 be an unexpected source of problems. Use this option with care.
150 example = literalExpression
152 { allowBroken = true; allowUnfree = true; }
155 description = lib.mdDoc ''
156 The configuration of the Nix Packages collection. (For
157 details, see the Nixpkgs documentation.) It allows you to set
158 package configuration options.
160 Ignored when `nixpkgs.pkgs` is set.
164 overlays = mkOption {
166 example = literalExpression
170 openssh = super.openssh.override {
172 kerberos = self.libkrb5;
177 type = types.listOf overlayType;
178 description = lib.mdDoc ''
179 List of overlays to apply to Nixpkgs.
180 This option allows modifying the Nixpkgs package set accessed through the `pkgs` module argument.
182 For details, see the [Overlays chapter in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-overlays).
184 If the {option}`nixpkgs.pkgs` option is set, overlays specified using `nixpkgs.overlays` will be applied after the overlays that were already included in `nixpkgs.pkgs`.
188 hostPlatform = mkOption {
189 type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
190 example = { system = "aarch64-linux"; };
191 # Make sure that the final value has all fields for sake of other modules
192 # referring to this. TODO make `lib.systems` itself use the module system.
193 apply = lib.systems.elaborate;
194 defaultText = literalExpression
195 ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform'';
196 description = lib.mdDoc ''
197 Specifies the platform where the NixOS configuration will run.
199 To cross-compile, set also `nixpkgs.buildPlatform`.
201 Ignored when `nixpkgs.pkgs` is set.
205 buildPlatform = mkOption {
206 type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
207 default = cfg.hostPlatform;
208 example = { system = "x86_64-linux"; };
209 # Make sure that the final value has all fields for sake of other modules
211 apply = lib.systems.elaborate;
212 defaultText = literalExpression
213 ''config.nixpkgs.hostPlatform'';
214 description = lib.mdDoc ''
215 Specifies the platform on which NixOS should be built.
216 By default, NixOS is built on the system where it runs, but you can
217 change where it's built. Setting this option will cause NixOS to be
220 For instance, if you're doing distributed multi-platform deployment,
221 or if you're building machines, you can set this to match your
222 development system and/or build farm.
224 Ignored when `nixpkgs.pkgs` is set.
228 localSystem = mkOption {
229 type = types.attrs; # TODO utilize lib.systems.parsedPlatform
230 default = { inherit (cfg) system; };
231 example = { system = "aarch64-linux"; };
232 # Make sure that the final value has all fields for sake of other modules
233 # referring to this. TODO make `lib.systems` itself use the module system.
234 apply = lib.systems.elaborate;
235 defaultText = literalExpression
236 ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform'';
237 description = lib.mdDoc ''
238 Systems with a recently generated `hardware-configuration.nix`
239 do not need to specify this option, unless cross-compiling, in which case
240 you should set *only* {option}`nixpkgs.buildPlatform`.
242 If this is somehow not feasible, you may fall back to removing the
243 {option}`nixpkgs.hostPlatform` line from the generated config and
246 Specifies the platform on which NixOS should be built. When
247 `nixpkgs.crossSystem` is unset, it also specifies
248 the platform *for* which NixOS should be
249 built. If this option is unset, it defaults to the platform
250 type of the machine where evaluation happens. Specifying this
251 option is useful when doing distributed multi-platform
252 deployment, or when building virtual machines. See its
253 description in the Nixpkgs manual for more details.
255 Ignored when `nixpkgs.pkgs` or `hostPlatform` is set.
259 # TODO deprecate. "crossSystem" is a nonsense identifier, because "cross"
260 # is a relation between at least 2 systems in the context of a
261 # specific build step, not a single system.
262 crossSystem = mkOption {
263 type = types.nullOr types.attrs; # TODO utilize lib.systems.parsedPlatform
265 example = { system = "aarch64-linux"; };
266 description = lib.mdDoc ''
267 Systems with a recently generated `hardware-configuration.nix`
268 may instead specify *only* {option}`nixpkgs.buildPlatform`,
269 or fall back to removing the {option}`nixpkgs.hostPlatform` line from the generated config.
271 Specifies the platform for which NixOS should be
272 built. Specify this only if it is different from
273 `nixpkgs.localSystem`, the platform
274 *on* which NixOS should be built. In other
275 words, specify this to cross-compile NixOS. Otherwise it
276 should be set as null, the default. See its description in the
277 Nixpkgs manual for more details.
279 Ignored when `nixpkgs.pkgs` or `hostPlatform` is set.
285 example = "i686-linux";
287 if opt.hostPlatform.isDefined
290 Neither ${opt.system} nor any other option in nixpkgs.* is meant
291 to be read by modules and configurations.
292 Use pkgs.stdenv.hostPlatform instead.
296 Neither ${opt.hostPlatform} nor the legacy option ${opt.system} has been set.
297 You can set ${opt.hostPlatform} in hardware-configuration.nix by re-running
298 a recent version of nixos-generate-config.
299 The option ${opt.system} is still fully supported for NixOS 22.05 interoperability,
300 but will be deprecated in the future, so we recommend to set ${opt.hostPlatform}.
302 defaultText = lib.literalMD ''
303 Traditionally `builtins.currentSystem`, but unset when invoking NixOS through `lib.nixosSystem`.
305 description = lib.mdDoc ''
306 This option does not need to be specified for NixOS configurations
307 with a recently generated `hardware-configuration.nix`.
309 Specifies the Nix platform type on which NixOS should be built.
310 It is better to specify `nixpkgs.localSystem` instead.
319 nixpkgs.localSystem.system = ..;
322 See `nixpkgs.localSystem` for more information.
324 Ignored when `nixpkgs.pkgs`, `nixpkgs.localSystem` or `nixpkgs.hostPlatform` is set.
332 # We explicitly set the default override priority, so that we do not need
333 # to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`.
334 # After all, to determine a definition priority, we need to evaluate `._type`,
335 # which is somewhat costly for Nixpkgs. With an explicit priority, we only
336 # evaluate the wrapper to find out that the priority is lower, and then we
337 # don't need to evaluate `finalPkgs`.
338 lib.mkOverride lib.modules.defaultOverridePriority
339 finalPkgs.__splicedPackages;
343 # Whether `pkgs` was constructed by this module. This is false when any of
344 # nixpkgs.pkgs or _module.args.pkgs is set.
346 # We set it with default priority and it can not be merged, so if the
347 # pkgs module argument has that priority, it's from us.
348 (lib.modules.mergeAttrDefinitionsWithPrio options._module.args).pkgs.highestPrio
349 == lib.modules.defaultOverridePriority
350 # Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it.
351 && !opt.pkgs.isDefined;
355 nixosExpectedSystem =
356 if config.nixpkgs.crossSystem != null
357 then config.nixpkgs.crossSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.crossSystem.config))
358 else config.nixpkgs.localSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.localSystem.config));
360 if config.nixpkgs.crossSystem != null
361 then "nixpkgs.crossSystem"
362 else "nixpkgs.localSystem";
363 pkgsSystem = finalPkgs.stdenv.targetPlatform.system;
365 assertion = constructedByMe -> !hasPlatform -> nixosExpectedSystem == pkgsSystem;
366 message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system.";
370 assertion = constructedByMe -> hasPlatform -> legacyOptionsDefined == [];
372 Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}:
376 However, it also defines the legacy options:
377 ${concatMapStrings showOptionWithDefLocs legacyOptionsDefined}
378 For a future proof system configuration, we recommend to remove
379 the legacy definitions.
383 assertion = opt.pkgs.isDefined -> cfg.config == {};
385 Your system configures nixpkgs with an externally created instance.
386 `nixpkgs.config` options should be passed when creating the instance instead.
389 ${lib.generators.toPretty { multiline = true; } opt.config}
395 # needs a full nixpkgs path to import nixpkgs
396 meta.buildDocsInSandbox = false;