2023-07-07 09:02:38 +01:00
{ config , options , lib , pkgs , . . . }:
2016-12-11 16:24:37 +01:00
with lib ;
let
2023-07-07 09:02:38 +01:00
cfg = config . nixpkgs ;
opt = options . nixpkgs ;
2016-12-11 16:24:37 +01:00
isConfig = x :
2021-12-07 13:48:40 -08:00
builtins . isAttrs x || lib . isFunction x ;
2016-12-11 16:24:37 +01:00
optCall = f : x :
2021-12-07 13:48:40 -08:00
if lib . isFunction f
2016-12-11 16:24:37 +01:00
then f x
else f ;
mergeConfig = lhs_ : rhs_ :
let
lhs = optCall lhs_ { inherit pkgs ; } ;
rhs = optCall rhs_ { inherit pkgs ; } ;
in
2023-07-07 09:02:38 +01:00
recursiveUpdate lhs rhs //
2016-12-11 16:24:37 +01:00
optionalAttrs ( lhs ? packageOverrides ) {
packageOverrides = pkgs :
optCall lhs . packageOverrides pkgs //
2023-07-07 09:02:38 +01:00
optCall ( attrByPath [ " p a c k a g e O v e r r i d e s " ] { } rhs ) pkgs ;
2016-12-11 16:24:37 +01:00
} //
optionalAttrs ( lhs ? perlPackageOverrides ) {
perlPackageOverrides = pkgs :
optCall lhs . perlPackageOverrides pkgs //
2023-07-07 09:02:38 +01:00
optCall ( attrByPath [ " p e r l P a c k a g e O v e r r i d e s " ] { } rhs ) pkgs ;
2016-12-11 16:24:37 +01:00
} ;
configType = mkOptionType {
2023-07-07 09:02:38 +01: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 " ;
2018-05-04 19:12:43 +02:00
check = x :
let traceXIfNot = c :
if c x then true
else lib . traceSeqN 1 x false ;
in traceXIfNot isConfig ;
2023-07-07 09:02:38 +01:00
merge = args : foldr ( def : mergeConfig def . value ) { } ;
2016-12-11 16:24:37 +01:00
} ;
2018-01-06 23:20:43 +01:00
overlayType = mkOptionType {
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 " ;
2021-12-07 13:48:40 -08:00
check = lib . isFunction ;
2018-01-06 23:20:43 +01:00
merge = lib . mergeOneOption ;
} ;
2023-07-07 09:02:38 +01:00
2024-06-13 13:48:07 +01:00
pkgsType = types . pkgs // {
2023-07-07 09:02:38 +01:00
# This type is only used by itself, so let's elaborate the description a bit
# for the purpose of documentation.
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 " ;
} ;
hasBuildPlatform = opt . buildPlatform . highestPrio < ( mkOptionDefault { } ) . priority ;
hasHostPlatform = opt . hostPlatform . isDefined ;
hasPlatform = hasHostPlatform || hasBuildPlatform ;
# Context for messages
hostPlatformLine = optionalString hasHostPlatform " ${ showOptionWithDefLocs opt . hostPlatform } " ;
buildPlatformLine = optionalString hasBuildPlatform " ${ showOptionWithDefLocs opt . buildPlatform } " ;
legacyOptionsDefined =
optional ( opt . system . highestPrio < ( mkDefault { } ) . priority ) opt . system
;
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 cfg . source ( {
inherit ( cfg ) config overlays ;
} // systemArgs )
else
import cfg . source {
inherit ( cfg ) config overlays ;
localSystem = { inherit ( cfg ) system ; } ;
} ;
finalPkgs = if opt . pkgs . isDefined then cfg . pkgs . appendOverlays cfg . overlays else defaultPkgs ;
2016-12-11 16:24:37 +01:00
in
{
2023-07-07 09:02:38 +01:00
options . nixpkgs = {
pkgs = mkOption {
type = pkgsType ;
example = literalExpression " i m p o r t < n i x p k g s > { } " ;
2024-04-14 23:02:32 +02:00
description = ''
2023-07-07 09:02:38 +01:00
If set , the pkgs argument to all nix-darwin modules is the value of
this option , extended with ` nixpkgs . overlays ` , if
that is also set . The nix-darwin and Nixpkgs architectures must
match . Any other options in ` nixpkgs . * ` , notably ` config ` ,
will be ignored .
The default value imports the Nixpkgs from
[ ] ( #opt-nixpkgs.source). The `config`, `overlays`, `localSystem`,
and ` crossSystem ` are based on this option's siblings .
This option can be used 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
their default value using ` lib . mkDefault ` , so
user-provided configuration can override it without using
` lib ` .
'' ;
} ;
config = mkOption {
2016-12-11 16:24:37 +01:00
default = { } ;
2021-10-23 15:05:52 +02:00
example = literalExpression
2016-12-11 16:24:37 +01:00
''
2023-07-07 09:02:38 +01:00
{ allowBroken = true ; allowUnfree = true ; }
2016-12-11 16:24:37 +01:00
'' ;
type = configType ;
2024-04-14 23:02:32 +02:00
description = ''
2025-02-03 19:34:11 +00:00
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).
2023-07-07 09:02:38 +01:00
2025-02-03 19:34:11 +00:00
Ignored when { option } ` nixpkgs . pkgs ` is set .
'' ;
2016-12-11 16:24:37 +01:00
} ;
2023-07-07 09:02:38 +01:00
overlays = mkOption {
2018-01-06 23:20:43 +01:00
default = [ ] ;
2023-07-07 09:02:38 +01:00
example = literalExpression
''
[
( self : super : {
openssh = super . openssh . override {
hpnSupport = true ;
kerberos = self . libkrb5 ;
} ;
} )
]
'' ;
type = types . listOf overlayType ;
2024-04-14 23:02:32 +02:00
description = ''
2025-02-03 19:31:14 +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 ` .
2023-07-07 09:02:38 +01:00
'' ;
} ;
hostPlatform = mkOption {
type = types . either types . str types . attrs ; # TODO utilize lib.systems.parsedPlatform
2025-02-03 19:32:13 +00:00
example = { system = " a a r c h 6 4 - d a r w i n " ; } ;
2023-07-07 09:02:38 +01: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-04-14 23:02:32 +02:00
description = ''
2023-07-07 09:02:38 +01:00
Specifies the platform where the nix-darwin configuration will run .
To cross-compile , set also ` nixpkgs . buildPlatform ` .
Ignored when ` nixpkgs . pkgs ` is set .
'' ;
} ;
buildPlatform = mkOption {
type = types . either types . str types . attrs ; # TODO utilize lib.systems.parsedPlatform
default = cfg . hostPlatform ;
2025-02-03 19:32:13 +00:00
example = { system = " x 8 6 _ 6 4 - d a r w i n " ; } ;
2023-07-07 09:02:38 +01:00
# Make sure that the final value has all fields for sake of other modules
# referring to this.
2025-02-03 19:33:20 +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 ;
2023-07-07 09:02:38 +01:00
defaultText = literalExpression
'' 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-14 23:02:32 +02:00
description = ''
2023-07-07 09:02:38 +01:00
Specifies the platform on which nix-darwin should be built .
By default , nix-darwin is built on the system where it runs , but you can
change where it's built . Setting this option will cause nix-darwin 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 .
Ignored when ` nixpkgs . pkgs ` is set .
2018-01-06 23:20:43 +01:00
'' ;
} ;
2023-07-07 09:02:38 +01:00
system = mkOption {
2018-01-06 23:20:43 +01:00
type = types . str ;
example = " x 8 6 _ 6 4 - d a r w i n " ;
2023-07-07 09:02:38 +01: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 ''
Neither $ { opt . hostPlatform } nor the legacy option $ { opt . system } has been set .
The option $ { opt . system } is still fully supported for 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 nix-darwin through ` lib . darwinSystem ` .
'' ;
2024-04-14 23:02:32 +02:00
description = ''
2023-07-07 09:02:38 +01:00
Specifies the Nix platform type on which nix-darwin should be built .
It is better to specify ` nixpkgs . hostPlatform ` instead .
Ignored when ` nixpkgs . pkgs ` or ` nixpkgs . hostPlatform ` is set .
'' ;
} ;
# nix-darwin only
source = mkOption {
type = types . path ;
defaultText = literalMD ''
` <nixpkgs> ` or nix-darwin's ` nixpkgs ` flake input
'' ;
2024-04-14 23:02:32 +02:00
description = ''
2023-07-07 09:02:38 +01:00
The path to import Nixpkgs from . If you're setting a custom
[ ] ( #opt-nixpkgs.pkgs) or `_module.args.pkgs`, setting this
to something with ` rev ` and ` shortRev ` attributes ( such as a
flake input or ` builtins . fetchGit ` result ) will also set
` system . nixpkgsRevision ` and related options .
( nix-darwin only )
'' ;
} ;
constructedByUs = mkOption {
type = types . bool ;
internal = true ;
description = ''
Whether ` pkgs ` was constructed by this module . This is false when any of
` nixpkgs . pkgs ` or ` _module . args . pkgs ` is set . ( nix-darwin only )
2018-01-06 23:20:43 +01:00
'' ;
} ;
2016-12-11 16:24:37 +01:00
} ;
config = {
2023-07-07 09:02:38 +01:00
_module . args = {
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`.
2024-06-13 13:48:07 +01:00
lib . mkOverride lib . modules . defaultOverridePriority
2023-07-07 09:02:38 +01:00
finalPkgs . __splicedPackages ;
} ;
2016-12-11 16:33:42 +01:00
2023-07-07 09:02:38 +01:00
nixpkgs . constructedByUs =
# 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.
2024-06-13 13:48:07 +01:00
( lib . modules . mergeAttrDefinitionsWithPrio options . _module . args ) . pkgs . highestPrio
= = lib . modules . defaultOverridePriority
2023-07-07 09:02:38 +01:00
# Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it.
&& ! opt . pkgs . isDefined ;
2016-12-11 16:33:42 +01:00
2023-07-07 09:02:38 +01:00
assertions = [
(
let
pkgsSystem = finalPkgs . stdenv . targetPlatform . system ;
in {
assertion = cfg . constructedByUs -> ! hasPlatform -> cfg . system = = pkgsSystem ;
2025-02-03 20:24:31 +00:00
message = " T h e n i x - d a r w i n 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 - d a r w i n w a s c o n f i g u r e d f o r s y s t e m ${ config . nixpkgs . system } v i a n i x - d a r w i n o p t i o n n i x p k g s . s y s t e m . T h e n i x - d a r w i n 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 . " ;
2023-07-07 09:02:38 +01:00
}
)
{
assertion = cfg . constructedByUs -> hasPlatform -> legacyOptionsDefined = = [ ] ;
message = ''
Your system configures nixpkgs with the platform parameter $ { optionalString hasBuildPlatform " s " }:
$ { hostPlatformLine
} $ { buildPlatformLine
}
However , it also defines the legacy options :
$ { concatMapStrings showOptionWithDefLocs legacyOptionsDefined }
For a future proof system configuration , we recommend to remove
the legacy definitions .
'' ;
}
2025-02-03 19:29:03 +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 :
$ { lib . generators . toPretty { multiline = true ; } opt . config }
'' ;
}
2023-07-07 09:02:38 +01:00
] ;
2016-12-11 16:24:37 +01:00
} ;
}