diff --git a/doc/build-helpers/special/checkpoint-build.section.md b/doc/build-helpers/special/checkpoint-build.section.md index a1ce5608f246d..649480bc967bf 100644 --- a/doc/build-helpers/special/checkpoint-build.section.md +++ b/doc/build-helpers/special/checkpoint-build.section.md @@ -36,7 +36,11 @@ let changedHello = pkgs.hello.overrideAttrs (_: { doCheck = false; patchPhase = '' + runHook prePatch + sed -i 's/Hello, world!/Hello, Nix!/g' src/hello.c + + runHook postPatch ''; }); in mkCheckpointBuild changedHello helloCheckpoint diff --git a/doc/build-helpers/trivial-build-helpers.chapter.md b/doc/build-helpers/trivial-build-helpers.chapter.md index 9e818be674b47..930b7f56c2c20 100644 --- a/doc/build-helpers/trivial-build-helpers.chapter.md +++ b/doc/build-helpers/trivial-build-helpers.chapter.md @@ -378,7 +378,11 @@ writeTextFile { executable = true; destination = "/some/subpath/my-cool-script"; checkPhase = '' + runHook preCheck + ${pkgs.shellcheck}/bin/shellcheck $out/some/subpath/my-cool-script + + runHook postCheck ''; meta = { license = pkgs.lib.licenses.cc0; diff --git a/doc/doc-support/lib-function-docs.nix b/doc/doc-support/lib-function-docs.nix index e6c08dabb5b05..bb81b50fddef4 100644 --- a/doc/doc-support/lib-function-docs.nix +++ b/doc/doc-support/lib-function-docs.nix @@ -102,6 +102,8 @@ stdenvNoCC.mkDerivation { ]; installPhase = '' + runHook preInstall + cd .. export NIX_STATE_DIR=$(mktemp -d) @@ -143,5 +145,7 @@ stdenvNoCC.mkDerivation { ) libsets} echo '```' >> "$out/index.md" + + runHook postInstall ''; } diff --git a/doc/doc-support/package.nix b/doc/doc-support/package.nix index f316656a585c1..483514066f2fb 100644 --- a/doc/doc-support/package.nix +++ b/doc/doc-support/package.nix @@ -48,6 +48,8 @@ stdenvNoCC.mkDerivation ( ''; buildPhase = '' + runHook preBuild + substituteInPlace ./languages-frameworks/python.section.md \ --subst-var-by python-interpreter-table "$(<"${pythonInterpreterTable}")" @@ -83,9 +85,13 @@ stdenvNoCC.mkDerivation ( --section-toc-depth 1 \ manual.md \ out/index.html + + runHook postBuild ''; installPhase = '' + runHook preInstall + dest="$out/share/doc/nixpkgs" mkdir -p "$(dirname "$dest")" mv out "$dest" @@ -96,6 +102,8 @@ stdenvNoCC.mkDerivation ( mkdir -p $out/nix-support/ echo "doc manual $dest manual.html" >> $out/nix-support/hydra-build-products echo "doc manual $dest nixpkgs-manual.epub" >> $out/nix-support/hydra-build-products + + runHook postInstall ''; passthru = { diff --git a/doc/hooks/tauri.section.md b/doc/hooks/tauri.section.md index 400e493d7feeb..675032f0b5416 100644 --- a/doc/hooks/tauri.section.md +++ b/doc/hooks/tauri.section.md @@ -23,7 +23,7 @@ In Nixpkgs, `cargo-tauri.hook` overrides the default build and install phases. wrapGAppsHook4, }: -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage (finalAttrs: { # . . . useFetchCargoVendor = true; @@ -31,8 +31,8 @@ rustPlatform.buildRustPackage rec { # Assuming our app's frontend uses `npm` as a package manager npmDeps = fetchNpmDeps { - name = "${pname}-npm-deps-${version}"; - inherit src; + name = "${finalAttrs.pname}-npm-deps-${finalAttrs.version}"; + inherit (finalAttrs) src; hash = "..."; }; @@ -62,7 +62,7 @@ rustPlatform.buildRustPackage rec { buildAndTestSubdir = cargoRoot; # . . . -} +}) ``` ## Variables controlling cargo-tauri {#tauri-hook-variables-controlling} diff --git a/doc/languages-frameworks/agda.section.md b/doc/languages-frameworks/agda.section.md index 33fffc60c8db3..fac090aa4b16a 100644 --- a/doc/languages-frameworks/agda.section.md +++ b/doc/languages-frameworks/agda.section.md @@ -51,7 +51,7 @@ agda.withPackages (p: [ src = fetchFromGitHub { repo = "agda-stdlib"; owner = "agda"; - rev = "v1.5"; + tag = "v1.5"; hash = "sha256-nEyxYGSWIDNJqBfGpRDLiOAnlHJKEKAOMnIaqfVZzJk="; }; })) @@ -82,7 +82,7 @@ agda.withPackages (p: [ repo = "repo"; owner = "owner"; version = "..."; - rev = "..."; + tag = "..."; hash = "..."; }; }) @@ -200,8 +200,12 @@ mkDerivation { libraryName = "IAL-1.3"; buildPhase = '' + runHook preBuild + patchShebangs find-deps.sh make + + runHook postBuild ''; } ``` diff --git a/doc/languages-frameworks/android.section.md b/doc/languages-frameworks/android.section.md index b640ba8d50118..09a9c49e24b7c 100644 --- a/doc/languages-frameworks/android.section.md +++ b/doc/languages-frameworks/android.section.md @@ -255,10 +255,12 @@ let # Use buildToolsVersion when you define androidComposition androidComposition = <...>; -in -pkgs.mkShell rec { + ANDROID_HOME = "${androidComposition.androidsdk}/libexec/android-sdk"; ANDROID_NDK_ROOT = "${ANDROID_HOME}/ndk-bundle"; +in +pkgs.mkShell { + inherit ANDROID_HOME ANDROID_NDK_ROOT; # Use the same buildToolsVersion here GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_HOME}/build-tools/${buildToolsVersion}/aapt2"; @@ -275,10 +277,12 @@ let # Use cmakeVersion when you define androidComposition androidComposition = <...>; -in -pkgs.mkShell rec { + ANDROID_HOME = "${androidComposition.androidsdk}/libexec/android-sdk"; ANDROID_NDK_ROOT = "${ANDROID_HOME}/ndk-bundle"; +in +pkgs.mkShell { + inherit ANDROID_HOME ANDROID_NDK_ROOT; # Use the same cmakeVersion here shellHook = '' diff --git a/doc/languages-frameworks/bower.section.md b/doc/languages-frameworks/bower.section.md index 346852c494267..28c212b533075 100644 --- a/doc/languages-frameworks/bower.section.md +++ b/doc/languages-frameworks/bower.section.md @@ -97,12 +97,22 @@ pkgs.stdenv.mkDerivation { }; buildPhase = '' + runHook preBuild + cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . # note 2 export HOME=$PWD # note 3 ${pkgs.nodePackages.gulp}/bin/gulp build # note 4 + + runHook postBuild ''; - installPhase = "mv gulpdist $out"; + installPhase = '' + runHook preInstall + + mv gulpdist $out + + runHook postInstall + ''; } ``` diff --git a/doc/languages-frameworks/dart.section.md b/doc/languages-frameworks/dart.section.md index dfb456ba19410..8ecfd59ad6fc2 100644 --- a/doc/languages-frameworks/dart.section.md +++ b/doc/languages-frameworks/dart.section.md @@ -38,8 +38,8 @@ buildDartApplication rec { src = fetchFromGitHub { owner = "sass"; - repo = pname; - rev = version; + repo = "dart-sass"; + tag = version; hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4="; }; diff --git a/doc/languages-frameworks/dlang.section.md b/doc/languages-frameworks/dlang.section.md index 6e9edefc5e0f3..439f306107334 100644 --- a/doc/languages-frameworks/dlang.section.md +++ b/doc/languages-frameworks/dlang.section.md @@ -36,7 +36,9 @@ buildDubPackage rec { installPhase = '' runHook preInstall + install -Dm755 btdu -t $out/bin + runHook postInstall ''; } diff --git a/doc/languages-frameworks/emscripten.section.md b/doc/languages-frameworks/emscripten.section.md index d1ed62d0503f5..e70584f0cf878 100644 --- a/doc/languages-frameworks/emscripten.section.md +++ b/doc/languages-frameworks/emscripten.section.md @@ -45,9 +45,11 @@ One advantage is that when `pkgs.zlib` is updated, it will automatically update buildInputs = old.buildInputs ++ [ pkg-config ]; # we need to reset this setting! env = (old.env or { }) // { NIX_CFLAGS_COMPILE = ""; }; + + # Some tests require writing at $HOME + nativeBuildInputs = old.nativeBuildInputs ++ [ writableTmpDirAsHomeHook ]; + configurePhase = '' - # FIXME: Some tests require writing at $HOME - HOME=$TMPDIR runHook preConfigure #export EMCC_DEBUG=2 @@ -58,12 +60,22 @@ One advantage is that when `pkgs.zlib` is updated, it will automatically update dontStrip = true; outputs = [ "out" ]; buildPhase = '' + runHook preBuild + emmake make + + runHook postBuild ''; installPhase = '' + runHook preInstall + emmake make install + + runHook postInstall ''; checkPhase = '' + runHook preCheck + echo "================= testing zlib using node =================" echo "Compiling a custom test" @@ -82,6 +94,8 @@ One advantage is that when `pkgs.zlib` is updated, it will automatically update echo "it seems to work! very good." fi echo "================= /testing zlib using node =================" + + runHook postCheck ''; postPatch = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin '' diff --git a/doc/languages-frameworks/go.section.md b/doc/languages-frameworks/go.section.md index 34bf913ef1e81..1fcbe6b196b7b 100644 --- a/doc/languages-frameworks/go.section.md +++ b/doc/languages-frameworks/go.section.md @@ -13,14 +13,14 @@ The following is an example expression using `buildGoModule`: ```nix { - pet = buildGoModule rec { + pet = buildGoModule (finalAttrs: { pname = "pet"; version = "0.3.4"; src = fetchFromGitHub { owner = "knqyf263"; repo = "pet"; - rev = "v${version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-Gjw1dRrgM8D3G7v6WIM2+50r4HmTXvx0Xxme2fH9TlQ="; }; @@ -32,7 +32,7 @@ The following is an example expression using `buildGoModule`: license = lib.licenses.mit; maintainers = with lib.maintainers; [ kalbasit ]; }; - }; + }); } ``` @@ -69,7 +69,6 @@ You can read more about [vendoring in the Go documentation](https://go.dev/ref/m To obtain the hash, set `vendorHash = lib.fakeHash;` and run the build. ([more details here](#sec-source-hashes)). Another way is to use use `nix-prefetch` to obtain the hash. The following command gets the value of `vendorHash` for package `pet`: - ```sh cd path/to/nixpkgs nix-prefetch -E "{ sha256 }: ((import ./. { }).my-package.overrideAttrs { vendorHash = sha256; }).goModules" @@ -84,7 +83,7 @@ nix-prefetch -E "{ sha256 }: ((import ./. { }).my-package.overrideAttrs { vendor version = "0.4.0"; src = fetchFromGitHub { inherit (previousAttrs.src) owner repo; - rev = "v${finalAttrs.version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-gVTpzmXekQxGMucDKskGi+e+34nJwwsXwvQTjRO6Gdg="; }; vendorHash = "sha256-dUvp7FEW09V0xMuhewPGw3TuAic/sD7xyXEYviZ2Ivs="; @@ -104,13 +103,11 @@ if any dependency has case-insensitive conflicts which will produce platform-dep Defaults to `false`. - ### `modPostBuild` {#var-go-modPostBuild} Shell commands to run after the build of the goModules executes `go mod vendor`, and before calculating fixed output derivation's `vendorHash`. Note that if you change this attribute, you need to update `vendorHash` attribute. - ### `modRoot` {#var-go-modRoot} The root directory of the Go module that contains the `go.mod` file. @@ -133,7 +130,7 @@ The most common use case for this argument is to make the resulting executable a ### `tags` {#var-go-tags} -A string list of [Go build tags (also called build constraints)](https://pkg.go.dev/cmd/go#hdr-Build_constraints) that are passed via the `-tags` argument of `go build`. These constraints control whether Go files from the source should be included in the build. For example: +A string list of [Go build tags (also called build constraints)](https://pkg.go.dev/cmd/go#hdr-Build_constraints) that are passed via the `-tags` argument of `go build`. These constraints control whether Go files from the source should be included in the build. For example: ```nix { diff --git a/doc/languages-frameworks/gradle.section.md b/doc/languages-frameworks/gradle.section.md index 762c8003a7a75..e19f42cd631e7 100644 --- a/doc/languages-frameworks/gradle.section.md +++ b/doc/languages-frameworks/gradle.section.md @@ -41,6 +41,8 @@ stdenv.mkDerivation (finalAttrs: { doCheck = true; installPhase = '' + runHook preInstall + mkdir -p $out/{bin,share/pdftk} cp build/libs/pdftk-all.jar $out/share/pdftk @@ -48,6 +50,8 @@ stdenv.mkDerivation (finalAttrs: { --add-flags "-jar $out/share/pdftk/pdftk-all.jar" cp ${finalAttrs.src}/pdftk.1 $out/share/man/man1 + + runHook postInstall ''; meta.sourceProvenance = with lib.sourceTypes; [ diff --git a/doc/languages-frameworks/java.section.md b/doc/languages-frameworks/java.section.md index 5208a6388a327..056e822074185 100644 --- a/doc/languages-frameworks/java.section.md +++ b/doc/languages-frameworks/java.section.md @@ -17,7 +17,9 @@ stdenv.mkDerivation { buildPhase = '' runHook preBuild + ant # build the project using ant + runHook postBuild ''; diff --git a/doc/languages-frameworks/javascript.section.md b/doc/languages-frameworks/javascript.section.md index 9acfd4181108a..8cccd4a51494c 100644 --- a/doc/languages-frameworks/javascript.section.md +++ b/doc/languages-frameworks/javascript.section.md @@ -193,8 +193,8 @@ buildNpmPackage rec { src = fetchFromGitHub { owner = "jesec"; - repo = pname; - rev = "v${version}"; + repo = "flood"; + tag = "v${version}"; hash = "sha256-BR+ZGkBBfd0dSQqAvujsbgsEPFYw/ThrylxUbOksYxM="; }; @@ -554,7 +554,7 @@ stdenv.mkDerivation (finalAttrs: { src = fetchFromGitHub { owner = "..."; repo = "..."; - rev = "v${finalAttrs.version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; @@ -621,9 +621,14 @@ It's important to use the `--offline` flag. For example if you script is `"build ```nix { + nativeBuildInputs = [ writableTmpDirAsHomeHook ]; + buildPhase = '' - export HOME=$(mktemp -d) + runHook preBuild + yarn --offline build + + runHook postBuild ''; } ``` @@ -641,7 +646,11 @@ The configure phase can sometimes fail because it makes many assumptions which m ```nix { configurePhase = '' + runHook preConfigure + ln -s $node_modules node_modules + + runHook postConfigure ''; } ``` @@ -651,8 +660,12 @@ or if you need a writeable node_modules directory: ```nix { configurePhase = '' + runHook preConfigure + cp -r $node_modules node_modules chmod +w node_modules + + runHook postConfigure ''; } ``` diff --git a/doc/languages-frameworks/lisp.section.md b/doc/languages-frameworks/lisp.section.md index 73f20436c76fc..eed6161d3a952 100644 --- a/doc/languages-frameworks/lisp.section.md +++ b/doc/languages-frameworks/lisp.section.md @@ -58,7 +58,11 @@ Such a Lisp can be now used e.g. to compile your sources: ```nix { buildPhase = '' + runHook preBuild + ${sbcl'}/bin/sbcl --load my-build-file.lisp + + runHook postBuild ''; } ``` @@ -184,7 +188,7 @@ let domain = "gitlab.common-lisp.net"; owner = "alexandria"; repo = "alexandria"; - rev = "v${version}"; + tag = "v${version}"; hash = "sha256-1Hzxt65dZvgOFIljjjlSGgKYkj+YBLwJCACi5DZsKmQ="; }; }; @@ -208,7 +212,7 @@ sbcl.pkgs.alexandria.overrideLispAttrs (oldAttrs: rec { domain = "gitlab.common-lisp.net"; owner = "alexandria"; repo = "alexandria"; - rev = "v${version}"; + tag = "v${version}"; hash = "sha256-1Hzxt65dZvgOFIljjjlSGgKYkj+YBLwJCACi5DZsKmQ="; }; }) diff --git a/doc/languages-frameworks/maven.section.md b/doc/languages-frameworks/maven.section.md index 88fe4d0c92245..c8102a6afc538 100644 --- a/doc/languages-frameworks/maven.section.md +++ b/doc/languages-frameworks/maven.section.md @@ -17,8 +17,8 @@ maven.buildMavenPackage rec { src = fetchFromGitHub { owner = "intoolswetrust"; - repo = pname; - rev = "${pname}-${version}"; + repo = "jd-cli"; + tag = "jd-cli-${version}"; hash = "sha256-rRttA5H0A0c44loBzbKH7Waoted3IsOgxGCD2VM0U/Q="; }; @@ -27,11 +27,15 @@ maven.buildMavenPackage rec { nativeBuildInputs = [ makeWrapper ]; installPhase = '' + runHook preInstall + mkdir -p $out/bin $out/share/jd-cli install -Dm644 jd-cli/target/jd-cli.jar $out/share/jd-cli makeWrapper ${jre}/bin/java $out/bin/jd-cli \ --add-flags "-jar $out/share/jd-cli/jd-cli.jar" + + runHook postInstall ''; meta = { @@ -76,7 +80,7 @@ jd-cli.overrideMavenAttrs (old: rec { src = fetchFromGitHub { owner = old.src.owner; repo = old.src.repo; - rev = "${old.pname}-${version}"; + tag = "${old.pname}-${version}"; # old source hash of 1.2.0 version hash = "sha256-US7j6tQ6mh1libeHnQdFxPGoxHzbZHqehWSgCYynKx8="; }; @@ -283,26 +287,41 @@ Traditionally the Maven repository is at `~/.m2/repository`. We will override th ::: ```nix -{ lib, stdenv, maven }: +{ + lib, + stdenv, + maven, +}: stdenv.mkDerivation { name = "maven-repository"; buildInputs = [ maven ]; + src = ./.; # or fetchFromGitHub, cleanSourceWith, etc + buildPhase = '' + runHook preBuild + mvn package -Dmaven.repo.local=$out + + runHook postBuild ''; # keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside installPhase = '' + runHook preInstall + find $out -type f \ -name \*.lastUpdated -or \ -name resolver-status.properties -or \ -name _remote.repositories \ -delete + + runHook postInstall ''; # don't do any fixup dontFixup = true; + outputHashAlgo = null; outputHashMode = "recursive"; # replace this with the correct SHA256 @@ -337,10 +356,16 @@ If your package uses _SNAPSHOT_ dependencies or _version ranges_; there is a str Regardless of which strategy is chosen above, the step to build the derivation is the same. ```nix -{ stdenv, maven, callPackage }: -# pick a repository derivation, here we will use buildMaven -let repository = callPackage ./build-maven-repository.nix { }; -in stdenv.mkDerivation rec { +{ + stdenv, + maven, + callPackage, +}: +let + # pick a repository derivation, here we will use buildMaven + repository = callPackage ./build-maven-repository.nix { }; +in +stdenv.mkDerivation (finalAttrs: { pname = "maven-demo"; version = "1.0"; @@ -348,14 +373,22 @@ in stdenv.mkDerivation rec { buildInputs = [ maven ]; buildPhase = '' + runHook preBuild + echo "Using repository ${repository}" mvn --offline -Dmaven.repo.local=${repository} package; + + runHook postBuild ''; installPhase = '' - install -Dm644 target/${pname}-${version}.jar $out/share/java + runHook preInstall + + install -Dm644 target/${finalAttrs.pname}-${finalAttrs.version}.jar $out/share/java + + runHook postInstall ''; -} +}) ``` ::: {.tip} @@ -393,35 +426,49 @@ We will read the Maven repository and flatten it to a single list. This list wil We make sure to provide this classpath to the `makeWrapper`. ```nix -{ stdenv, maven, callPackage, makeWrapper, jre }: +{ + stdenv, + maven, + callPackage, + makeWrapper, + jre, +}: let repository = callPackage ./build-maven-repository.nix { }; -in stdenv.mkDerivation rec { +in +stdenv.mkDerivation (finalAttrs: { pname = "maven-demo"; version = "1.0"; - src = builtins.fetchTarball - "https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz"; + src = builtins.fetchTarball "https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz"; nativeBuildInputs = [ makeWrapper ]; buildInputs = [ maven ]; buildPhase = '' + runHook preBuild + echo "Using repository ${repository}" mvn --offline -Dmaven.repo.local=${repository} package; + + runHook postBuild ''; installPhase = '' + runHook preInstall + mkdir -p $out/bin classpath=$(find ${repository} -name "*.jar" -printf ':%h/%f'); - install -Dm644 target/${pname}-${version}.jar $out/share/java + install -Dm644 target/${finalAttrs.pname}-${finalAttrs.version}.jar $out/share/java # create a wrapper that will automatically set the classpath # this should be the paths from the dependency derivation - makeWrapper ${jre}/bin/java $out/bin/${pname} \ - --add-flags "-classpath $out/share/java/${pname}-${version}.jar:''${classpath#:}" \ + makeWrapper ${jre}/bin/java $out/bin/${finalAttrs.pname} \ + --add-flags "-classpath $out/share/java/${finalAttrs.pname}-${finalAttrs.version}.jar:''${classpath#:}" \ --add-flags "Main" + + runHook postInstall ''; -} +}) ``` #### MANIFEST file via Maven Plugin {#manifest-file-via-maven-plugin} @@ -471,36 +518,51 @@ Main-Class: Main We will modify the derivation above to add a symlink to our repository so that it's accessible to our JAR during the `installPhase`. ```nix -{ stdenv, maven, callPackage, makeWrapper, jre }: -# pick a repository derivation, here we will use buildMaven -let repository = callPackage ./build-maven-repository.nix { }; -in stdenv.mkDerivation rec { +{ + stdenv, + maven, + callPackage, + makeWrapper, + jre, +}: +let + # pick a repository derivation, here we will use buildMaven + repository = callPackage ./build-maven-repository.nix { }; +in +stdenv.mkDerivation (finalAttrs: { pname = "maven-demo"; version = "1.0"; - src = builtins.fetchTarball - "https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz"; + src = builtins.fetchTarball "https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz"; nativeBuildInputs = [ makeWrapper ]; buildInputs = [ maven ]; buildPhase = '' + runHook preBuild + echo "Using repository ${repository}" mvn --offline -Dmaven.repo.local=${repository} package; + + runHook postBuild ''; installPhase = '' + runHook preInstall + mkdir -p $out/bin # create a symbolic link for the repository directory ln -s ${repository} $out/repository - install -Dm644 target/${pname}-${version}.jar $out/share/java + install -Dm644 target/${finalAttrs.pname}-${finalAttrs.version}.jar $out/share/java # create a wrapper that will automatically set the classpath # this should be the paths from the dependency derivation - makeWrapper ${jre}/bin/java $out/bin/${pname} \ - --add-flags "-jar $out/share/java/${pname}-${version}.jar" + makeWrapper ${jre}/bin/java $out/bin/${finalAttrs.pname} \ + --add-flags "-jar $out/share/java/${finalAttrs.pname}-${finalAttrs.version}.jar" + + runHook postInstall ''; -} +}) ``` ::: {.note} Our script produces a dependency on `jre` rather than `jdk` to restrict the runtime closure necessary to run the application. diff --git a/doc/languages-frameworks/nim.section.md b/doc/languages-frameworks/nim.section.md index f0196c9d116f5..a26bbddd89f95 100644 --- a/doc/languages-frameworks/nim.section.md +++ b/doc/languages-frameworks/nim.section.md @@ -16,7 +16,7 @@ buildNimPackage (finalAttrs: { src = fetchFromGitHub { owner = "inv2004"; repo = "ttop"; - rev = "v${finalAttrs.version}"; + tag = "v${finalAttrs.version}"; hash = lib.fakeHash; }; diff --git a/doc/languages-frameworks/php.section.md b/doc/languages-frameworks/php.section.md index 1bcb4ee727a59..b2c4927e87d7d 100644 --- a/doc/languages-frameworks/php.section.md +++ b/doc/languages-frameworks/php.section.md @@ -229,7 +229,7 @@ php.buildComposerProject (finalAttrs: { src = fetchFromGitHub { owner = "git-owner"; repo = "git-repo"; - rev = finalAttrs.version; + tag = finalAttrs.version; hash = "sha256-VcQRSss2dssfkJ+iUb5qT+FJ10GHiFDzySigcmuVI+8="; }; @@ -266,7 +266,7 @@ let src = fetchFromGitHub { owner = "git-owner"; repo = "git-repo"; - rev = finalAttrs.version; + tag = finalAttrs.version; hash = "sha256-VcQRSss2dssfkJ+iUb5qT+FJ10GHiFDzySigcmuVI+8="; }; in { diff --git a/doc/languages-frameworks/python.section.md b/doc/languages-frameworks/python.section.md index bbc5da116a6a8..45503d4884097 100644 --- a/doc/languages-frameworks/python.section.md +++ b/doc/languages-frameworks/python.section.md @@ -1737,10 +1737,11 @@ with import { }; let pythonPackages = python3Packages; -in pkgs.mkShell rec { +in +pkgs.mkShell { name = "impurePythonEnv"; - venvDir = "./.venv"; - buildInputs = [ + + packages = [ # A Python interpreter including the 'venv' module is required to bootstrap # the environment. pythonPackages.python @@ -1766,6 +1767,8 @@ in pkgs.mkShell rec { zlib ]; + venvDir = "./.venv"; + # Run this command, only after creating the virtual environment postVenvCreation = '' unset SOURCE_DATE_EPOCH @@ -1778,7 +1781,6 @@ in pkgs.mkShell rec { # allow pip to install wheels unset SOURCE_DATE_EPOCH ''; - } ``` @@ -1792,9 +1794,11 @@ with import { }; let venvDir = "./.venv"; pythonPackages = python3Packages; -in pkgs.mkShell rec { +in +pkgs.mkShell { name = "impurePythonEnv"; - buildInputs = [ + + packages = [ pythonPackages.python # Needed when using python 2.7 # pythonPackages.virtualenv @@ -2040,6 +2044,7 @@ Occasionally packages don't make use of a common test framework, which may then * Tests that attempt to access `$HOME` can be fixed by using the following work-around before running tests (e.g. `preCheck`): `export HOME=$(mktemp -d)` + or by adding the `writableTmpDirAsHomeHook` hook to `nativeCheckInputs`. * Compiling with Cython causes tests to fail with a `ModuleNotLoadedError`. This can be fixed with two changes in the derivation: 1) replacing `pytest` with `pytestCheckHook` and 2) adding a `preCheck` containing `cd $out` to run diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 34ac80cac9989..d3a910cd4f68d 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -24,14 +24,14 @@ Rust applications are packaged by using the `buildRustPackage` helper from `rust ```nix { lib, fetchFromGitHub, rustPlatform }: -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage (finalAttrs: { pname = "ripgrep"; version = "14.1.1"; src = fetchFromGitHub { owner = "BurntSushi"; - repo = pname; - rev = version; + repo = "ripgrep"; + tag = version; hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg="; }; @@ -44,7 +44,7 @@ rustPlatform.buildRustPackage rec { license = lib.licenses.unlicense; maintainers = [ ]; }; -} +}) ``` `buildRustPackage` requires a `cargoHash` attribute, computed over all crate sources of this package. @@ -100,12 +100,12 @@ be made invariant to the version by setting `cargoDepsName` to `pname`: ```nix -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage (finalAttrs: { pname = "broot"; version = "1.2.0"; src = fetchCrate { - inherit pname version; + inherit (finalAttrs) pname version; hash = "sha256-aDQA4A5mScX9or3Lyiv/5GyAehidnpKKE0grhbP1Ctc="; }; @@ -114,7 +114,7 @@ rustPlatform.buildRustPackage rec { cargoDepsName = pname; # ... -} +}) ``` ### Importing a `Cargo.lock` file {#importing-a-cargo.lock-file} @@ -178,7 +178,7 @@ The output hash of each dependency that uses a git source must be specified in the `outputHashes` attribute. For example: ```nix -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage { pname = "myproject"; version = "1.0.0"; @@ -203,7 +203,7 @@ For usage outside nixpkgs, `allowBuiltinFetchGit` could be used to avoid having to specify `outputHashes`. For example: ```nix -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage { pname = "myproject"; version = "1.0.0"; @@ -229,7 +229,7 @@ If you want to use different features for check phase, you can use For example: ```nix -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage { pname = "myproject"; version = "1.0.0"; @@ -246,53 +246,53 @@ rustPlatform.buildRustPackage rec { ### Cross compilation {#cross-compilation} By default, Rust packages are compiled for the host platform, just like any -other package is. The `--target` passed to rust tools is computed from this. +other package is. The `--target` passed to rust tools is computed from this. By default, it takes the `stdenv.hostPlatform.config` and replaces components where they are known to differ. But there are ways to customize the argument: - - To choose a different target by name, define - `stdenv.hostPlatform.rust.rustcTarget` as that name (a string), and that - name will be used instead. +- To choose a different target by name, define + `stdenv.hostPlatform.rust.rustcTarget` as that name (a string), and that + name will be used instead. - For example: + For example: - ```nix - import { - crossSystem = (import ).systems.examples.armhf-embedded // { - rust.rustcTarget = "thumbv7em-none-eabi"; - }; - } - ``` + ```nix + import { + crossSystem = (import ).systems.examples.armhf-embedded // { + rust.rustcTarget = "thumbv7em-none-eabi"; + }; + } + ``` - will result in: + will result in: - ```shell - --target thumbv7em-none-eabi - ``` + ```shell + --target thumbv7em-none-eabi + ``` - - To pass a completely custom target, define - `stdenv.hostPlatform.rust.rustcTarget` with its name, and - `stdenv.hostPlatform.rust.platform` with the value. The value will be - serialized to JSON in a file called - `${stdenv.hostPlatform.rust.rustcTarget}.json`, and the path of that file - will be used instead. +- To pass a completely custom target, define + `stdenv.hostPlatform.rust.rustcTarget` with its name, and + `stdenv.hostPlatform.rust.platform` with the value. The value will be + serialized to JSON in a file called + `${stdenv.hostPlatform.rust.rustcTarget}.json`, and the path of that file + will be used instead. - For example: + For example: - ```nix - import { - crossSystem = (import ).systems.examples.armhf-embedded // { - rust.rustcTarget = "thumb-crazy"; - rust.platform = { foo = ""; bar = ""; }; - }; - } - ``` + ```nix + import { + crossSystem = (import ).systems.examples.armhf-embedded // { + rust.rustcTarget = "thumb-crazy"; + rust.platform = { foo = ""; bar = ""; }; + }; + } + ``` - will result in: + will result in: - ```shell - --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""} - ``` + ```shell + --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""} + ``` Note that currently custom targets aren't compiled with `std`, so `cargo test` will fail. This can be ignored by adding `doCheck = false;` to your derivation. @@ -339,9 +339,9 @@ This can only be worked around by patching the affected tests accordingly. In some instances, it may be necessary to disable testing altogether (with `doCheck = false;`): -* If no tests exist -- the `checkPhase` should be explicitly disabled to skip +- If no tests exist -- the `checkPhase` should be explicitly disabled to skip unnecessary build steps to speed up the build. -* If tests are highly impure (e.g. due to network usage). +- If tests are highly impure (e.g. due to network usage). There will obviously be some corner-cases not listed above where it's sensible to disable tests. The above are just guidelines, and exceptions may be granted on a case-by-case basis. @@ -415,7 +415,7 @@ source code in a reproducible way. If it is missing or out-of-date one can use the `cargoPatches` attribute to update or add it. ```nix -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage { # ... cargoPatches = [ # a patch file to add/update Cargo.lock in the source code @@ -452,12 +452,12 @@ The `src` attribute is required, as well as a hash specified through one of the `hash` attribute. The following optional attributes can also be used: -* `name`: the name that is used for the dependencies tarball. If +- `name`: the name that is used for the dependencies tarball. If `name` is not specified, then the name `cargo-deps` will be used. -* `sourceRoot`: when the `Cargo.lock`/`Cargo.toml` are in a +- `sourceRoot`: when the `Cargo.lock`/`Cargo.toml` are in a subdirectory, `sourceRoot` specifies the relative path to these files. -* `patches`: patches to apply before vendoring. This is useful when +- `patches`: patches to apply before vendoring. This is useful when the `Cargo.lock`/`Cargo.toml` files need to be patched before vendoring. @@ -500,7 +500,7 @@ you of the correct hash. `rustPlatform` provides the following hooks to automate Cargo builds: -* `cargoSetupHook`: configure Cargo to use dependencies vendored +- `cargoSetupHook`: configure Cargo to use dependencies vendored through `fetchCargoVendor` or `importCargoLock`. This hook uses the `cargoDeps` environment variable to find the vendored dependencies. If a project already vendors its dependencies, the @@ -508,29 +508,29 @@ you of the correct hash. `Cargo.toml`/`Cargo.lock` files are not in `sourceRoot`, then the optional `cargoRoot` is used to specify the Cargo root directory relative to `sourceRoot`. -* `cargoBuildHook`: use Cargo to build a crate. If the crate to be +- `cargoBuildHook`: use Cargo to build a crate. If the crate to be built is a crate in e.g. a Cargo workspace, the relative path to the crate to build can be set through the optional `buildAndTestSubdir` environment variable. Features can be specified with `cargoBuildNoDefaultFeatures` and `cargoBuildFeatures`. Additional Cargo build flags can be passed through `cargoBuildFlags`. -* `maturinBuildHook`: use [Maturin](https://github.com/PyO3/maturin) +- `maturinBuildHook`: use [Maturin](https://github.com/PyO3/maturin) to build a Python wheel. Similar to `cargoBuildHook`, the optional variable `buildAndTestSubdir` can be used to build a crate in a Cargo workspace. Additional Maturin flags can be passed through `maturinBuildFlags`. -* `cargoCheckHook`: run tests using Cargo. The build type for checks +- `cargoCheckHook`: run tests using Cargo. The build type for checks can be set using `cargoCheckType`. Features can be specified with `cargoCheckNoDefaultFeatures` and `cargoCheckFeatures`. Additional flags can be passed to the tests using `checkFlags` and `checkFlagsArray`. By default, tests are run in parallel. This can be disabled by setting `dontUseCargoParallelTests`. -* `cargoNextestHook`: run tests using +- `cargoNextestHook`: run tests using [cargo-nextest](https://github.com/nextest-rs/nextest). The same options for `cargoCheckHook` also applies to `cargoNextestHook`. -* `cargoInstallHook`: install binaries and static/shared libraries +- `cargoInstallHook`: install binaries and static/shared libraries that were built using `cargoBuildHook`. -* `bindgenHook`: for crates which use `bindgen` as a build dependency, lets +- `bindgenHook`: for crates which use `bindgen` as a build dependency, lets `bindgen` find `libclang` and `libclang` find the libraries in `buildInputs`. #### Examples {#examples} @@ -548,32 +548,33 @@ directory of the `tokenizers` project's source archive, we use `sourceRoot` to point the tooling to this directory: ```nix -{ fetchFromGitHub -, buildPythonPackage -, cargo -, rustPlatform -, rustc -, setuptools-rust +{ + fetchFromGitHub, + buildPythonPackage, + cargo, + rustPlatform, + rustc, + setuptools-rust, }: -buildPythonPackage rec { +buildPythonPackage (finalAttrs: { pname = "tokenizers"; version = "0.10.0"; src = fetchFromGitHub { owner = "huggingface"; - repo = pname; - rev = "python-v${version}"; + repo = "tokenizers"; + tag = "python-v${finalAttrs.version}"; hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw="; }; + sourceRoot = "${src.name}/bindings/python"; + cargoDeps = rustPlatform.fetchCargoVendor { - inherit pname version src sourceRoot; + inherit (finalAttrs) pname version src sourceRoot; hash = "sha256-RO1m8wEd5Ic2M9q+zFHeCJWhCr4Sv3CEWd08mkxsBec="; }; - sourceRoot = "${src.name}/bindings/python"; - nativeBuildInputs = [ cargo rustPlatform.cargoSetupHook @@ -582,44 +583,44 @@ buildPythonPackage rec { ]; # ... -} +}) ``` In some projects, the Rust crate is not in the main Python source -directory. In such cases, the `cargoRoot` attribute can be used to +directory. In such cases, the `cargoRoot` attribute can be used to specify the crate's directory relative to `sourceRoot`. In the following example, the crate is in `src/rust`, as specified in the `cargoRoot` attribute. Note that we also need to specify the correct path for `fetchCargoVendor`. ```nix - -{ buildPythonPackage -, fetchPypi -, rustPlatform -, setuptools-rust -, openssl +{ + buildPythonPackage, + fetchPypi, + rustPlatform, + setuptools-rust, + openssl, }: -buildPythonPackage rec { +buildPythonPackage (finalAttrs: { pname = "cryptography"; version = "3.4.2"; # Also update the hash in vectors.nix src = fetchPypi { - inherit pname version; + inherit (finalAttrs) pname version; hash = "sha256-xGDilsjLOnls3MfVbGKnj80KCUCczZxlis5PmHzpNcQ="; }; + cargoRoot = "src/rust"; + cargoDeps = rustPlatform.fetchCargoVendor { - inherit pname version src; - sourceRoot = "${pname}-${version}/${cargoRoot}"; + inherit (finalAttrs) pname version src; + sourceRoot = "${finalAttrs.pname}-${finalAttrs.version}/${finalAttrs.cargoRoot}"; hash = "sha256-ctUt8maCjnGddKPf+Ii++wKsAXA1h+JM6zKQNXXwJqQ="; }; - cargoRoot = "src/rust"; - # ... -} +}) ``` #### Python package using `maturin` {#python-package-using-maturin} @@ -632,13 +633,14 @@ builds the `retworkx` Python package. `fetchCargoVendor` and `maturinBuildHook` is used to perform the build. ```nix -{ lib -, buildPythonPackage -, rustPlatform -, fetchFromGitHub +{ + lib, + buildPythonPackage, + rustPlatform, + fetchFromGitHub, }: -buildPythonPackage rec { +buildPythonPackage (finalAttrs: { pname = "retworkx"; version = "0.6.0"; pyproject = true; @@ -646,19 +648,19 @@ buildPythonPackage rec { src = fetchFromGitHub { owner = "Qiskit"; repo = "retworkx"; - rev = version; + tag = finalAttrs.version; hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20="; }; cargoDeps = rustPlatform.fetchCargoVendor { - inherit pname version src; + inherit (finalAttrs) pname version src; hash = "sha256-QsPCQhNZKYCAogQriQX6pBYQUDAIUsEdRX/63dAqTzg="; }; nativeBuildInputs = with rustPlatform; [ cargoSetupHook maturinBuildHook ]; # ... -} +}) ``` #### Rust package built with `meson` {#rust-package-built-with-meson} @@ -666,23 +668,24 @@ buildPythonPackage rec { Some projects, especially GNOME applications, are built with the Meson Build System instead of calling Cargo directly. Using `rustPlatform.buildRustPackage` may successfully build the main program, but related files will be missing. Instead, you need to set up Cargo dependencies with `fetchCargoVendor` and `cargoSetupHook` and leave the rest to Meson. `rust` and `cargo` are still needed in `nativeBuildInputs` for Meson to use. ```nix -{ lib -, stdenv -, fetchFromGitLab -, meson -, ninja -, pkg-config -, rustPlatform -, rustc -, cargo -, wrapGAppsHook4 -, blueprint-compiler -, libadwaita -, libsecret -, tinysparql +{ + lib, + stdenv, + fetchFromGitLab, + meson, + ninja, + pkg-config, + rustPlatform, + rustc, + cargo, + wrapGAppsHook4, + blueprint-compiler, + libadwaita, + libsecret, + tinysparql, }: -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "health"; version = "0.95.0"; @@ -690,12 +693,12 @@ stdenv.mkDerivation rec { domain = "gitlab.gnome.org"; owner = "World"; repo = "health"; - rev = version; + tag = finalAttrs.version; hash = "sha256-PrNPprSS98yN8b8yw2G6hzTSaoE65VbsM3q7FVB4mds="; }; cargoDeps = rustPlatform.fetchCargoVendor { - inherit pname version src; + inherit (finalAttrs) pname version src; hash = "sha256-eR1ZGtTZQNhofFUEjI7IX16sMKPJmAl7aIFfPJukecg="; }; @@ -717,7 +720,7 @@ stdenv.mkDerivation rec { ]; # ... -} +}) ``` ## `buildRustCrate`: Compiling Rust crates using Nix instead of Cargo {#compiling-rust-crates-using-nix-instead-of-cargo} @@ -727,7 +730,7 @@ stdenv.mkDerivation rec { When run, `cargo build` produces a file called `Cargo.lock`, containing pinned versions of all dependencies. Nixpkgs contains a tool called `crate2Nix` (`nix-shell -p crate2nix`), which can be -used to turn a `Cargo.lock` into a Nix expression. That Nix +used to turn a `Cargo.lock` into a Nix expression. That Nix expression calls `rustc` directly (hence bypassing Cargo), and can be used to compile a crate and all its dependencies. @@ -892,6 +895,7 @@ To package things that require Rust nightly, `RUSTC_BOOTSTRAP = true;` can somet ::: There are two community maintained approaches to Rust toolchain management: + - [oxalica's Rust overlay](https://github.com/oxalica/rust-overlay) - [fenix](https://github.com/nix-community/fenix) @@ -1003,6 +1007,7 @@ rustPlatform.buildRustPackage rec { ``` Follow the below steps to try that snippet. + 1. save the above snippet as `default.nix` in that directory 2. cd into that directory and run `nix-build` @@ -1014,12 +1019,12 @@ and cross compilation in its [Examples](https://github.com/nix-community/fenix#e ## Using `git bisect` on the Rust compiler {#using-git-bisect-on-the-rust-compiler} Sometimes an upgrade of the Rust compiler (`rustc`) will break a -downstream package. In these situations, being able to `git bisect` +downstream package. In these situations, being able to `git bisect` the `rustc` version history to find the offending commit is quite -useful. Nixpkgs makes it easy to do this. +useful. Nixpkgs makes it easy to do this. First, roll back your nixpkgs to a commit in which its `rustc` used -*the most recent one which doesn't have the problem.* You'll need +_the most recent one which doesn't have the problem._ You'll need to do this because of `rustc`'s extremely aggressive version-pinning. @@ -1047,14 +1052,14 @@ repository: If the problem you're troubleshooting only manifests when cross-compiling you can uncomment the `lib.optionalAttrs` in the example above, and replace `isAarch64` with the target that is -having problems. This will speed up your bisect quite a bit, since +having problems. This will speed up your bisect quite a bit, since the host compiler won't need to be rebuilt. Now, you can start a `git bisect` in the directory where you checked -out the `rustc` source code. It is recommended to select the +out the `rustc` source code. It is recommended to select the endpoint commits by searching backwards from `origin/master` for the -*commits which added the release notes for the versions in -question.* If you set the endpoints to commits on the release +_commits which added the release notes for the versions in +question._ If you set the endpoints to commits on the release branches (i.e. the release tags), git-bisect will often get confused by the complex merge-commit structures it will need to traverse. diff --git a/doc/languages-frameworks/swift.section.md b/doc/languages-frameworks/swift.section.md index 88d98deeb2dd3..b67dfc052ccff 100644 --- a/doc/languages-frameworks/swift.section.md +++ b/doc/languages-frameworks/swift.section.md @@ -69,42 +69,55 @@ This produces some files in a directory `nix`, which will be part of your Nix expression. The next step is to write that expression: ```nix -{ stdenv, swift, swiftpm, swiftpm2nix, fetchFromGitHub }: +{ + stdenv, + swift, + swiftpm, + swiftpm2nix, + fetchFromGitHub, +}: let # Pass the generated files to the helper. generated = swiftpm2nix.helpers ./nix; in -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "myproject"; version = "0.0.0"; src = fetchFromGitHub { owner = "nixos"; - repo = pname; - rev = version; + repo = "myproject"; + tag = finalAttrs.version; hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; # Including SwiftPM as a nativeBuildInput provides a buildPhase for you. # This by default performs a release build using SwiftPM, essentially: # swift build -c release - nativeBuildInputs = [ swift swiftpm ]; + nativeBuildInputs = [ + swift + swiftpm + ]; # The helper provides a configure snippet that will prepare all dependencies # in the correct place, where SwiftPM expects them. configurePhase = generated.configure; installPhase = '' + runHook preInstall + # This is a special function that invokes swiftpm to find the location # of the binaries it produced. binPath="$(swiftpmBinPath)" # Now perform any installation steps. mkdir -p $out/bin cp $binPath/myproject $out/bin/ + + runHook postInstall ''; -} +}) ``` ### Custom build flags {#ssec-swiftpm-custom-build-flags} diff --git a/doc/languages-frameworks/texlive.section.md b/doc/languages-frameworks/texlive.section.md index a31a4357a22f5..17a3213605af4 100644 --- a/doc/languages-frameworks/texlive.section.md +++ b/doc/languages-frameworks/texlive.section.md @@ -81,18 +81,20 @@ Release 23.11 ships with a new interface that will eventually replace `texlive.c - TeX Live packages are also available under `texlive.pkgs` as derivations with outputs `out`, `tex`, `texdoc`, `texsource`, `tlpkg`, `man`, `info`. They cannot be installed outside of `texlive.combine` but are available for other uses. To repackage a font, for instance, use ```nix - stdenvNoCC.mkDerivation rec { + stdenvNoCC.mkDerivation (finalAttrs: { src = texlive.pkgs.iwona; dontUnpack = true; - inherit (src) pname version; + inherit (finalAttrs.src) pname version; installPhase = '' runHook preInstall + install -Dm644 $src/fonts/opentype/nowacki/iwona/*.otf -t $out/share/fonts/opentype + runHook postInstall ''; - } + }) ``` See `biber`, `iwona` for complete examples. diff --git a/doc/packages/cataclysm-dda.section.md b/doc/packages/cataclysm-dda.section.md index f401e9b9efa53..b038ae91fee8d 100644 --- a/doc/packages/cataclysm-dda.section.md +++ b/doc/packages/cataclysm-dda.section.md @@ -102,7 +102,7 @@ let src = fetchFromGitHub { owner = "Someone"; repo = "AwesomeMod"; - rev = "..."; + tag = "..."; hash = "..."; }; # Path to be installed in the unpacked source (default: ".") diff --git a/doc/packages/weechat.section.md b/doc/packages/weechat.section.md index 295397f476b04..b056decee3e8f 100644 --- a/doc/packages/weechat.section.md +++ b/doc/packages/weechat.section.md @@ -77,9 +77,13 @@ stdenv.mkDerivation { }; passthru.scripts = [ "foo.py" "bar.lua" ]; installPhase = '' + runHook preInstall + mkdir $out/share cp foo.py $out/share cp bar.lua $out/share + + runHook postInstall ''; } ``` diff --git a/doc/stdenv/stdenv.chapter.md b/doc/stdenv/stdenv.chapter.md index 80059a78733c3..62cfe0631704f 100644 --- a/doc/stdenv/stdenv.chapter.md +++ b/doc/stdenv/stdenv.chapter.md @@ -20,14 +20,14 @@ stdenv.mkDerivation { **Since [RFC 0035](https://github.com/NixOS/rfcs/pull/35), this is preferred for packages in Nixpkgs**, as it allows us to reuse the version easily: ```nix -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "libfoo"; version = "1.2.3"; src = fetchurl { - url = "http://example.org/libfoo-source-${version}.tar.bz2"; + url = "http://example.org/libfoo-source-${finalAttrs.version}.tar.bz2"; hash = "sha256-tWxU/LANbQE32my+9AXyt3nCT7NBVfJ45CX757EMT3Q="; }; -} +}) ``` Many packages have dependencies that are not provided in the standard environment. It’s usually sufficient to specify those dependencies in the `buildInputs` attribute: @@ -51,12 +51,20 @@ stdenv.mkDerivation { version = "4.5"; # ... buildPhase = '' + runHook preBuild + gcc foo.c -o foo + + runHook postBuild ''; installPhase = '' + runHook preInstall + mkdir -p $out/bin cp foo $out/bin - ''; + + runHook postInstall +''; } ``` @@ -207,8 +215,23 @@ These dependencies are only injected when [`doCheck`](#var-stdenv-doCheck) is se #### Example {#ssec-stdenv-dependencies-overview-example} Consider for example this simplified derivation for `solo5`, a sandboxing tool: + ```nix -stdenv.mkDerivation rec { +{ + lib, + stdenv, + fetchurl, + makeWrapper, + pkg-config, + libseccomp, + dosfstools, + mtools, + parted, + syslinux, + util-linux, + qemu, +}: +stdenv.mkDerivation (finalAttrs: { pname = "solo5"; version = "0.7.5"; @@ -217,7 +240,10 @@ stdenv.mkDerivation rec { hash = "sha256-viwrS9lnaU8sTGuzK/+L/PlMM/xRRtgVuK5pixVeDEw="; }; - nativeBuildInputs = [ makeWrapper pkg-config ]; + nativeBuildInputs = [ + makeWrapper + pkg-config + ]; buildInputs = [ libseccomp ]; postInstall = '' @@ -227,13 +253,23 @@ stdenv.mkDerivation rec { --replace-fail "cp " "cp --no-preserve=mode " wrapProgram $out/bin/solo5-virtio-mkimage \ - --prefix PATH : ${lib.makeBinPath [ dosfstools mtools parted syslinux ]} + --prefix PATH : ${ + lib.makeBinPath [ + dosfstools + mtools + parted + syslinux + ] + } ''; doCheck = true; - nativeCheckInputs = [ util-linux qemu ]; - checkPhase = '' [elided] ''; -} + nativeCheckInputs = [ + util-linux + qemu + ]; + checkPhase = ''[elided] ''; +}) ``` - `makeWrapper` is a setup hook, i.e., a shell script sourced by the generic builder of `stdenv`. diff --git a/nixos/doc/manual/configuration/adding-custom-packages.section.md b/nixos/doc/manual/configuration/adding-custom-packages.section.md index f2012d9c24626..20fc79406ce7c 100644 --- a/nixos/doc/manual/configuration/adding-custom-packages.section.md +++ b/nixos/doc/manual/configuration/adding-custom-packages.section.md @@ -43,13 +43,13 @@ tree. For instance, here is how you specify a build of the { environment.systemPackages = let - my-hello = with pkgs; stdenv.mkDerivation rec { + my-hello = stdenv.mkDerivation (finalAttrs: { name = "hello-2.8"; - src = fetchurl { - url = "mirror://gnu/hello/${name}.tar.gz"; + src = pkgs.fetchurl { + url = "mirror://gnu/hello/${finalAttrs.name}.tar.gz"; hash = "sha256-5rd/gffPfa761Kn1tl3myunD8TuM+66oy1O7XqVGDXM="; }; - }; + }); in [ my-hello ]; } @@ -69,13 +69,13 @@ where `my-hello.nix` contains: ```nix with import {}; # bring all of Nixpkgs into scope -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { name = "hello-2.8"; src = fetchurl { - url = "mirror://gnu/hello/${name}.tar.gz"; + url = "mirror://gnu/hello/${finalAttrs.name}.tar.gz"; hash = "sha256-5rd/gffPfa761Kn1tl3myunD8TuM+66oy1O7XqVGDXM="; }; -} +}) ``` This allows testing the package easily: