at 25.11-pre 16 kB view raw
1{ 2 config, 3 options, 4 lib, 5 pkgs, 6 ... 7}: 8let 9 cfg = config.nixpkgs; 10 opt = options.nixpkgs; 11 12 isConfig = x: builtins.isAttrs x || lib.isFunction x; 13 14 optCall = f: x: if lib.isFunction f then f x else f; 15 16 mergeConfig = 17 lhs_: rhs_: 18 let 19 lhs = optCall lhs_ { inherit pkgs; }; 20 rhs = optCall rhs_ { inherit pkgs; }; 21 in 22 lib.recursiveUpdate lhs rhs 23 // lib.optionalAttrs (lhs ? packageOverrides) { 24 packageOverrides = 25 pkgs: 26 optCall lhs.packageOverrides pkgs // optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs; 27 } 28 // lib.optionalAttrs (lhs ? perlPackageOverrides) { 29 perlPackageOverrides = 30 pkgs: 31 optCall lhs.perlPackageOverrides pkgs 32 // optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs; 33 }; 34 35 configType = lib.mkOptionType { 36 name = "nixpkgs-config"; 37 description = "nixpkgs config"; 38 check = 39 x: 40 let 41 traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false; 42 in 43 traceXIfNot isConfig; 44 merge = args: lib.foldr (def: mergeConfig def.value) { }; 45 }; 46 47 overlayType = lib.mkOptionType { 48 name = "nixpkgs-overlay"; 49 description = "nixpkgs overlay"; 50 check = lib.isFunction; 51 merge = lib.mergeOneOption; 52 }; 53 54 pkgsType = lib.types.pkgs // { 55 # This type is only used by itself, so let's elaborate the description a bit 56 # for the purpose of documentation. 57 description = "An evaluation of Nixpkgs; the top level attribute set of packages"; 58 }; 59 60 hasBuildPlatform = opt.buildPlatform.highestPrio < (lib.mkOptionDefault { }).priority; 61 hasHostPlatform = opt.hostPlatform.isDefined; 62 hasPlatform = hasHostPlatform || hasBuildPlatform; 63 64 # Context for messages 65 hostPlatformLine = lib.optionalString hasHostPlatform "${lib.showOptionWithDefLocs opt.hostPlatform}"; 66 buildPlatformLine = lib.optionalString hasBuildPlatform "${lib.showOptionWithDefLocs opt.buildPlatform}"; 67 68 legacyOptionsDefined = 69 lib.optional (opt.localSystem.highestPrio < (lib.mkDefault { }).priority) opt.system 70 ++ lib.optional (opt.localSystem.highestPrio < (lib.mkOptionDefault { }).priority) opt.localSystem 71 ++ lib.optional (opt.crossSystem.highestPrio < (lib.mkOptionDefault { }).priority) opt.crossSystem; 72 73 defaultPkgs = 74 if opt.hostPlatform.isDefined then 75 let 76 isCross = cfg.buildPlatform != cfg.hostPlatform; 77 systemArgs = 78 if isCross then 79 { 80 localSystem = cfg.buildPlatform; 81 crossSystem = cfg.hostPlatform; 82 } 83 else 84 { 85 localSystem = cfg.hostPlatform; 86 }; 87 in 88 import ../../.. ( 89 { 90 inherit (cfg) config overlays; 91 } 92 // systemArgs 93 ) 94 else 95 import ../../.. { 96 inherit (cfg) 97 config 98 overlays 99 localSystem 100 crossSystem 101 ; 102 }; 103 104 finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs; 105 106in 107 108{ 109 imports = [ 110 ./assertions.nix 111 ./meta.nix 112 (lib.mkRemovedOptionModule [ "nixpkgs" "initialSystem" ] 113 "The NixOS options `nesting.clone` and `nesting.children` have been deleted, and replaced with named specialisation. Therefore `nixpgks.initialSystem` has no effect anymore." 114 ) 115 ]; 116 117 options.nixpkgs = { 118 119 pkgs = lib.mkOption { 120 defaultText = lib.literalExpression '' 121 import "''${nixos}/.." { 122 inherit (cfg) config overlays localSystem crossSystem; 123 } 124 ''; 125 type = pkgsType; 126 example = lib.literalExpression "import <nixpkgs> {}"; 127 description = '' 128 If set, the pkgs argument to all NixOS modules is the value of 129 this option, extended with `nixpkgs.overlays`, if 130 that is also set. Either `nixpkgs.crossSystem` or 131 `nixpkgs.localSystem` will be used in an assertion 132 to check that the NixOS and Nixpkgs architectures match. Any 133 other options in `nixpkgs.*`, notably `config`, 134 will be ignored. 135 136 If unset, the pkgs argument to all NixOS modules is determined 137 as shown in the default value for this option. 138 139 The default value imports the Nixpkgs source files 140 relative to the location of this NixOS module, because 141 NixOS and Nixpkgs are distributed together for consistency, 142 so the `nixos` in the default value is in fact a 143 relative path. The `config`, `overlays`, 144 `localSystem`, and `crossSystem` come 145 from this option's siblings. 146 147 This option can be used by applications like NixOps to increase 148 the performance of evaluation, or to create packages that depend 149 on a container that should be built with the exact same evaluation 150 of Nixpkgs, for example. Applications like this should set 151 their default value using `lib.mkDefault`, so 152 user-provided configuration can override it without using 153 `lib`. 154 155 Note that using a distinct version of Nixpkgs with NixOS may 156 be an unexpected source of problems. Use this option with care. 157 ''; 158 }; 159 160 config = lib.mkOption { 161 default = { }; 162 example = lib.literalExpression '' 163 { allowBroken = true; allowUnfree = true; } 164 ''; 165 type = configType; 166 description = '' 167 Global configuration for Nixpkgs. 168 The complete list of [Nixpkgs configuration options](https://nixos.org/manual/nixpkgs/unstable/#sec-config-options-reference) is in the [Nixpkgs manual section on global configuration](https://nixos.org/manual/nixpkgs/unstable/#chap-packageconfig). 169 170 Ignored when {option}`nixpkgs.pkgs` is set. 171 ''; 172 }; 173 174 overlays = lib.mkOption { 175 default = [ ]; 176 example = lib.literalExpression '' 177 [ 178 (self: super: { 179 openssh = super.openssh.override { 180 hpnSupport = true; 181 kerberos = self.libkrb5; 182 }; 183 }) 184 ] 185 ''; 186 type = lib.types.listOf overlayType; 187 description = '' 188 List of overlays to apply to Nixpkgs. 189 This option allows modifying the Nixpkgs package set accessed through the `pkgs` module argument. 190 191 For details, see the [Overlays chapter in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-overlays). 192 193 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`. 194 ''; 195 }; 196 197 hostPlatform = lib.mkOption { 198 type = lib.types.either lib.types.str lib.types.attrs; # TODO utilize lib.systems.parsedPlatform 199 example = { 200 system = "aarch64-linux"; 201 }; 202 # Make sure that the final value has all fields for sake of other modules 203 # referring to this. TODO make `lib.systems` itself use the module system. 204 apply = lib.systems.elaborate; 205 defaultText = lib.literalExpression ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform''; 206 description = '' 207 Specifies the platform where the NixOS configuration will run. 208 209 To cross-compile, set also `nixpkgs.buildPlatform`. 210 211 Ignored when `nixpkgs.pkgs` is set. 212 ''; 213 }; 214 215 buildPlatform = lib.mkOption { 216 type = lib.types.either lib.types.str lib.types.attrs; # TODO utilize lib.systems.parsedPlatform 217 default = cfg.hostPlatform; 218 example = { 219 system = "x86_64-linux"; 220 }; 221 # Make sure that the final value has all fields for sake of other modules 222 # referring to this. 223 apply = 224 inputBuildPlatform: 225 let 226 elaborated = lib.systems.elaborate inputBuildPlatform; 227 in 228 if lib.systems.equals elaborated cfg.hostPlatform then 229 cfg.hostPlatform # make identical, so that `==` equality works; see https://github.com/NixOS/nixpkgs/issues/278001 230 else 231 elaborated; 232 defaultText = lib.literalExpression ''config.nixpkgs.hostPlatform''; 233 description = '' 234 Specifies the platform on which NixOS should be built. 235 By default, NixOS is built on the system where it runs, but you can 236 change where it's built. Setting this option will cause NixOS to be 237 cross-compiled. 238 239 For instance, if you're doing distributed multi-platform deployment, 240 or if you're building machines, you can set this to match your 241 development system and/or build farm. 242 243 Ignored when `nixpkgs.pkgs` is set. 244 ''; 245 }; 246 247 localSystem = lib.mkOption { 248 type = lib.types.attrs; # TODO utilize lib.systems.parsedPlatform 249 default = { inherit (cfg) system; }; 250 example = { 251 system = "aarch64-linux"; 252 }; 253 # Make sure that the final value has all fields for sake of other modules 254 # referring to this. TODO make `lib.systems` itself use the module system. 255 apply = lib.systems.elaborate; 256 defaultText = lib.literalExpression ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform''; 257 description = '' 258 Systems with a recently generated `hardware-configuration.nix` 259 do not need to specify this option, unless cross-compiling, in which case 260 you should set *only* {option}`nixpkgs.buildPlatform`. 261 262 If this is somehow not feasible, you may fall back to removing the 263 {option}`nixpkgs.hostPlatform` line from the generated config and 264 use the old options. 265 266 Specifies the platform on which NixOS should be built. When 267 `nixpkgs.crossSystem` is unset, it also specifies 268 the platform *for* which NixOS should be 269 built. If this option is unset, it defaults to the platform 270 type of the machine where evaluation happens. Specifying this 271 option is useful when doing distributed multi-platform 272 deployment, or when building virtual machines. See its 273 description in the Nixpkgs manual for more details. 274 275 Ignored when `nixpkgs.pkgs` or `hostPlatform` is set. 276 ''; 277 }; 278 279 # TODO deprecate. "crossSystem" is a nonsense identifier, because "cross" 280 # is a relation between at least 2 systems in the context of a 281 # specific build step, not a single system. 282 crossSystem = lib.mkOption { 283 type = lib.types.nullOr lib.types.attrs; # TODO utilize lib.systems.parsedPlatform 284 default = null; 285 example = { 286 system = "aarch64-linux"; 287 }; 288 description = '' 289 Systems with a recently generated `hardware-configuration.nix` 290 may instead specify *only* {option}`nixpkgs.buildPlatform`, 291 or fall back to removing the {option}`nixpkgs.hostPlatform` line from the generated config. 292 293 Specifies the platform for which NixOS should be 294 built. Specify this only if it is different from 295 `nixpkgs.localSystem`, the platform 296 *on* which NixOS should be built. In other 297 words, specify this to cross-compile NixOS. Otherwise it 298 should be set as null, the default. See its description in the 299 Nixpkgs manual for more details. 300 301 Ignored when `nixpkgs.pkgs` or `hostPlatform` is set. 302 ''; 303 }; 304 305 system = lib.mkOption { 306 type = lib.types.str; 307 example = "i686-linux"; 308 default = 309 if opt.hostPlatform.isDefined then 310 throw '' 311 Neither ${opt.system} nor any other option in nixpkgs.* is meant 312 to be read by modules and configurations. 313 Use pkgs.stdenv.hostPlatform instead. 314 '' 315 else 316 throw '' 317 Neither ${opt.hostPlatform} nor the legacy option ${opt.system} has been set. 318 You can set ${opt.hostPlatform} in hardware-configuration.nix by re-running 319 a recent version of nixos-generate-config. 320 The option ${opt.system} is still fully supported for NixOS 22.05 interoperability, 321 but will be deprecated in the future, so we recommend to set ${opt.hostPlatform}. 322 ''; 323 defaultText = lib.literalMD '' 324 Traditionally `builtins.currentSystem`, but unset when invoking NixOS through `lib.nixosSystem`. 325 ''; 326 description = '' 327 This option does not need to be specified for NixOS configurations 328 with a recently generated `hardware-configuration.nix`. 329 330 Specifies the Nix platform type on which NixOS should be built. 331 It is better to specify `nixpkgs.localSystem` instead. 332 ``` 333 { 334 nixpkgs.system = ..; 335 } 336 ``` 337 is the same as 338 ``` 339 { 340 nixpkgs.localSystem.system = ..; 341 } 342 ``` 343 See `nixpkgs.localSystem` for more information. 344 345 Ignored when `nixpkgs.pkgs`, `nixpkgs.localSystem` or `nixpkgs.hostPlatform` is set. 346 ''; 347 }; 348 }; 349 350 config = { 351 _module.args = { 352 pkgs = 353 # We explicitly set the default override priority, so that we do not need 354 # to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`. 355 # After all, to determine a definition priority, we need to evaluate `._type`, 356 # which is somewhat costly for Nixpkgs. With an explicit priority, we only 357 # evaluate the wrapper to find out that the priority is lower, and then we 358 # don't need to evaluate `finalPkgs`. 359 lib.mkOverride lib.modules.defaultOverridePriority finalPkgs.__splicedPackages; 360 }; 361 362 assertions = 363 let 364 # Whether `pkgs` was constructed by this module. This is false when any of 365 # nixpkgs.pkgs or _module.args.pkgs is set. 366 constructedByMe = 367 # We set it with default priority and it can not be merged, so if the 368 # pkgs module argument has that priority, it's from us. 369 (lib.modules.mergeAttrDefinitionsWithPrio options._module.args).pkgs.highestPrio 370 == lib.modules.defaultOverridePriority 371 # Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it. 372 && !opt.pkgs.isDefined; 373 in 374 [ 375 ( 376 let 377 nixosExpectedSystem = 378 if config.nixpkgs.crossSystem != null then 379 config.nixpkgs.crossSystem.system or (lib.systems.parse.doubleFromSystem ( 380 lib.systems.parse.mkSystemFromString config.nixpkgs.crossSystem.config 381 )) 382 else 383 config.nixpkgs.localSystem.system or (lib.systems.parse.doubleFromSystem ( 384 lib.systems.parse.mkSystemFromString config.nixpkgs.localSystem.config 385 )); 386 nixosOption = 387 if config.nixpkgs.crossSystem != null then "nixpkgs.crossSystem" else "nixpkgs.localSystem"; 388 pkgsSystem = finalPkgs.stdenv.targetPlatform.system; 389 in 390 { 391 assertion = constructedByMe -> !hasPlatform -> nixosExpectedSystem == pkgsSystem; 392 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."; 393 } 394 ) 395 { 396 assertion = constructedByMe -> hasPlatform -> legacyOptionsDefined == [ ]; 397 message = '' 398 Your system configures nixpkgs with the platform parameter${lib.optionalString hasBuildPlatform "s"}: 399 ${hostPlatformLine}${buildPlatformLine} 400 However, it also defines the legacy options: 401 ${lib.concatMapStrings lib.showOptionWithDefLocs legacyOptionsDefined} 402 For a future proof system configuration, we recommend to remove 403 the legacy definitions. 404 ''; 405 } 406 { 407 assertion = opt.pkgs.isDefined -> cfg.config == { }; 408 message = '' 409 Your system configures nixpkgs with an externally created instance. 410 `nixpkgs.config` options should be passed when creating the instance instead. 411 412 Current value: 413 ${lib.generators.toPretty { multiline = true; } cfg.config} 414 415 Defined in: 416 ${lib.concatMapStringsSep "\n" (file: " - ${file}") opt.config.files} 417 ''; 418 } 419 ]; 420 }; 421 422 # needs a full nixpkgs path to import nixpkgs 423 meta.buildDocsInSandbox = false; 424}