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