diff --git a/doc/build-helpers/trivial-build-helpers.chapter.md b/doc/build-helpers/trivial-build-helpers.chapter.md index a0cda86a66071..4648c79855423 100644 --- a/doc/build-helpers/trivial-build-helpers.chapter.md +++ b/doc/build-helpers/trivial-build-helpers.chapter.md @@ -1,6 +1,7 @@ # Trivial build helpers {#chap-trivial-builders} -Nixpkgs provides a couple of functions that help with building derivations. The most important one, `stdenv.mkDerivation`, has already been documented above. The following functions wrap `stdenv.mkDerivation`, making it easier to use in certain cases. +Nixpkgs provides a variety of wrapper functions that help build commonly useful derivations. +Like [`stdenv.mkDerivation`](#sec-using-stdenv), each of these build helpers creates a derivation, but the arguments passed are different (usually simpler) from those required by `stdenv.mkDerivation`. ## `runCommand` {#trivial-builder-runCommand} @@ -58,63 +59,416 @@ Variant of `runCommand` that forces the derivation to be built locally, it is no This sets [`allowSubstitutes` to `false`](https://nixos.org/nix/manual/#adv-attr-allowSubstitutes), so only use `runCommandLocal` if you are certain the user will always have a builder for the `system` of the derivation. This should be true for most trivial use cases (e.g., just copying some files to a different location or adding symlinks) because there the `system` is usually the same as `builtins.currentSystem`. ::: -## `writeTextFile`, `writeText`, `writeTextDir`, `writeScript`, `writeScriptBin` {#trivial-builder-writeText} +## Writing text files {#trivial-builder-text-writing} -These functions write `text` to the Nix store. This is useful for creating scripts from Nix expressions. `writeTextFile` takes an attribute set and expects two arguments, `name` and `text`. `name` corresponds to the name used in the Nix store path. `text` will be the contents of the file. You can also set `executable` to true to make this file have the executable bit set. +Nixpkgs provides the following functions for producing derivations which write text files or executable scripts into the Nix store. +They are useful for creating files from Nix expression, and are all implemented as convenience wrappers around `writeTextFile`. -Many more commands wrap `writeTextFile` including `writeText`, `writeTextDir`, `writeScript`, and `writeScriptBin`. These are convenience functions over `writeTextFile`. +Each of these functions will cause a derivation to be produced. +When you coerce the result of each of these functions to a string with [string interpolation](https://nixos.org/manual/nix/stable/language/string-interpolation) or [`builtins.toString`](https://nixos.org/manual/nix/stable/language/builtins#builtins-toString), it will evaluate to the [store path](https://nixos.org/manual/nix/stable/store/store-path) of this derivation. + +:::: {.note} +Some of these functions will put the resulting files within a directory inside the [derivation output](https://nixos.org/manual/nix/stable/language/derivations#attr-outputs). +If you need to refer to the resulting files somewhere else in a Nix expression, append their path to the derivation's store path. + +For example, if the file destination is a directory: -Here are a few examples: ```nix -# Writes my-file to /nix/store/ -writeTextFile { +my-file = writeTextFile { name = "my-file"; text = '' Contents of File ''; + destination = "/share/my-file"; } -# See also the `writeText` helper function below. +``` -# Writes executable my-file to /nix/store//bin/my-file +Remember to append "/share/my-file" to the resulting store path when using it elsewhere: + +```nix +writeShellScript "evaluate-my-file.sh" '' + cat ${my-file}/share/my-file +''; +``` +:::: + +### `writeTextFile` {#trivial-builder-writeTextFile} + +Write a text file to the Nix store. + +`writeTextFile` takes an attribute set with the following possible attributes: + +`name` (String) + +: Corresponds to the name used in the Nix store path identifier. + +`text` (String) + +: The contents of the file. + +`executable` (Bool, _optional_) + +: Make this file have the executable bit set. + + Default: `false` + +`destination` (String, _optional_) + +: A subpath under the derivation's output path into which to put the file. + Subdirectories are created automatically when the derivation is realised. + + By default, the store path itself will be a file containing the text contents. + + Default: `""` + +`checkPhase` (String, _optional_) + +: Commands to run after generating the file. + + Default: `""` + +`meta` (Attribute set, _optional_) + +: Additional metadata for the derivation. + + Default: `{}` + +`allowSubstitutes` (Bool, _optional_) + +: Whether to allow substituting from a binary cache. + Passed through to [`allowSubsitutes`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-allowSubstitutes) of the underlying call to `builtins.derivation`. + + It defaults to `false`, as running the derivation's simple `builder` executable locally is assumed to be faster than network operations. + Set it to true if the `checkPhase` step is expensive. + + Default: `false` + +`preferLocalBuild` (Bool, _optional_) + +: Whether to prefer building locally, even if faster [remote build machines](https://nixos.org/manual/nix/stable/command-ref/conf-file#conf-substituters) are available. + + Passed through to [`preferLocalBuild`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-preferLocalBuild) of the underlying call to `builtins.derivation`. + + It defaults to `true` for the same reason `allowSubstitutes` defaults to `false`. + + Default: `true` + +The resulting store path will include some variation of the name, and it will be a file unless `destination` is used, in which case it will be a directory. + +::: {.example #ex-writeTextFile} +# Usage 1 of `writeTextFile` + +Write `my-file` to `/nix/store//some/subpath/my-cool-script`, making it executable. +Also run a check on the resulting file in a `checkPhase`, and supply values for the less-used options. + +```nix +writeTextFile { + name = "my-cool-script"; + text = '' + #!/bin/sh + echo "This is my cool script!" + ''; + executable = true; + destination = "/some/subpath/my-cool-script"; + checkPhase = '' + ${pkgs.shellcheck}/bin/shellcheck $out/some/subpath/my-cool-script + ''; + meta = { + license = pkgs.lib.licenses.cc0; + }; + allowSubstitutes = true; + preferLocalBuild = false; +}; +``` +::: + +::: {.example #ex2-writeTextFile} +# Usage 2 of `writeTextFile` + +Write the string `Contents of File` to `/nix/store/`. +See also the [](#trivial-builder-writeText) helper function. + +```nix writeTextFile { name = "my-file"; text = '' Contents of File ''; +} +``` +::: + +::: {.example #ex3-writeTextFile} +# Usage 3 of `writeTextFile` + +Write an executable script `my-script` to `/nix/store//bin/my-script`. +See also the [](#trivial-builder-writeScriptBin) helper function. + +```nix +writeTextFile { + name = "my-script"; + text = '' + echo "hi" + ''; executable = true; - destination = "/bin/my-file"; + destination = "/bin/my-script"; } -# Writes contents of file to /nix/store/ +``` +::: + +### `writeText` {#trivial-builder-writeText} + +Write a text file to the Nix store + +`writeText` takes the following arguments: +a string. + +`name` (String) + +: The name used in the Nix store path. + +`text` (String) + +: The contents of the file. + +The store path will include the name, and it will be a file. + +::: {.example #ex-writeText} +# Usage of `writeText` + +Write the string `Contents of File` to `/nix/store/`: + +```nix writeText "my-file" '' Contents of File ''; -# Writes contents of file to /nix/store//share/my-file +``` +::: + +This is equivalent to: + +```nix +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; +} +``` + +### `writeTextDir` {#trivial-builder-writeTextDir} + +Write a text file within a subdirectory of the Nix store. + +`writeTextDir` takes the following arguments: + +`path` (String) + +: The destination within the Nix store path under which to create the file. + +`text` (String) + +: The contents of the file. + +The store path will be a directory. + +::: {.example #ex-writeTextDir} +# Usage of `writeTextDir` + +Write the string `Contents of File` to `/nix/store//share/my-file`: + +```nix writeTextDir "share/my-file" '' Contents of File ''; -# Writes my-file to /nix/store/ and makes executable +``` +::: + +This is equivalent to: + +```nix +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; + destination = "share/my-file"; +} +``` + +### `writeScript` {#trivial-builder-writeScript} + +Write an executable script file to the Nix store. + +`writeScript` takes the following arguments: + +`name` (String) + +: The name used in the Nix store path. + +`text` (String) + +: The contents of the file. + +The created file is marked as executable. +The store path will include the name, and it will be a file. + +::: {.example #ex-writeScript} +# Usage of `writeScript` + +Write the string `Contents of File` to `/nix/store/` and make the file executable. + +```nix writeScript "my-file" '' Contents of File ''; -# Writes my-file to /nix/store//bin/my-file and makes executable. -writeScriptBin "my-file" +``` +::: + +This is equivalent to: + +```nix +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; + executable = true; +} +``` + +### `writeScriptBin` {#trivial-builder-writeScriptBin} + +Write a script within a `bin` subirectory of a directory in the Nix store. +This is for consistency with the convention of software packages placing executables under `bin`. + +`writeScriptBin` takes the following arguments: + +`name` (String) + +: The name used in the Nix store path and within the file created under the store path. + +`text` (String) + +: The contents of the file. + +The created file is marked as executable. +The file's contents will be put into `/nix/store//bin/`. +The store path will include the the name, and it will be a directory. + +::: {.example #ex-writeScriptBin} +# Usage of `writeScriptBin` + +```nix +writeScriptBin "my-script" '' - Contents of File + echo "hi" ''; -# Writes my-file to /nix/store/ and makes executable. -writeShellScript "my-file" +``` +::: + +This is equivalent to: + +```nix +writeTextFile { + name = "my-script"; + text = '' + echo "hi" + ''; + executable = true; + destination = "bin/my-script" +} +``` + +### `writeShellScript` {#trivial-builder-writeShellScript} + +Write a Bash script to the store. + +`writeShellScript` takes the following arguments: + +`name` (String) + +: The name used in the Nix store path. + +`text` (String) + +: The contents of the file. + +The created file is marked as executable. +The store path will include the name, and it will be a file. + +This function is almost exactly like [](#trivial-builder-writeScript), except that it prepends to the file a [shebang](https://en.wikipedia.org/wiki/Shebang_%28Unix%29) line that points to the version of Bash used in Nixpkgs. + + +::: {.example #ex-writeShellScript} +# Usage of `writeShellScript` + +```nix +writeShellScript "my-script" '' - Contents of File + echo "hi" + ''; +``` +::: + +This is equivalent to: + +```nix +writeTextFile { + name = "my-script"; + text = '' + #! ${pkgs.runtimeShell} + echo "hi" ''; -# Writes my-file to /nix/store//bin/my-file and makes executable. -writeShellScriptBin "my-file" + executable = true; +} +``` + +### `writeShellScriptBin` {#trivial-builder-writeShellScriptBin} + +Write a Bash script to a "bin" subdirectory of a directory in the Nix store. + +`writeShellScriptBin` takes the following arguments: + +`name` (String) + +: The name used in the Nix store path and within the file generated under the store path. + +`text` (String) + +: The contents of the file. + +The file's contents will be put into `/nix/store//bin/`. +The store path will include the the name, and it will be a directory. + +This function is a combination of [](#trivial-builder-writeShellScript) and [](#trivial-builder-writeScriptBin). + +::: {.example #ex-writeShellScriptBin} +# Usage of `writeShellScriptBin` + +```nix +writeShellScriptBin "my-script" '' - Contents of File + echo "hi" ''; +``` +::: + +This is equivalent to: +```nix +writeTextFile { + name = "my-script"; + text = '' + #! ${pkgs.runtimeShell} + echo "hi" + ''; + executable = true; + destination = "bin/my-script" +} ``` ## `concatTextFile`, `concatText`, `concatScript` {#trivial-builder-concatText} diff --git a/pkgs/build-support/trivial-builders/default.nix b/pkgs/build-support/trivial-builders/default.nix index bdb79d9bf463c..93ae83a8ebd16 100644 --- a/pkgs/build-support/trivial-builders/default.nix +++ b/pkgs/build-support/trivial-builders/default.nix @@ -182,101 +182,32 @@ rec { eval "$checkPhase" ''; - /* - Writes a text file to nix store with no optional parameters available. - - Example: - - - # Writes contents of file to /nix/store/ - writeText "my-file" - '' - Contents of File - ''; - - - */ + # See doc/build-helpers/trivial-build-helpers.chapter.md + # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing writeText = name: text: writeTextFile { inherit name text; }; - /* - Writes a text file to nix store in a specific directory with no - optional parameters available. - - Example: - - - # Writes contents of file to /nix/store//share/my-file - writeTextDir "share/my-file" - '' - Contents of File - ''; - - - */ + # See doc/build-helpers/trivial-build-helpers.chapter.md + # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing writeTextDir = path: text: writeTextFile { inherit text; name = builtins.baseNameOf path; destination = "/${path}"; }; - /* - Writes a text file to /nix/store/ and marks the file as - executable. - - If passed as a build input, will be used as a setup hook. This makes setup - hooks more efficient to create: you don't need a derivation that copies - them to $out/nix-support/setup-hook, instead you can use the file as is. - - Example: - - - # Writes my-file to /nix/store/ and makes executable - writeScript "my-file" - '' - Contents of File - ''; - - - */ + # See doc/build-helpers/trivial-build-helpers.chapter.md + # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing writeScript = name: text: writeTextFile { inherit name text; executable = true; }; - /* - Writes a text file to /nix/store//bin/ and - marks the file as executable. - - Example: - - - - # Writes my-file to /nix/store//bin/my-file and makes executable. - writeScriptBin "my-file" - '' - Contents of File - ''; - - - */ + # See doc/build-helpers/trivial-build-helpers.chapter.md + # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing writeScriptBin = name: text: writeTextFile { inherit name text; executable = true; destination = "/bin/${name}"; }; - /* - Similar to writeScript. Writes a Shell script and checks its syntax. - Automatically includes interpreter above the contents passed. - - Example: - - - # Writes my-file to /nix/store/ and makes executable. - writeShellScript "my-file" - '' - Contents of File - ''; - - - */ + # See doc/build-helpers/trivial-build-helpers.chapter.md + # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing writeShellScript = name: text: writeTextFile { inherit name; @@ -290,22 +221,8 @@ rec { ''; }; - /* - Similar to writeShellScript and writeScriptBin. - Writes an executable Shell script to /nix/store//bin/ and checks its syntax. - Automatically includes interpreter above the contents passed. - - Example: - - - # Writes my-file to /nix/store//bin/my-file and makes executable. - writeShellScriptBin "my-file" - '' - Contents of File - ''; - - - */ + # See doc/build-helpers/trivial-build-helpers.chapter.md + # or https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-text-writing writeShellScriptBin = name: text: writeTextFile { inherit name;