diff --git a/doc/build-helpers/fixed-point-arguments.chapter.md b/doc/build-helpers/fixed-point-arguments.chapter.md index af6d5912ce37..000dfe097abc 100644 --- a/doc/build-helpers/fixed-point-arguments.chapter.md +++ b/doc/build-helpers/fixed-point-arguments.chapter.md @@ -1,46 +1,39 @@ # Fixed-point arguments of build helpers {#chap-build-helpers-finalAttrs} -As mentioned in the beginning of this part, `stdenv.mkDerivation` could alternatively accept a fixed-point function. The input of this function, typically named `finalAttrs`, is expected to be the final state of the attribute set. A build helper like this is said to accept **fixed-point arguments**. +`stdenv.mkDerivation` also accepts a [fixed-point function](#function-library-lib.fixedPoints.fix) instead of a plain attribute set: -Build helpers don't always support fixed-point arguments yet, as support in [`stdenv.mkDerivation`](#mkderivation-recursive-attributes) was first included in Nixpkgs 22.05. +```nix +stdenv.mkDerivation (finalAttrs: { + pname = "hello"; + version = "2.12"; -## Defining a build helper with `lib.extendMkDerivation` {#sec-build-helper-extendMkDerivation} + src = fetchurl { + url = "mirror://gnu/hello/hello-${finalAttrs.version}.tar.gz"; + hash = "sha256-..."; + }; +}) +``` -Developers can use the Nixpkgs library function [`lib.customisation.extendMkDerivation`](#function-library-lib.customisation.extendMkDerivation) to define a build helper supporting fixed-point arguments from an existing one with such support, with an attribute overlay similar to the one taken by [`.overrideAttrs`](#sec-pkg-overrideAttrs). +The function's input, conventionally named `finalAttrs`, is the final state of the attribute set. Here `src` reads `finalAttrs.version` instead of repeating the version string. A build helper like this is said to accept **fixed-point arguments**. + +Attributes that reference each other through `finalAttrs` stay correct when changing any of them with [`overrideAttrs`](#sec-pkg-overrideAttrs), because they all access the final values of the fixed-point computation. + +`rec` cannot do this: its self-references are fixed when the set is defined and ignore later overrides. +See [recursive-sets](https://nix.dev/manual/nix/stable/language/syntax#recursive-sets) for the underlying mechanism. + +## Define a build helper with `lib.extendMkDerivation` {#sec-build-helper-extendMkDerivation} + +Use [`lib.customisation.extendMkDerivation`](#function-library-lib.customisation.extendMkDerivation) to define a build helper with fixed-point support from an existing one. It takes an attribute overlay similar to [`.overrideAttrs`](#sec-pkg-overrideAttrs). Besides overriding, `lib.extendMkDerivation` also supports `excludeDrvArgNames` to optionally exclude some arguments in the input fixed-point arguments from passing down to the base build helper (specified as `constructDrv`). :::{.example #ex-build-helpers-extendMkDerivation} -# Example definition of `mkLocalDerivation` extended from `stdenv.mkDerivation` with `lib.extendMkDerivation` +# Example `mkLocalDerivation` - a build helper over `mkDerivation` -We want to define a build helper named `mkLocalDerivation` that builds locally without using substitutes by default. +Define a build helper named `mkLocalDerivation` that builds locally without using substitutes by default. -Instead of taking a plain attribute set, - -```nix -{ - preferLocalBuild ? true, - allowSubstitute ? false, - specialArg ? (_: false), - ... -}@args: - -stdenv.mkDerivation ( - removeAttrs [ - # Don't pass specialArg into mkDerivation. - "specialArg" - ] args - // { - # Arguments to pass - inherit preferLocalBuild allowSubstitute; - # Some expressions involving specialArg - greeting = if specialArg "hi" then "hi" else "hello"; - } -) -``` - -we could define with `lib.extendMkDerivation` an attribute overlay to make the result build helper also accept the attribute set's fixed point passing to the underlying `stdenv.mkDerivation`, named `finalAttrs` here: +Use `lib.extendMkDerivation`: ```nix lib.extendMkDerivation { @@ -67,4 +60,8 @@ lib.extendMkDerivation { ``` ::: -If one needs to apply extra changes to the result derivation, pass the derivation transformation function to `lib.extendMkDerivation` as `lib.customisation.extendMkDerivation { transformDrv = drv: ...; }`. +To apply extra changes to the result derivation, pass `transformDrv` to `lib.extendMkDerivation`: + +```nix +lib.customisation.extendMkDerivation { transformDrv = drv: /...; } +```