2023-07-07 09:02:38 +01:00
{
config ,
options ,
lib ,
pkgs ,
. . .
} :
2016-12-11 16:24:37 +01:00
let
2023-07-07 09:02:38 +01:00
cfg = config . nixpkgs ;
opt = options . nixpkgs ;
2021-12-07 13:48:40 -08:00
isConfig = x : builtins . isAttrs x || lib . isFunction x ;
2016-12-11 16:24:37 +01:00
2021-12-07 13:48:40 -08:00
optCall = f : x : if lib . isFunction f then f x else f ;
2016-12-11 16:24:37 +01:00
mergeConfig =
lhs_ : rhs_ :
let
lhs = optCall lhs_ { inherit pkgs ; } ;
rhs = optCall rhs_ { inherit pkgs ; } ;
in
2025-02-03 19:26:13 +00:00
lib . recursiveUpdate lhs rhs
// lib . optionalAttrs ( lhs ? packageOverrides ) {
2016-12-11 16:24:37 +01:00
packageOverrides =
pkgs :
2025-02-03 19:26:13 +00:00
optCall lhs . packageOverrides pkgs // optCall ( lib . 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
}
2025-02-03 19:26:13 +00:00
// lib . optionalAttrs ( lhs ? perlPackageOverrides ) {
2016-12-11 16:24:37 +01:00
perlPackageOverrides =
pkgs :
optCall lhs . perlPackageOverrides pkgs
2025-02-03 19:26:13 +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 ;
2016-12-11 16:24:37 +01:00
} ;
2025-02-03 19:26:13 +00:00
configType = lib . 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 ;
2025-02-03 19:26:13 +00:00
merge = args : lib . foldr ( def : mergeConfig def . value ) { } ;
2016-12-11 16:24:37 +01:00
} ;
2025-02-03 19:26:13 +00:00
overlayType = lib . mkOptionType {
2018-01-06 23:20:43 +01: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 " ;
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
2025-02-03 19:26:13 +00:00
pkgsType = lib . 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 " ;
} ;
2025-02-03 19:26:13 +00:00
hasBuildPlatform = opt . buildPlatform . highestPrio < ( lib . mkOptionDefault { } ) . priority ;
2023-07-07 09:02:38 +01:00
hasHostPlatform = opt . hostPlatform . isDefined ;
hasPlatform = hasHostPlatform || hasBuildPlatform ;
# Context for messages
2025-02-03 19:26:13 +00:00
hostPlatformLine = lib . optionalString hasHostPlatform " ${ lib . showOptionWithDefLocs opt . hostPlatform } " ;
buildPlatformLine = lib . optionalString hasBuildPlatform " ${ lib . showOptionWithDefLocs opt . buildPlatform } " ;
2023-07-07 09:02:38 +01:00
legacyOptionsDefined = lib . optional (
2025-02-03 19:26:13 +00:00
opt . system . highestPrio < ( lib . mkDefault { } ) . priority
) opt . system ;
2023-07-07 09:02:38 +01:00
defaultPkgs =
if opt . hostPlatform . isDefined then
let
2025-02-03 19:40:03 +00:00
isCross =
! ( lib . systems . equals ( lib . systems . elaborate cfg . buildPlatform ) (
lib . systems . elaborate cfg . hostPlatform
) ) ;
2023-07-07 09:02:38 +01:00
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 = {
2025-02-03 19:26:13 +00:00
pkgs = lib . mkOption {
2023-07-07 09:02:38 +01:00
type = pkgsType ;
2025-02-03 19:26:13 +00:00
example = lib . 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 ` .
'' ;
} ;
2025-02-03 19:26:13 +00:00
config = lib . mkOption {
2016-12-11 16:24:37 +01:00
default = { } ;
2025-02-03 19:26:13 +00:00
example = lib . literalExpression ''
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
} ;
2025-02-03 19:26:13 +00:00
overlays = lib . mkOption {
2018-01-06 23:20:43 +01:00
default = [ ] ;
2025-02-03 19:26:13 +00:00
example = lib . literalExpression ''
2023-07-07 09:02:38 +01:00
[
( self : super : {
openssh = super . openssh . override {
hpnSupport = true ;
kerberos = self . libkrb5 ;
} ;
} )
]
'' ;
2025-02-03 19:26:13 +00:00
type = lib . 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
'' ;
} ;
2025-02-03 19:26:13 +00:00
hostPlatform = lib . mkOption {
2025-02-03 19:40:03 +00:00
type = lib . types . either lib . types . str lib . types . attrs ;
2025-02-03 19:32:13 +00:00
example = {
system = " a a r c h 6 4 - d a r w i n " ;
} ;
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 .
'' ;
} ;
2025-02-03 19:26:13 +00:00
buildPlatform = lib . mkOption {
2025-02-03 19:40:03 +00:00
type = lib . types . either lib . types . str lib . types . attrs ;
2023-07-07 09:02:38 +01:00
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:26:13 +00:00
defaultText = lib . 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
'' ;
} ;
2025-02-03 19:26:13 +00:00
system = lib . mkOption {
type = lib . types . str ;
2018-01-06 23:20:43 +01:00
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
2025-02-03 19:26:13 +00:00
source = lib . mkOption {
type = lib . types . path ;
defaultText = lib . literalMD ''
2023-07-07 09:02:38 +01:00
` <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 )
'' ;
} ;
2025-02-03 19:26:13 +00:00
constructedByUs = lib . mkOption {
type = lib . types . bool ;
2023-07-07 09:02:38 +01:00
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 finalPkgs . __splicedPackages ;
2023-07-07 09:02:38 +01:00
} ;
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 = ''
2025-02-03 19:26:13 +00:00
Your system configures nixpkgs with the platform parameter $ { lib . optionalString hasBuildPlatform " s " }:
2023-07-07 09:02:38 +01:00
$ { hostPlatformLine } $ { buildPlatformLine }
However , it also defines the legacy options :
2025-02-03 19:26:13 +00:00
$ { lib . concatMapStrings lib . showOptionWithDefLocs legacyOptionsDefined }
2023-07-07 09:02:38 +01:00
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 :
2025-02-03 19:35:53 +00:00
$ { lib . generators . toPretty { multiline = true ; } cfg . config }
2025-02-03 19:36:42 +00:00
Defined in :
$ { lib . concatMapStringsSep " \n " ( file : " - ${ file } " ) opt . config . files }
2025-02-03 19:29:03 +00:00
'' ;
}
2025-02-03 19:40:03 +00:00
{
assertion =
( opt . hostPlatform . isDefined -> builtins . isAttrs cfg . buildPlatform -> ! ( cfg . buildPlatform ? parsed ) )
&& ( opt . hostPlatform . isDefined -> builtins . isAttrs cfg . hostPlatform -> ! ( cfg . hostPlatform ? parsed ) ) ;
message = ''
Passing fully elaborated systems to ` nixpkgs . localSystem ` , ` nixpkgs . crossSystem ` , ` nixpkgs . buildPlatform `
or ` nixpkgs . hostPlatform ` will break composability of package sets in nixpkgs . For example , pkgs . pkgsStatic
would not work in modules anymore .
'' ;
}
2023-07-07 09:02:38 +01:00
] ;
2016-12-11 16:24:37 +01:00
} ;
}