extendMkDerivation
lib.customisation.extendMkDerivation
Define a mkDerivation-like function based on another mkDerivation-like function.
stdenv.mkDerivation gives access to
its final set of derivation attributes when it is passed a function,
or when it is passed an overlay-style function in overrideAttrs.
Instead of composing new stdenv.mkDerivation-like build helpers
using normal function composition,
extendMkDerivation makes sure that the returned build helper
supports such first class recursion like mkDerivation does.
extendMkDerivation takes an extra attribute set to configure its behaviour.
One can optionally specify
transformDrv to specify a function to apply to the result derivation,
or inheritFunctionArgs to decide whether to inherit the __functionArgs
from the base build helper.
Inputs
extendMkDerivation-specific configurations-
constructDrv(required)- Base build helper, the
mkDerivation-like build helper to extend. excludeDrvArgNames(default to[ ])- Argument names not to pass from the input fixed-point arguments to
constructDrv. It doesn't apply to the updating arguments returned byextendDrvArgs. excludeFunctionArgNames(default to[ ])__functionArgsattribute names to remove from the result build helper.excludeFunctionArgNamesis useful for argument deprecation while avoiding ellipses.extendDrvArgs(required)- An extension (overlay) of the argument set, like the one taken by
overrideAttrsbut applied before passing toconstructDrv. inheritFunctionArgs(default totrue)- Whether to inherit
__functionArgsfrom the base build helper. SetinheritFunctionArgstofalsewhenextendDrvArgs'sargsset pattern does not contain an ellipsis. transformDrv(default tolib.id)- Function to apply to the result derivation.
Type
extendMkDerivation ::
{
constructDrv :: ((FixedPointArgs | AttrSet) -> a)
excludeDrvArgNames :: [ String ],
excludeFunctionArgNames :: [ String ]
extendDrvArgs :: (AttrSet -> AttrSet -> AttrSet)
inheritFunctionArgs :: Bool,
transformDrv :: a -> a,
}
-> (FixedPointArgs | AttrSet) -> a
FixedPointArgs = AttrSet -> AttrSet
a = Derivation when defining a build helper
Examples
lib.customisation.extendMkDerivation usage example
mkLocalDerivation = lib.extendMkDerivation {
constructDrv = pkgs.stdenv.mkDerivation;
excludeDrvArgNames = [ "specialArg" ];
extendDrvArgs =
finalAttrs: args@{ preferLocalBuild ? true, allowSubstitute ? false, specialArg ? (_: false), ... }:
{ inherit preferLocalBuild allowSubstitute; passthru = { inherit specialArg; } // args.passthru or { }; };
}
mkLocalDerivation.__functionArgs
=> { allowSubstitute = true; preferLocalBuild = true; specialArg = true; }
mkLocalDerivation { inherit (pkgs.hello) pname version src; specialArg = _: false; }
=> «derivation /nix/store/xirl67m60ahg6jmzicx43a81g635g8z8-hello-2.12.1.drv»
mkLocalDerivation (finalAttrs: { inherit (pkgs.hello) pname version src; specialArg = _: false; })
=> «derivation /nix/store/xirl67m60ahg6jmzicx43a81g635g8z8-hello-2.12.1.drv»
(mkLocalDerivation (finalAttrs: { inherit (pkgs.hello) pname version src; passthru = { foo = "a"; bar = "${finalAttrs.passthru.foo}b"; }; })).bar
=> "ab"
If transformDrv is specified,
it should take care of existing attributes that perform overriding
(e.g., overrideAttrs)
to ensure that the overriding functionality of the result derivation
work as expected.
Modifications that breaks the overriding include
direct attribute set update
and lib.extendDerivation.
Noogle detected
Implementation
The following is the current implementation of this function.
extendMkDerivation =
let
extendsWithExclusion =
excludedNames: g: f: final:
let
previous = f final;
in
removeAttrs previous excludedNames // g final previous;
in
{
constructDrv,
excludeDrvArgNames ? [ ],
excludeFunctionArgNames ? [ ],
extendDrvArgs,
inheritFunctionArgs ? true,
transformDrv ? id,
}:
setFunctionArgs
# Adds the fixed-point style support
(
fpargs:
transformDrv (
constructDrv (extendsWithExclusion excludeDrvArgNames extendDrvArgs (toFunction fpargs))
)
)
# Add __functionArgs
(
removeAttrs (
# Inherit the __functionArgs from the base build helper
optionalAttrs inheritFunctionArgs (removeAttrs (functionArgs constructDrv) excludeDrvArgNames)
# Recover the __functionArgs from the derived build helper
// functionArgs (extendDrvArgs { })
) excludeFunctionArgNames
)
// {
inherit
# Expose to the result build helper.
constructDrv
excludeDrvArgNames
extendDrvArgs
transformDrv
;
};