@@ -9,7 +9,6 @@ let
assertMsg
attrNames
boolToString
chooseDevOutputs
concatLists
concatMap
concatMapStrings
@@ -19,7 +18,7 @@ let
extendDerivation
filter
findFirst
flip
getDev
head
imap1
isAttrs
@@ -40,6 +39,15 @@ let
unique
;
inherit ( import ../../build-support/lib/cmake.nix { inherit lib stdenv ; } ) makeCMakeFlags ;
inherit ( import ../../build-support/lib/meson.nix { inherit lib stdenv ; } ) makeMesonFlags ;
mkDerivation =
fnOrAttrs :
if builtins . isFunction fnOrAttrs
then makeDerivationExtensible fnOrAttrs
else makeDerivationExtensibleConst fnOrAttrs ;
checkMeta = import ./check-meta.nix {
inherit lib config ;
# Nix itself uses the `system` field of a derivation to decide where
@@ -102,11 +110,42 @@ let
makeDerivationExtensible ( self : attrs // ( if builtins . isFunction f0 || f0 ? __functor then f self attrs else f0 ) ) )
attrs ;
mkDerivationSimple = overrideAttrs :
knownHardeningFlags = [
" b i n d n o w "
" f o r m a t "
" f o r t i f y "
" f o r t i f y 3 "
" p i c "
" p i e "
" r e l r o "
" s t a c k p r o t e c t o r "
" s t r i c t o v e r f l o w "
" t r i v i a l a u t o v a r i n i t "
" z e r o c a l l u s e d r e g s "
] ;
removedOrReplacedAttrNames = [
" c h e c k I n p u t s " " i n s t a l l C h e c k I n p u t s "
" n a t i v e C h e c k I n p u t s " " n a t i v e I n s t a l l C h e c k I n p u t s "
" _ _ c o n t e n t A d d r e s s e d "
" _ _ d a r w i n A l l o w L o c a l N e t w o r k i n g "
" _ _ i m p u r e H o s t D e p s " " _ _ p r o p a g a t e d I m p u r e H o s t D e p s "
" s a n d b o x P r o f i l e " " p r o p a g a t e d S a n d b o x P r o f i l e "
] ;
# Turn a derivation into its outPath without a string context attached.
# See the comment at the usage site.
unsafeDerivationToUntrackedOutpath = drv :
if isDerivation drv
then builtins . unsafeDiscardStringContext drv . outPath
else drv ;
makeDerivationArgument =
# `mk Derivation` wraps the builtin `derivation` function to
# produce derivations that use this stdenv and its shell.
# `make DerivationArgument` is responsible for the `mkDerivation` arguments that
# affect the actual derivation, excluding a few behaviors that are not
# essential, and specific to `mkDerivation`: `env`, `cmakeFlags`, `mesonFlags`.
#
# See also:
#
@@ -146,8 +185,6 @@ let
# Configure Phase
, configureFlags ? [ ]
, cmakeFlags ? [ ]
, mesonFlags ? [ ]
, # Target is not included by default because most programs don't care.
# Including it then would cause needless mass rebuilds.
#
@@ -169,14 +206,6 @@ let
, enableParallelBuilding ? config . enableParallelBuildingByDefault
, meta ? { }
, passthru ? { }
, pos ? # position used in error messages and for meta.position
( if attrs . meta . description or null != null
then builtins . unsafeGetAttrPos " d e s c r i p t i o n " attrs . meta
else if attrs . version or null != null
then builtins . unsafeGetAttrPos " v e r s i o n " attrs
else builtins . unsafeGetAttrPos " n a m e " attrs )
, separateDebugInfo ? false
, outputs ? [ " o u t " ]
, __darwinAllowLocalNetworking ? false
@@ -198,8 +227,6 @@ let
# but for anything complex, be prepared to debug if enabling.
, __structuredAttrs ? config . structuredAttrsByDefault or false
, env ? { }
, . . . } @ attrs :
# Policy on acceptable hash types in nixpkgs
@@ -222,13 +249,6 @@ let
separateDebugInfo' = separateDebugInfo && stdenv . hostPlatform . isLinux ;
outputs' = outputs ++ optional separateDebugInfo' " d e b u g " ;
# Turn a derivation into its outPath without a string context attached.
# See the comment at the usage site.
unsafeDerivationToUntrackedOutpath = drv :
if isDerivation drv
then builtins . unsafeDiscardStringContext drv . outPath
else drv ;
noNonNativeDeps = builtins . length ( depsBuildTarget ++ depsBuildTargetPropagated
++ depsHostHost ++ depsHostHostPropagated
++ buildInputs ++ propagatedBuildInputs
@@ -239,19 +259,6 @@ let
# disabling fortify implies fortify3 should also be disabled
then unique ( hardeningDisable ++ [ " f o r t i f y 3 " ] )
else hardeningDisable ;
knownHardeningFlags = [
" b i n d n o w "
" f o r m a t "
" f o r t i f y "
" f o r t i f y 3 "
" p i c "
" p i e "
" r e l r o "
" s t a c k p r o t e c t o r "
" s t r i c t o v e r f l o w "
" t r i v i a l a u t o v a r i n i t "
" z e r o c a l l u s e d r e g s "
] ;
defaultHardeningFlags =
( if stdenv . hasCC then stdenv . cc else { } ) . defaultHardeningFlags or
# fallback safe-ish set of flags
@@ -264,10 +271,13 @@ let
erroneousHardeningFlags = subtractLists knownHardeningFlags ( hardeningEnable ++ remove " a l l " hardeningDisable ) ;
checkDependencyList = checkDependencyList' [ ] ;
checkDependencyList' = positions : name : deps : flip imap1 deps ( index : dep :
if isDerivation dep || dep = = null || builtins . isString dep || builtins . isPath dep then dep
else if isList dep then checkDependencyList' ( [ index ] ++ positions ) name dep
else throw " D e p e n d e n c y i s n o t o f a v a l i d t y p e : ${ concatMapStrings ( ix : " e l e m e n t ${ toString ix } o f " ) ( [ index ] ++ positions ) } ${ name } f o r ${ attrs . name or attrs . pname } " ) ;
checkDependencyList' = positions : name : deps :
imap1
( index : dep :
if isDerivation dep || dep = = null || builtins . isString dep || builtins . isPath dep then dep
else if isList dep then checkDependencyList' ( [ index ] ++ positions ) name dep
else throw " D e p e n d e n c y i s n o t o f a v a l i d t y p e : ${ concatMapStrings ( ix : " e l e m e n t ${ toString ix } o f " ) ( [ index ] ++ positions ) } ${ name } f o r ${ attrs . name or attrs . pname } " )
deps ;
in if builtins . length erroneousHardeningFlags != 0
then abort ( " m k D e r i v a t i o n w a s c a l l e d w i t h u n s u p p o r t e d h a r d e n i n g f l a g s : " + lib . generators . toPretty { } {
inherit erroneousHardeningFlags hardeningDisable hardeningEnable knownHardeningFlags ;
@@ -286,70 +296,37 @@ else let
outputs = outputs' ;
references = nativeBuildInputs ++ buildInputs
++ propagatedNativeBuildInputs ++ propagatedBuildInputs ;
dependencies = map ( map chooseDevOutputs ) [
dependencies = [
[
( map ( drv : drv . __spliced . buildBuild or drv ) ( checkDependencyList " d e p s B u i l d B u i l d " depsBuildBuild ) )
( map ( drv : drv . __spliced . buildHost or drv ) ( checkDependencyList " n a t i v e B u i l d I n p u t s " nativeBuildInputs' ) )
( map ( drv : drv . __spliced . buildTarget or drv ) ( checkDependencyList " d e p s B u i l d T a r g e t " depsBuildTarget ) )
( map ( drv : getDev drv . __spliced . buildBuild or drv ) ( checkDependencyList " d e p s B u i l d B u i l d " depsBuildBuild ) )
( map ( drv : getDev drv . __spliced . buildHost or drv ) ( checkDependencyList " n a t i v e B u i l d I n p u t s " nativeBuildInputs' ) )
( map ( drv : getDev drv . __spliced . buildTarget or drv ) ( checkDependencyList " d e p s B u i l d T a r g e t " depsBuildTarget ) )
]
[
( map ( drv : drv . __spliced . hostHost or drv ) ( checkDependencyList " d e p s H o s t H o s t " depsHostHost ) )
( map ( drv : drv . __spliced . hostTarget or drv ) ( checkDependencyList " b u i l d I n p u t s " buildInputs' ) )
( map ( drv : getDev drv . __spliced . hostHost or drv ) ( checkDependencyList " d e p s H o s t H o s t " depsHostHost ) )
( map ( drv : getDev drv . __spliced . hostTarget or drv ) ( checkDependencyList " b u i l d I n p u t s " buildInputs' ) )
]
[
( map ( drv : drv . __spliced . targetTarget or drv ) ( checkDependencyList " d e p s T a r g e t T a r g e t " depsTargetTarget ) )
( map ( drv : getDev drv . __spliced . targetTarget or drv ) ( checkDependencyList " d e p s T a r g e t T a r g e t " depsTargetTarget ) )
]
] ;
propagatedDependencies = map ( map chooseDevOutputs ) [
propagatedDependencies = [
[
( map ( drv : drv . __spliced . buildBuild or drv ) ( checkDependencyList " d e p s B u i l d B u i l d P r o p a g a t e d " depsBuildBuildPropagated ) )
( map ( drv : drv . __spliced . buildHost or drv ) ( checkDependencyList " p r o p a g a t e d N a t i v e B u i l d I n p u t s " propagatedNativeBuildInputs ) )
( map ( drv : drv . __spliced . buildTarget or drv ) ( checkDependencyList " d e p s B u i l d T a r g e t P r o p a g a t e d " depsBuildTargetPropagated ) )
( map ( drv : getDev drv . __spliced . buildBuild or drv ) ( checkDependencyList " d e p s B u i l d B u i l d P r o p a g a t e d " depsBuildBuildPropagated ) )
( map ( drv : getDev drv . __spliced . buildHost or drv ) ( checkDependencyList " p r o p a g a t e d N a t i v e B u i l d I n p u t s " propagatedNativeBuildInputs ) )
( map ( drv : getDev drv . __spliced . buildTarget or drv ) ( checkDependencyList " d e p s B u i l d T a r g e t P r o p a g a t e d " depsBuildTargetPropagated ) )
]
[
( map ( drv : drv . __spliced . hostHost or drv ) ( checkDependencyList " d e p s H o s t H o s t P r o p a g a t e d " depsHostHostPropagated ) )
( map ( drv : drv . __spliced . hostTarget or drv ) ( checkDependencyList " p r o p a g a t e d B u i l d I n p u t s " propagatedBuildInputs ) )
( map ( drv : getDev drv . __spliced . hostHost or drv ) ( checkDependencyList " d e p s H o s t H o s t P r o p a g a t e d " depsHostHostPropagated ) )
( map ( drv : getDev drv . __spliced . hostTarget or drv ) ( checkDependencyList " p r o p a g a t e d B u i l d I n p u t s " propagatedBuildInputs ) )
]
[
( map ( drv : drv . __spliced . targetTarget or drv ) ( checkDependencyList " d e p s T a r g e t T a r g e t P r o p a g a t e d " depsTargetTargetPropagated ) )
( map ( drv : getDev drv . __spliced . targetTarget or drv ) ( checkDependencyList " d e p s T a r g e t T a r g e t P r o p a g a t e d " depsTargetTargetPropagated ) )
]
] ;
computedSandboxProfile =
concatMap ( input : input . __propagatedSandboxProfile or [ ] )
( stdenv . extraNativeBuildInputs
++ stdenv . extraBuildInputs
++ concatLists dependencies ) ;
computedPropagatedSandboxProfile =
concatMap ( input : input . __propagatedSandboxProfile or [ ] )
( concatLists propagatedDependencies ) ;
computedImpureHostDeps =
unique ( concatMap ( input : input . __propagatedImpureHostDeps or [ ] )
( stdenv . extraNativeBuildInputs
++ stdenv . extraBuildInputs
++ concatLists dependencies ) ) ;
computedPropagatedImpureHostDeps =
unique ( concatMap ( input : input . __propagatedImpureHostDeps or [ ] )
( concatLists propagatedDependencies ) ) ;
envIsExportable = isAttrs env && ! isDerivation env ;
derivationArg =
( removeAttrs attrs
( [ " m e t a " " p a s s t h r u " " p o s "
" c h e c k I n p u t s " " i n s t a l l C h e c k I n p u t s "
" n a t i v e C h e c k I n p u t s " " n a t i v e I n s t a l l C h e c k I n p u t s "
" _ _ c o n t e n t A d d r e s s e d "
" _ _ d a r w i n A l l o w L o c a l N e t w o r k i n g "
" _ _ i m p u r e H o s t D e p s " " _ _ p r o p a g a t e d I m p u r e H o s t D e p s "
" s a n d b o x P r o f i l e " " p r o p a g a t e d S a n d b o x P r o f i l e " ]
++ optional ( __structuredAttrs || envIsExportable ) " e n v " ) )
removeAttrs attrs removedOrReplacedAttrNames
// ( optionalAttrs ( attrs ? name || ( attrs ? pname && attrs ? version ) ) {
name =
let
@@ -377,7 +354,7 @@ else let
assert assertMsg ( attrs ? version && attrs . version != null ) " T h e ‘ v e r s i o n ’ a t t r i b u t e c a n n o t b e n u l l . " ;
" ${ attrs . pname } ${ staticMarker } ${ hostSuffix } - ${ attrs . version } "
) ;
} ) // optionalAttrs __structuredAttrs { env = checkedEnv ; } // {
} ) // {
builder = attrs . realBuilder or stdenv . shell ;
args = attrs . args or [ " - e " ( attrs . builder or ./default-builder.sh ) ] ;
inherit stdenv ;
@@ -415,54 +392,6 @@ else let
++ optional ( elem " h o s t " configurePlatforms ) " - - h o s t = ${ stdenv . hostPlatform . config } "
++ optional ( elem " t a r g e t " configurePlatforms ) " - - t a r g e t = ${ stdenv . targetPlatform . config } " ;
cmakeFlags =
cmakeFlags
++ optionals ( stdenv . hostPlatform != stdenv . buildPlatform ) ( [
" - D C M A K E _ S Y S T E M _ N A M E = ${ findFirst isString " G e n e r i c " ( optional ( ! stdenv . hostPlatform . isRedox ) stdenv . hostPlatform . uname . system ) } "
] ++ optionals ( stdenv . hostPlatform . uname . processor != null ) [
" - D C M A K E _ S Y S T E M _ P R O C E S S O R = ${ stdenv . hostPlatform . uname . processor } "
] ++ optionals ( stdenv . hostPlatform . uname . release != null ) [
" - D C M A K E _ S Y S T E M _ V E R S I O N = ${ stdenv . hostPlatform . uname . release } "
] ++ optionals ( stdenv . hostPlatform . isDarwin ) [
" - D C M A K E _ O S X _ A R C H I T E C T U R E S = ${ stdenv . hostPlatform . darwinArch } "
] ++ optionals ( stdenv . buildPlatform . uname . system != null ) [
" - D C M A K E _ H O S T _ S Y S T E M _ N A M E = ${ stdenv . buildPlatform . uname . system } "
] ++ optionals ( stdenv . buildPlatform . uname . processor != null ) [
" - D C M A K E _ H O S T _ S Y S T E M _ P R O C E S S O R = ${ stdenv . buildPlatform . uname . processor } "
] ++ optionals ( stdenv . buildPlatform . uname . release != null ) [
" - D C M A K E _ H O S T _ S Y S T E M _ V E R S I O N = ${ stdenv . buildPlatform . uname . release } "
] ++ optionals ( stdenv . buildPlatform . canExecute stdenv . hostPlatform ) [
" - D C M A K E _ C R O S S C O M P I L I N G _ E M U L A T O R = e n v "
] ++ lib . optionals stdenv . hostPlatform . isStatic [
" - D C M A K E _ L I N K _ S E A R C H _ S T A R T _ S T A T I C = O N "
] ) ;
mesonFlags =
let
# See https://mesonbuild.com/Reference-tables.html#cpu-families
cpuFamily = platform : with platform ;
/* */ if isAarch32 then " a r m "
else if isx86_32 then " x 8 6 "
else platform . uname . processor ;
crossFile = builtins . toFile " c r o s s - f i l e . c o n f " ''
[ p r o p e r t i e s ]
b i n d g e n _ c l a n g _ a r g u m e n t s = [ ' - t a r g e t ' , ' ${ stdenv . targetPlatform . config } ' ]
n e e d s _ e x e _ w r a p p e r = ${ boolToString ( ! stdenv . buildPlatform . canExecute stdenv . hostPlatform ) }
[ h o s t _ m a c h i n e ]
s y s t e m = ' ${ stdenv . targetPlatform . parsed . kernel . name } '
c p u _ f a m i l y = ' ${ cpuFamily stdenv . targetPlatform } '
c p u = ' ${ stdenv . targetPlatform . parsed . cpu . name } '
e n d i a n = ${ if stdenv . targetPlatform . isLittleEndian then " ' l i t t l e ' " else " ' b i g ' " }
[ b i n a r i e s ]
l l v m - c o n f i g = ' l l v m - c o n f i g - n a t i v e '
r u s t = [ ' r u s t c ' , ' - - t a r g e t ' , ' ${ stdenv . targetPlatform . rust . rustcTargetSpec } ' ]
'' ;
crossFlags = optionals ( stdenv . hostPlatform != stdenv . buildPlatform ) [ " - - c r o s s - f i l e = ${ crossFile } " ] ;
in crossFlags ++ mesonFlags ;
inherit patches ;
inherit doCheck doInstallCheck ;
@@ -482,7 +411,28 @@ else let
NIX_HARDENING_ENABLE = enabledHardeningOptions ;
} // optionalAttrs ( stdenv . hostPlatform . isx86_64 && stdenv . hostPlatform ? gcc . arch ) {
requiredSystemFeatures = attrs . requiredSystemFeatures or [ ] ++ [ " g c c a r c h - ${ stdenv . hostPlatform . gcc . arch } " ] ;
} // optionalAttrs ( stdenv . buildPlatform . isDarwin ) {
} // optionalAttrs ( stdenv . buildPlatform . isDarwin ) (
let
computedSandboxProfile =
concatMap ( input : input . __propagatedSandboxProfile or [ ] )
( stdenv . extraNativeBuildInputs
++ stdenv . extraBuildInputs
++ concatLists dependencies ) ;
computedPropagatedSandboxProfile =
concatMap ( input : input . __propagatedSandboxProfile or [ ] )
( concatLists propagatedDependencies ) ;
computedImpureHostDeps =
unique ( concatMap ( input : input . __propagatedImpureHostDeps or [ ] )
( stdenv . extraNativeBuildInputs
++ stdenv . extraBuildInputs
++ concatLists dependencies ) ) ;
computedPropagatedImpureHostDeps =
unique ( concatMap ( input : input . __propagatedImpureHostDeps or [ ] )
( concatLists propagatedDependencies ) ) ;
in {
inherit __darwinAllowLocalNetworking ;
# TODO: remove `unique` once nix has a list canonicalization primitive
__sandboxProfile =
@@ -497,7 +447,7 @@ else let
" / b i n / s h "
] ;
__propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ;
} //
} ) //
# If we use derivations directly here, they end up as build-time dependencies.
# This is especially problematic in the case of disallowed*, since the disallowed
# derivations will be built by nix as build-time dependencies, while those
@@ -533,7 +483,82 @@ else let
mapNullable unsafeDerivationToUntrackedOutpath attrs . allowedRequisites ;
} ;
meta = checkMeta . commonMeta { inherit validity attrs pos references ; } ;
in
derivationArg ;
mkDerivationSimple = overrideAttrs :
# `mkDerivation` wraps the builtin `derivation` function to
# produce derivations that use this stdenv and its shell.
#
# Internally, it delegates most of its behavior to `makeDerivationArgument`,
# except for the `env`, `cmakeFlags`, and `mesonFlags` attributes, as well
# as the attributes `meta` and `passthru` that affect [package attributes],
# and not the derivation itself.
#
# See also:
#
# * https://nixos.org/nixpkgs/manual/#sec-using-stdenv
# Details on how to use this mkDerivation function
#
# * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations
# Explanation about derivations in general
#
# * [package attributes]: https://nixos.org/manual/nix/stable/glossary#package-attribute-set
{
# Configure Phase
cmakeFlags ? [ ]
, mesonFlags ? [ ]
, meta ? { }
, passthru ? { }
, pos ? # position used in error messages and for meta.position
( if attrs . meta . description or null != null
then builtins . unsafeGetAttrPos " d e s c r i p t i o n " attrs . meta
else if attrs . version or null != null
then builtins . unsafeGetAttrPos " v e r s i o n " attrs
else builtins . unsafeGetAttrPos " n a m e " attrs )
# Experimental. For simple packages mostly just works,
# but for anything complex, be prepared to debug if enabling.
, __structuredAttrs ? config . structuredAttrsByDefault or false
, env ? { }
, . . . } @ attrs :
# Policy on acceptable hash types in nixpkgs
assert attrs ? outputHash -> (
let algo =
attrs . outputHashAlgo or ( head ( splitString " - " attrs . outputHash ) ) ;
in
if algo = = " m d 5 " then
throw " R e j e c t e d i n s e c u r e ${ algo } h a s h ' ${ attrs . outputHash } ' "
else
true
) ;
let
envIsExportable = isAttrs env && ! isDerivation env ;
derivationArg = makeDerivationArgument
( removeAttrs
attrs
( [ " m e t a " " p a s s t h r u " " p o s " ]
++ optional ( __structuredAttrs || envIsExportable ) " e n v "
)
// optionalAttrs __structuredAttrs { env = checkedEnv ; }
// {
cmakeFlags = makeCMakeFlags attrs ;
mesonFlags = makeMesonFlags attrs ;
} ) ;
meta = checkMeta . commonMeta {
inherit validity attrs pos ;
references = attrs . nativeBuildInputs ++ attrs . buildInputs
++ attrs . propagatedNativeBuildInputs ++ attrs . propagatedBuildInputs ;
} ;
validity = checkMeta . assertValidity { inherit meta attrs ; } ;
checkedEnv =
@@ -603,7 +628,6 @@ extendDerivation
( derivation ( derivationArg // optionalAttrs envIsExportable checkedEnv ) ) ;
in
fnOrAttrs :
if builtins . isFunction fnOrAttrs
then makeDerivationExtensible fnOrAttrs
else makeDerivationExtensibleConst fnOrAttrs
{
inherit mkDerivation ;
}