2020-04-24 23:36:52 +00:00
{ config , options , lib , pkgs , . . . }:
let
cfg = config . nixpkgs ;
opt = options . nixpkgs ;
isConfig = x :
builtins . isAttrs x || lib . isFunction x ;
optCall = f : x :
if lib . isFunction f
then f x
else f ;
mergeConfig = lhs_ : rhs_ :
let
lhs = optCall lhs_ { inherit pkgs ; } ;
rhs = optCall rhs_ { inherit pkgs ; } ;
in
2024-09-19 14:19:46 +00:00
lib . recursiveUpdate lhs rhs //
lib . optionalAttrs ( lhs ? packageOverrides ) {
2020-04-24 23:36:52 +00:00
packageOverrides = pkgs :
optCall lhs . packageOverrides pkgs //
2024-09-19 14:19:46 +00:00
optCall ( lib . attrByPath [ " p a c k a g e O v e r r i d e s " ] { } rhs ) pkgs ;
2020-04-24 23:36:52 +00:00
} //
2024-09-19 14:19:46 +00:00
lib . optionalAttrs ( lhs ? perlPackageOverrides ) {
2020-04-24 23:36:52 +00:00
perlPackageOverrides = pkgs :
optCall lhs . perlPackageOverrides pkgs //
2024-09-19 14:19:46 +00:00
optCall ( lib . attrByPath [ " p e r l P a c k a g e O v e r r i d e s " ] { } rhs ) pkgs ;
2020-04-24 23:36:52 +00:00
} ;
2024-09-19 14:19:46 +00:00
configType = lib . mkOptionType {
2020-04-24 23:36:52 +00:00
name = " n i x p k g s - c o n f i g " ;
description = " n i x p k g s c o n f i g " ;
check = x :
let traceXIfNot = c :
if c x then true
else lib . traceSeqN 1 x false ;
in traceXIfNot isConfig ;
2024-09-19 14:19:46 +00:00
merge = args : lib . foldr ( def : mergeConfig def . value ) { } ;
2020-04-24 23:36:52 +00:00
} ;
2024-09-19 14:19:46 +00:00
overlayType = lib . mkOptionType {
2020-04-24 23:36:52 +00:00
name = " n i x p k g s - o v e r l a y " ;
description = " n i x p k g s o v e r l a y " ;
check = lib . isFunction ;
merge = lib . mergeOneOption ;
} ;
2024-09-19 14:19:46 +00:00
pkgsType = lib . types . pkgs // {
2023-05-24 13:37:59 +00:00
# This type is only used by itself, so let's elaborate the description a bit
# for the purpose of documentation.
2020-04-24 23:36:52 +00:00
description = " A n e v a l u a t i o n o f N i x p k g s ; t h e t o p l e v e l a t t r i b u t e s e t o f p a c k a g e s " ;
} ;
2024-09-19 14:19:46 +00:00
hasBuildPlatform = opt . buildPlatform . highestPrio < ( lib . mkOptionDefault { } ) . priority ;
2022-06-26 10:26:21 +00:00
hasHostPlatform = opt . hostPlatform . isDefined ;
hasPlatform = hasHostPlatform || hasBuildPlatform ;
# Context for messages
2024-09-19 14:19:46 +00:00
hostPlatformLine = lib . optionalString hasHostPlatform " ${ lib . showOptionWithDefLocs opt . hostPlatform } " ;
buildPlatformLine = lib . optionalString hasBuildPlatform " ${ lib . showOptionWithDefLocs opt . buildPlatform } " ;
2022-06-26 10:26:21 +00:00
legacyOptionsDefined =
2024-09-19 14:19:46 +00:00
lib . optional ( opt . localSystem . highestPrio < ( lib . mkDefault { } ) . priority ) opt . system
++ lib . optional ( opt . localSystem . highestPrio < ( lib . mkOptionDefault { } ) . priority ) opt . localSystem
++ lib . optional ( opt . crossSystem . highestPrio < ( lib . mkOptionDefault { } ) . priority ) opt . crossSystem
2022-06-26 10:26:21 +00:00
;
defaultPkgs =
if opt . hostPlatform . isDefined
then
let isCross = cfg . buildPlatform != cfg . hostPlatform ;
systemArgs =
if isCross
then {
localSystem = cfg . buildPlatform ;
crossSystem = cfg . hostPlatform ;
}
else {
localSystem = cfg . hostPlatform ;
} ;
in
import ../../.. ( {
inherit ( cfg ) config overlays ;
} // systemArgs )
else
import ../../.. {
inherit ( cfg ) config overlays localSystem crossSystem ;
} ;
2020-04-24 23:36:52 +00:00
finalPkgs = if opt . pkgs . isDefined then cfg . pkgs . appendOverlays cfg . overlays else defaultPkgs ;
in
{
2022-01-22 01:22:15 +00:00
imports = [
./assertions.nix
./meta.nix
2024-09-19 14:19:46 +00:00
( lib . mkRemovedOptionModule [ " n i x p k g s " " i n i t i a l S y s t e m " ] " T h e N i x O S o p t i o n s ` n e s t i n g . c l o n e ` a n d ` n e s t i n g . c h i l d r e n ` h a v e b e e n d e l e t e d , a n d r e p l a c e d w i t h n a m e d s p e c i a l i s a t i o n . T h e r e f o r e ` n i x p g k s . i n i t i a l S y s t e m ` h a s n o e f f e c t a n y m o r e . " )
2022-01-22 01:22:15 +00:00
] ;
2020-04-24 23:36:52 +00:00
options . nixpkgs = {
2024-09-19 14:19:46 +00:00
pkgs = lib . mkOption {
defaultText = lib . literalExpression ''
2021-10-06 13:57:05 +00:00
import " ' ' ${ nixos } / . . " {
inherit ( cfg ) config overlays localSystem crossSystem ;
}
'' ;
2020-04-24 23:36:52 +00:00
type = pkgsType ;
2024-09-19 14:19:46 +00:00
example = lib . literalExpression " i m p o r t < n i x p k g s > { } " ;
2024-04-21 15:54:59 +00:00
description = ''
2020-04-24 23:36:52 +00:00
If set , the pkgs argument to all NixOS modules is the value of
2022-08-21 13:32:41 +00:00
this option , extended with ` nixpkgs . overlays ` , if
that is also set . Either ` nixpkgs . crossSystem ` or
` nixpkgs . localSystem ` will be used in an assertion
2020-04-24 23:36:52 +00:00
to check that the NixOS and Nixpkgs architectures match . Any
2022-08-21 13:32:41 +00:00
other options in ` nixpkgs . * ` , notably ` config ` ,
2020-04-24 23:36:52 +00:00
will be ignored .
If unset , the pkgs argument to all NixOS modules is determined
as shown in the default value for this option .
The default value imports the Nixpkgs source files
relative to the location of this NixOS module , because
NixOS and Nixpkgs are distributed together for consistency ,
2022-08-21 13:32:41 +00:00
so the ` nixos ` in the default value is in fact a
relative path . The ` config ` , ` overlays ` ,
` localSystem ` , and ` crossSystem ` come
2020-04-24 23:36:52 +00:00
from this option's siblings .
This option can be used by applications like NixOps to increase
the performance of evaluation , or to create packages that depend
on a container that should be built with the exact same evaluation
of Nixpkgs , for example . Applications like this should set
2022-08-21 13:32:41 +00:00
their default value using ` lib . mkDefault ` , so
2020-04-24 23:36:52 +00:00
user-provided configuration can override it without using
2022-08-21 13:32:41 +00:00
` lib ` .
2020-04-24 23:36:52 +00:00
Note that using a distinct version of Nixpkgs with NixOS may
be an unexpected source of problems . Use this option with care .
'' ;
} ;
2024-09-19 14:19:46 +00:00
config = lib . mkOption {
2020-04-24 23:36:52 +00:00
default = { } ;
2024-09-19 14:19:46 +00:00
example = lib . literalExpression
2020-04-24 23:36:52 +00:00
''
{ allowBroken = true ; allowUnfree = true ; }
'' ;
type = configType ;
2024-04-21 15:54:59 +00:00
description = ''
Global configuration for Nixpkgs .
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).
2020-04-24 23:36:52 +00:00
2024-04-21 15:54:59 +00:00
Ignored when { option } ` nixpkgs . pkgs ` is set .
2020-04-24 23:36:52 +00:00
'' ;
} ;
2024-09-19 14:19:46 +00:00
overlays = lib . mkOption {
2020-04-24 23:36:52 +00:00
default = [ ] ;
2024-09-19 14:19:46 +00:00
example = lib . literalExpression
2020-04-24 23:36:52 +00:00
''
[
( self : super : {
openssh = super . openssh . override {
hpnSupport = true ;
kerberos = self . libkrb5 ;
} ;
} )
]
'' ;
2024-09-19 14:19:46 +00:00
type = lib . types . listOf overlayType ;
2024-04-21 15:54:59 +00:00
description = ''
2023-10-09 19:29:22 +00:00
List of overlays to apply to Nixpkgs .
This option allows modifying the Nixpkgs package set accessed through the ` pkgs ` module argument .
For details , see the [ Overlays chapter in the Nixpkgs manual ] ( https://nixos.org/manual/nixpkgs/stable/ #chap-overlays).
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 ` .
2020-04-24 23:36:52 +00:00
'' ;
} ;
2024-09-19 14:19:46 +00:00
hostPlatform = lib . mkOption {
type = lib . types . either lib . types . str lib . types . attrs ; # TODO utilize lib.systems.parsedPlatform
2023-11-16 04:20:00 +00:00
example = { system = " a a r c h 6 4 - l i n u x " ; } ;
2022-06-26 10:26:21 +00:00
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib . systems . elaborate ;
2024-09-19 14:19:46 +00:00
defaultText = lib . literalExpression
2022-06-26 10:26:21 +00:00
'' ( i m p o r t " ''$ { n i x o s } / . . / l i b " ) . l i b . s y s t e m s . e x a m p l e s . a a r c h 6 4 - m u l t i p l a t f o r m '' ;
2024-04-21 15:54:59 +00:00
description = ''
2022-06-26 10:26:21 +00:00
Specifies the platform where the NixOS configuration will run .
2022-08-21 13:32:41 +00:00
To cross-compile , set also ` nixpkgs . buildPlatform ` .
2022-06-26 10:26:21 +00:00
2022-08-21 13:32:41 +00:00
Ignored when ` nixpkgs . pkgs ` is set .
2022-06-26 10:26:21 +00:00
'' ;
} ;
2024-09-19 14:19:46 +00:00
buildPlatform = lib . mkOption {
type = lib . types . either lib . types . str lib . types . attrs ; # TODO utilize lib.systems.parsedPlatform
2022-06-26 10:26:21 +00:00
default = cfg . hostPlatform ;
2023-11-16 04:20:00 +00:00
example = { system = " x 8 6 _ 6 4 - l i n u x " ; } ;
2022-06-26 10:26:21 +00:00
# Make sure that the final value has all fields for sake of other modules
# referring to this.
2024-04-21 15:54:59 +00:00
apply = inputBuildPlatform :
let elaborated = lib . systems . elaborate inputBuildPlatform ;
in if lib . systems . equals elaborated cfg . hostPlatform
then cfg . hostPlatform # make identical, so that `==` equality works; see https://github.com/NixOS/nixpkgs/issues/278001
else elaborated ;
2024-09-19 14:19:46 +00:00
defaultText = lib . literalExpression
2022-06-26 10:26:21 +00:00
'' c o n f i g . n i x p k g s . h o s t P l a t f o r m '' ;
2024-04-21 15:54:59 +00:00
description = ''
2022-06-26 10:26:21 +00:00
Specifies the platform on which NixOS should be built .
By default , NixOS is built on the system where it runs , but you can
change where it's built . Setting this option will cause NixOS to be
cross-compiled .
For instance , if you're doing distributed multi-platform deployment ,
or if you're building machines , you can set this to match your
development system and/or build farm .
2022-08-21 13:32:41 +00:00
Ignored when ` nixpkgs . pkgs ` is set .
2022-06-26 10:26:21 +00:00
'' ;
} ;
2024-09-19 14:19:46 +00:00
localSystem = lib . mkOption {
type = lib . types . attrs ; # TODO utilize lib.systems.parsedPlatform
2020-04-24 23:36:52 +00:00
default = { inherit ( cfg ) system ; } ;
2023-11-16 04:20:00 +00:00
example = { system = " a a r c h 6 4 - l i n u x " ; } ;
2020-04-24 23:36:52 +00:00
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib . systems . elaborate ;
2024-09-19 14:19:46 +00:00
defaultText = lib . literalExpression
2020-04-24 23:36:52 +00:00
'' ( i m p o r t " ''$ { n i x o s } / . . / l i b " ) . l i b . s y s t e m s . e x a m p l e s . a a r c h 6 4 - m u l t i p l a t f o r m '' ;
2024-04-21 15:54:59 +00:00
description = ''
2022-08-21 13:32:41 +00:00
Systems with a recently generated ` hardware-configuration . nix `
2022-08-12 12:06:08 +00:00
do not need to specify this option , unless cross-compiling , in which case
2022-08-21 13:32:41 +00:00
you should set * only * { option } ` nixpkgs . buildPlatform ` .
2022-08-12 12:06:08 +00:00
If this is somehow not feasible , you may fall back to removing the
2022-08-21 13:32:41 +00:00
{ option } ` nixpkgs . hostPlatform ` line from the generated config and
2022-08-12 12:06:08 +00:00
use the old options .
2020-04-24 23:36:52 +00:00
Specifies the platform on which NixOS should be built . When
2022-08-21 13:32:41 +00:00
` nixpkgs . crossSystem ` is unset , it also specifies
the platform * for * which NixOS should be
2020-04-24 23:36:52 +00:00
built . If this option is unset , it defaults to the platform
type of the machine where evaluation happens . Specifying this
option is useful when doing distributed multi-platform
deployment , or when building virtual machines . See its
description in the Nixpkgs manual for more details .
2022-08-21 13:32:41 +00:00
Ignored when ` nixpkgs . pkgs ` or ` hostPlatform ` is set .
2020-04-24 23:36:52 +00:00
'' ;
} ;
2022-06-26 10:26:21 +00:00
# TODO deprecate. "crossSystem" is a nonsense identifier, because "cross"
# is a relation between at least 2 systems in the context of a
# specific build step, not a single system.
2024-09-19 14:19:46 +00:00
crossSystem = lib . mkOption {
type = lib . types . nullOr lib . types . attrs ; # TODO utilize lib.systems.parsedPlatform
2020-04-24 23:36:52 +00:00
default = null ;
2023-11-16 04:20:00 +00:00
example = { system = " a a r c h 6 4 - l i n u x " ; } ;
2024-04-21 15:54:59 +00:00
description = ''
2022-08-21 13:32:41 +00:00
Systems with a recently generated ` hardware-configuration . nix `
may instead specify * only * { option } ` nixpkgs . buildPlatform ` ,
or fall back to removing the { option } ` nixpkgs . hostPlatform ` line from the generated config .
2022-08-12 12:06:08 +00:00
2020-04-24 23:36:52 +00:00
Specifies the platform for which NixOS should be
built . Specify this only if it is different from
2022-08-21 13:32:41 +00:00
` nixpkgs . localSystem ` , the platform
* on * which NixOS should be built . In other
2020-04-24 23:36:52 +00:00
words , specify this to cross-compile NixOS . Otherwise it
should be set as null , the default . See its description in the
Nixpkgs manual for more details .
2022-08-21 13:32:41 +00:00
Ignored when ` nixpkgs . pkgs ` or ` hostPlatform ` is set .
2020-04-24 23:36:52 +00:00
'' ;
} ;
2024-09-19 14:19:46 +00:00
system = lib . mkOption {
type = lib . types . str ;
2020-04-24 23:36:52 +00:00
example = " i 6 8 6 - l i n u x " ;
2022-08-12 12:06:08 +00:00
default =
if opt . hostPlatform . isDefined
then
throw ''
Neither $ { opt . system } nor any other option in nixpkgs . * is meant
to be read by modules and configurations .
Use pkgs . stdenv . hostPlatform instead .
''
else
throw ''
2022-11-21 17:40:18 +00:00
Neither $ { opt . hostPlatform } nor the legacy option $ { opt . system } has been set .
2022-08-12 12:06:08 +00:00
You can set $ { opt . hostPlatform } in hardware-configuration . nix by re-running
a recent version of nixos-generate-config .
The option $ { opt . system } is still fully supported for NixOS 22 .05 interoperability ,
but will be deprecated in the future , so we recommend to set $ { opt . hostPlatform } .
'' ;
defaultText = lib . literalMD ''
Traditionally ` builtins . currentSystem ` , but unset when invoking NixOS through ` lib . nixosSystem ` .
'' ;
2024-04-21 15:54:59 +00:00
description = ''
2022-08-12 12:06:08 +00:00
This option does not need to be specified for NixOS configurations
2022-09-09 14:08:57 +00:00
with a recently generated ` hardware-configuration . nix ` .
2022-08-12 12:06:08 +00:00
2020-04-24 23:36:52 +00:00
Specifies the Nix platform type on which NixOS should be built .
2022-09-09 14:08:57 +00:00
It is better to specify ` nixpkgs . localSystem ` instead .
` ` `
2020-04-24 23:36:52 +00:00
{
nixpkgs . system = . . ;
}
2022-09-09 14:08:57 +00:00
` ` `
2020-04-24 23:36:52 +00:00
is the same as
2022-09-09 14:08:57 +00:00
` ` `
2020-04-24 23:36:52 +00:00
{
nixpkgs . localSystem . system = . . ;
}
2022-09-09 14:08:57 +00:00
` ` `
See ` nixpkgs . localSystem ` for more information .
2020-04-24 23:36:52 +00:00
2022-09-09 14:08:57 +00:00
Ignored when ` nixpkgs . pkgs ` , ` nixpkgs . localSystem ` or ` nixpkgs . hostPlatform ` is set .
2020-04-24 23:36:52 +00:00
'' ;
} ;
} ;
config = {
_module . args = {
2023-07-15 17:15:38 +00:00
pkgs =
# We explicitly set the default override priority, so that we do not need
# to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`.
# After all, to determine a definition priority, we need to evaluate `._type`,
# which is somewhat costly for Nixpkgs. With an explicit priority, we only
# evaluate the wrapper to find out that the priority is lower, and then we
# don't need to evaluate `finalPkgs`.
lib . mkOverride lib . modules . defaultOverridePriority
finalPkgs . __splicedPackages ;
2020-04-24 23:36:52 +00:00
} ;
2023-07-15 17:15:38 +00:00
assertions = let
# Whether `pkgs` was constructed by this module. This is false when any of
# nixpkgs.pkgs or _module.args.pkgs is set.
constructedByMe =
# We set it with default priority and it can not be merged, so if the
# pkgs module argument has that priority, it's from us.
( lib . modules . mergeAttrDefinitionsWithPrio options . _module . args ) . pkgs . highestPrio
== lib . modules . defaultOverridePriority
# Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it.
&& ! opt . pkgs . isDefined ;
in [
2020-04-24 23:36:52 +00:00
(
let
nixosExpectedSystem =
if config . nixpkgs . crossSystem != null
then config . nixpkgs . crossSystem . system or ( lib . systems . parse . doubleFromSystem ( lib . systems . parse . mkSystemFromString config . nixpkgs . crossSystem . config ) )
else config . nixpkgs . localSystem . system or ( lib . systems . parse . doubleFromSystem ( lib . systems . parse . mkSystemFromString config . nixpkgs . localSystem . config ) ) ;
nixosOption =
if config . nixpkgs . crossSystem != null
then " n i x p k g s . c r o s s S y s t e m "
else " n i x p k g s . l o c a l S y s t e m " ;
pkgsSystem = finalPkgs . stdenv . targetPlatform . system ;
in {
2022-10-30 15:09:59 +00:00
assertion = constructedByMe -> ! hasPlatform -> nixosExpectedSystem == pkgsSystem ;
2020-04-24 23:36:52 +00:00
message = " T h e N i x O S n i x p k g s . p k g s o p t i o n w a s s e t t o a N i x p k g s i n v o c a t i o n t h a t c o m p i l e s t o t a r g e t s y s t e m ${ pkgsSystem } b u t N i x O S w a s c o n f i g u r e d f o r s y s t e m ${ nixosExpectedSystem } v i a N i x O S o p t i o n ${ nixosOption } . T h e N i x O S s y s t e m s e t t i n g s m u s t m a t c h t h e N i x p k g s t a r g e t s y s t e m . " ;
}
)
2022-06-26 10:26:21 +00:00
{
2022-10-21 18:38:19 +00:00
assertion = constructedByMe -> hasPlatform -> legacyOptionsDefined == [ ] ;
2022-06-26 10:26:21 +00:00
message = ''
2024-09-19 14:19:46 +00:00
Your system configures nixpkgs with the platform parameter $ { lib . optionalString hasBuildPlatform " s " }:
2022-06-26 10:26:21 +00:00
$ { hostPlatformLine
} $ { buildPlatformLine
}
However , it also defines the legacy options :
2024-09-19 14:19:46 +00:00
$ { lib . concatMapStrings lib . showOptionWithDefLocs legacyOptionsDefined }
2022-06-26 10:26:21 +00:00
For a future proof system configuration , we recommend to remove
the legacy definitions .
'' ;
}
2023-10-09 19:29:22 +00:00
{
assertion = opt . pkgs . isDefined -> cfg . config == { } ;
message = ''
Your system configures nixpkgs with an externally created instance .
` nixpkgs . config ` options should be passed when creating the instance instead .
Current value :
2024-09-26 11:04:55 +00:00
$ { lib . generators . toPretty { multiline = true ; } cfg . config }
Defined in :
$ { lib . concatMapStringsSep " \n " ( file : " - ${ file } " ) opt . config . files }
2023-10-09 19:29:22 +00:00
'' ;
}
2020-04-24 23:36:52 +00:00
] ;
} ;
2022-01-07 04:07:37 +00:00
# needs a full nixpkgs path to import nixpkgs
meta . buildDocsInSandbox = false ;
2020-04-24 23:36:52 +00:00
}