crane/docs/customizing_builds.md
Ivan Petkov a3f0c63eed
Try to avoid IFD in vendorCargoDeps and crateNameFromCargoToml; also avoid recommending nesting cleanCargoSource and path (#641)
We don't need to nest `cleanCargoSource` and `path` just to populate a
default value for `name`. As they both ultimately delegate to
`builtins.path`, the nesting can lead to IFD in situations which are
otherwise avoidable
2024-06-10 20:53:46 -07:00

69 lines
2.7 KiB
Markdown

## Customizing builds
All derivations, whether they are configured through `buildPackage`,
`cargoBuild`, or even `mkCargoDerivation`, eventually delegate to
[`mkDerivation` which is defined by
nixpkgs](https://nixos.org/manual/nixpkgs/unstable/#ssec-stdenv-dependencies).
At its heart, `mkDerivation` builds up a big `bash` script which is executed by
the builder. Inputs are added to the execution `$PATH`, libraries are added to
include paths, and all other variables are set as shell variables. But these
scripts also come with a small framework for [running various different
phases](https://nixos.org/manual/nixpkgs/unstable/#sec-stdenv-phases). Many of
these phases also come with their own _hooks_ which are shell functions which
can be subscribed to execute before and/or after a particular phase has run.
Although build phases and their hooks allow for easily extending and customizing
the build instructions for a particular derivation, it can become difficult to
identify exactly where a bit of logic should execute. The following are a good
set of resources to consult when in doubt:
1. The [nixpkgs
manual](https://nixos.org/manual/nixpkgs/unstable/#sec-stdenv-phases) for
describing the default set of build phases and their hooks
1. The [crane API reference](./API.md) for additional hooks it introduces
1. Setting `NIX_DEBUG` to a non-zero value will cause the builder to print out
various variables and commands it will run (increasing values will increase
the verbosity).
1. When all else fails [source for the generic build
scripts](https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh)
themselves can be useful
All that out of the way, here's a quick example of how to use the build phases
and hooks to customize a particular build:
```nix
craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
# Define a list of function names to execute before the `configurePhase` runs
preConfigurePhases = [
"foo"
"bar"
];
# Define the functions themselves
foo = ''
# double the amount of rust test threads we can use
# Note that crane will set these defaults as a `postPatchHook` which
# should have already run by the time the preConfigurePhases are called
export RUST_TEST_THREADS=$((RUST_TEST_THREADS * 2))
'';
bar = ''
# decrement by one test thread if running in release mode
if [[ "${CARGO_PROFILE}" == "release" ]]; then
export RUST_TEST_THREADS=$((RUST_TEST_THREADS - 2))
fi
'';
# Lastly, add postInstall to install additional items after
# the default installPhase has run and installed the package binaries
postInstall = ''
echo "hello world" > $out/hello.txt
# also install the README.md for good measure
cp README.md $out/
'';
}
```