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