1 # Trivial build helpers {#chap-trivial-builders}
3 Nixpkgs provides a variety of wrapper functions that help build commonly useful derivations.
4 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`.
6 ## `runCommand` {#trivial-builder-runCommand}
8 `runCommand :: String -> AttrSet -> String -> Derivation`
10 The result of `runCommand name drvAttrs buildCommand` is a derivation that is built by running the specified shell commands.
12 By default `runCommand` runs in a stdenv with no compiler environment, whereas [`runCommandCC`](#trivial-builder-runCommandCC) uses the default stdenv, `pkgs.stdenv`.
15 : The name that Nix will append to the store path in the same way that `stdenv.mkDerivation` uses its `name` attribute.
18 : Attributes to pass to the underlying call to [`stdenv.mkDerivation`](#chap-stdenv).
20 `buildCommand :: String`
21 : Shell commands to run in the derivation builder.
24 You have to create a file or directory `$out` for Nix to be able to run the builder successfully.
27 ::: {.example #ex-runcommand-simple}
28 # Invocation of `runCommand`
31 (import <nixpkgs> {}).runCommand "my-example" {} ''
32 echo My example command is running
36 echo I can write data to the Nix store > $out/message
38 echo I can also run basic commands like:
52 ## `runCommandCC` {#trivial-builder-runCommandCC}
54 This works just like `runCommand`. The only difference is that it also provides a C compiler in `buildCommand`'s environment. To minimize your dependencies, you should only use this if you are sure you will need a C compiler as part of running your command.
56 ## `runCommandLocal` {#trivial-builder-runCommandLocal}
58 Variant of `runCommand` that forces the derivation to be built locally, it is not substituted. This is intended for very cheap commands (<1s execution time). It saves on the network round-trip and can speed up a build.
61 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`.
64 ## Writing text files {#trivial-builder-text-writing}
66 Nixpkgs provides the following functions for producing derivations which write text files or executable scripts into the Nix store.
67 They are useful for creating files from Nix expression, and are all implemented as convenience wrappers around `writeTextFile`.
69 Each of these functions will cause a derivation to be produced.
70 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.
73 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).
74 If you need to refer to the resulting files somewhere else in a Nix expression, append their path to the derivation's store path.
76 For example, if the file destination is a directory:
80 my-file = writeTextFile {
85 destination = "/share/my-file";
90 Remember to append "/share/my-file" to the resulting store path when using it elsewhere:
93 writeShellScript "evaluate-my-file.sh" ''
94 cat ${my-file}/share/my-file
99 ### `makeDesktopItem` {#trivial-builder-makeDesktopItem}
101 Write an [XDG desktop file](https://specifications.freedesktop.org/desktop-entry-spec/1.4/) to the Nix store.
103 This function is usually used to add desktop items to a package through the `copyDesktopItems` hook.
105 `makeDesktopItem` adheres to version 1.4 of the specification.
107 #### Inputs {#trivial-builder-makeDesktopItem-inputs}
109 `makeDesktopItem` takes an attribute set that accepts most values from the [XDG specification](https://specifications.freedesktop.org/desktop-entry-spec/1.4/ar01s06.html).
111 All recognised keys from the specification are supported with the exception of the "Hidden" field. The keys are converted into camelCase format, but correspond 1:1 to their equivalent in the specification: `genericName`, `noDisplay`, `comment`, `icon`, `onlyShowIn`, `notShowIn`, `dbusActivatable`, `tryExec`, `exec`, `path`, `terminal`, `mimeTypes`, `categories`, `implements`, `keywords`, `startupNotify`, `startupWMClass`, `url`, `prefersNonDefaultGPU`.
113 The "Version" field is hardcoded to the version `makeDesktopItem` currently adheres to.
115 The following fields are either required, are of a different type than in the specification, carry specific default values, or are additional fields supported by `makeDesktopItem`:
119 : The name of the desktop file in the Nix store.
121 `type` (String; _optional_)
123 : Default value: `"Application"`
125 `desktopName` (String)
127 : Corresponds to the "Name" field of the specification.
129 `actions` (List of Attribute set; _optional_)
131 : A list of attribute sets {name, exec?, icon?}
133 `extraConfig` (Attribute set; _optional_)
135 : Additional key/value pairs to be added verbatim to the desktop file. Attributes need to be prefixed with 'X-'.
137 #### Examples {#trivial-builder-makeDesktopItem-examples}
139 ::: {.example #ex-makeDesktopItem}
140 # Usage 1 of `makeDesktopItem`
142 Write a desktop file `/nix/store/<store path>/my-program.desktop` to the Nix store.
148 desktopName = "My Program";
149 genericName = "Video Player";
151 comment = "Cool video player";
152 icon = "/path/to/icon";
153 onlyShowIn = [ "KDE" ];
154 dbusActivatable = true;
155 tryExec = "my-program";
156 exec = "my-program --someflag";
157 path = "/some/working/path";
161 exec = "my-program --new-window";
164 mimeTypes = [ "video/mp4" ];
165 categories = [ "Utility" ];
166 implements = [ "org.my-program" ];
167 keywords = [ "Video" "Player" ];
168 startupNotify = false;
169 startupWMClass = "MyProgram";
170 prefersNonDefaultGPU = false;
171 extraConfig.X-SomeExtension = "somevalue";
177 ::: {.example #ex2-makeDesktopItem}
178 # Usage 2 of `makeDesktopItem`
180 Override the `hello` package to add a desktop item.
187 hello.overrideAttrs {
188 nativeBuildInputs = [ copyDesktopItems ];
190 desktopItems = [(makeDesktopItem {
192 desktopName = "Hello";
200 ### `writeTextFile` {#trivial-builder-writeTextFile}
202 Write a text file to the Nix store.
204 `writeTextFile` takes an attribute set with the following possible attributes:
208 : Corresponds to the name used in the Nix store path identifier.
212 : The contents of the file.
214 `executable` (Bool, _optional_)
216 : Make this file have the executable bit set.
220 `destination` (String, _optional_)
222 : A subpath under the derivation's output path into which to put the file.
223 Subdirectories are created automatically when the derivation is realised.
225 By default, the store path itself will be a file containing the text contents.
229 `checkPhase` (String, _optional_)
231 : Commands to run after generating the file.
235 `meta` (Attribute set, _optional_)
237 : Additional metadata for the derivation.
241 `allowSubstitutes` (Bool, _optional_)
243 : Whether to allow substituting from a binary cache.
244 Passed through to [`allowSubsitutes`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-allowSubstitutes) of the underlying call to `builtins.derivation`.
246 It defaults to `false`, as running the derivation's simple `builder` executable locally is assumed to be faster than network operations.
247 Set it to true if the `checkPhase` step is expensive.
251 `preferLocalBuild` (Bool, _optional_)
253 : 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.
255 Passed through to [`preferLocalBuild`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-preferLocalBuild) of the underlying call to `builtins.derivation`.
257 It defaults to `true` for the same reason `allowSubstitutes` defaults to `false`.
261 `derivationArgs` (Attribute set, _optional_)
263 : Extra arguments to pass to the underlying call to `stdenv.mkDerivation`.
267 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.
269 ::: {.example #ex-writeTextFile}
270 # Usage 1 of `writeTextFile`
272 Write `my-file` to `/nix/store/<store path>/some/subpath/my-cool-script`, making it executable.
273 Also run a check on the resulting file in a `checkPhase`, and supply values for the less-used options.
277 name = "my-cool-script";
280 echo "This is my cool script!"
283 destination = "/some/subpath/my-cool-script";
285 ${pkgs.shellcheck}/bin/shellcheck $out/some/subpath/my-cool-script
288 license = pkgs.lib.licenses.cc0;
290 allowSubstitutes = true;
291 preferLocalBuild = false;
296 ::: {.example #ex2-writeTextFile}
297 # Usage 2 of `writeTextFile`
299 Write the string `Contents of File` to `/nix/store/<store path>`.
300 See also the [](#trivial-builder-writeText) helper function.
312 ::: {.example #ex3-writeTextFile}
313 # Usage 3 of `writeTextFile`
315 Write an executable script `my-script` to `/nix/store/<store path>/bin/my-script`.
316 See also the [](#trivial-builder-writeScriptBin) helper function.
325 destination = "/bin/my-script";
330 ### `writeText` {#trivial-builder-writeText}
332 Write a text file to the Nix store
334 `writeText` takes the following arguments:
339 : The name used in the Nix store path.
343 : The contents of the file.
345 The store path will include the name, and it will be a file.
347 ::: {.example #ex-writeText}
348 # Usage of `writeText`
350 Write the string `Contents of File` to `/nix/store/<store path>`:
360 This is equivalent to:
371 ### `writeTextDir` {#trivial-builder-writeTextDir}
373 Write a text file within a subdirectory of the Nix store.
375 `writeTextDir` takes the following arguments:
379 : The destination within the Nix store path under which to create the file.
383 : The contents of the file.
385 The store path will be a directory.
387 ::: {.example #ex-writeTextDir}
388 # Usage of `writeTextDir`
390 Write the string `Contents of File` to `/nix/store/<store path>/share/my-file`:
393 writeTextDir "share/my-file"
400 This is equivalent to:
408 destination = "share/my-file";
412 ### `writeScript` {#trivial-builder-writeScript}
414 Write an executable script file to the Nix store.
416 `writeScript` takes the following arguments:
420 : The name used in the Nix store path.
424 : The contents of the file.
426 The created file is marked as executable.
427 The store path will include the name, and it will be a file.
429 ::: {.example #ex-writeScript}
430 # Usage of `writeScript`
432 Write the string `Contents of File` to `/nix/store/<store path>` and make the file executable.
435 writeScript "my-file"
442 This is equivalent to:
454 ### `writeScriptBin` {#trivial-builder-writeScriptBin}
456 Write a script within a `bin` subirectory of a directory in the Nix store.
457 This is for consistency with the convention of software packages placing executables under `bin`.
459 `writeScriptBin` takes the following arguments:
463 : The name used in the Nix store path and within the file created under the store path.
467 : The contents of the file.
469 The created file is marked as executable.
470 The file's contents will be put into `/nix/store/<store path>/bin/<name>`.
471 The store path will include the the name, and it will be a directory.
473 ::: {.example #ex-writeScriptBin}
474 # Usage of `writeScriptBin`
477 writeScriptBin "my-script"
484 This is equivalent to:
493 destination = "bin/my-script";
497 ### `writeShellScript` {#trivial-builder-writeShellScript}
499 Write a Bash script to the store.
501 `writeShellScript` takes the following arguments:
505 : The name used in the Nix store path.
509 : The contents of the file.
511 The created file is marked as executable.
512 The store path will include the name, and it will be a file.
514 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.
515 <!-- this cannot be changed in practice, so there is no point pretending it's somehow generic -->
517 ::: {.example #ex-writeShellScript}
518 # Usage of `writeShellScript`
521 writeShellScript "my-script"
528 This is equivalent to:
534 #! ${pkgs.runtimeShell}
541 ### `writeShellScriptBin` {#trivial-builder-writeShellScriptBin}
543 Write a Bash script to a "bin" subdirectory of a directory in the Nix store.
545 `writeShellScriptBin` takes the following arguments:
549 : The name used in the Nix store path and within the file generated under the store path.
553 : The contents of the file.
555 The file's contents will be put into `/nix/store/<store path>/bin/<name>`.
556 The store path will include the the name, and it will be a directory.
558 This function is a combination of [](#trivial-builder-writeShellScript) and [](#trivial-builder-writeScriptBin).
560 ::: {.example #ex-writeShellScriptBin}
561 # Usage of `writeShellScriptBin`
564 writeShellScriptBin "my-script"
571 This is equivalent to:
577 #! ${pkgs.runtimeShell}
581 destination = "bin/my-script";
585 ## `concatTextFile`, `concatText`, `concatScript` {#trivial-builder-concatText}
587 These functions concatenate `files` to the Nix store in a single file. This is useful for configuration files structured in lines of text. `concatTextFile` takes an attribute set and expects two arguments, `name` and `files`. `name` corresponds to the name used in the Nix store path. `files` will be the files to be concatenated. You can also set `executable` to true to make this file have the executable bit set.
588 `concatText` and`concatScript` are simple wrappers over `concatTextFile`.
590 Here are a few examples:
593 # Writes my-file to /nix/store/<store path>
596 files = [ drv1 "${drv2}/path/to/file" ];
598 # See also the `concatText` helper function below.
600 # Writes executable my-file to /nix/store/<store path>/bin/my-file
603 files = [ drv1 "${drv2}/path/to/file" ];
605 destination = "/bin/my-file";
607 # Writes contents of files to /nix/store/<store path>
608 concatText "my-file" [ file1 file2 ]
610 # Writes contents of files to /nix/store/<store path>
611 concatScript "my-file" [ file1 file2 ]
614 ## `writeShellApplication` {#trivial-builder-writeShellApplication}
616 `writeShellApplication` is similar to `writeShellScriptBin` and `writeScriptBin` but supports runtime dependencies with `runtimeInputs`.
617 Writes an executable shell script to `/nix/store/<store path>/bin/<name>` and checks its syntax with [`shellcheck`](https://github.com/koalaman/shellcheck) and the `bash`'s `-n` option.
618 Some basic Bash options are set by default (`errexit`, `nounset`, and `pipefail`), but can be overridden with `bashOptions`.
620 Extra arguments may be passed to `stdenv.mkDerivation` by setting `derivationArgs`; note that variables set in this manner will be set when the shell script is _built,_ not when it's run.
621 Runtime environment variables can be set with the `runtimeEnv` argument.
623 For example, the following shell application can refer to `curl` directly, rather than needing to write `${curl}/bin/curl`:
626 writeShellApplication {
627 name = "show-nixos-org";
629 runtimeInputs = [ curl w3m ];
632 curl -s 'https://nixos.org' | w3m -dump -T text/html
637 ## `symlinkJoin` {#trivial-builder-symlinkJoin}
639 This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, `name`, and `paths`. `name` is the name used in the Nix store path for the created derivation. `paths` is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within.
642 # adds symlinks of hello and stack to current build and prints "links added"
643 symlinkJoin { name = "myexample"; paths = [ pkgs.hello pkgs.stack ]; postBuild = "echo links added"; }
645 This creates a derivation with a directory structure like the following:
647 /nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample
649 | |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello
650 | `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack
654 | `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack
656 | `-- vendor_completions.d
657 | `-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish
661 ## `writeReferencesToFile` {#trivial-builder-writeReferencesToFile}
663 Deprecated. Use [`writeClosure`](#trivial-builder-writeClosure) instead.
665 ## `writeClosure` {#trivial-builder-writeClosure}
667 Given a list of [store paths](https://nixos.org/manual/nix/stable/glossary#gloss-store-path) (or string-like expressions coercible to store paths), write their collective [closure](https://nixos.org/manual/nix/stable/glossary#gloss-closure) to a text file.
669 The result is equivalent to the output of `nix-store -q --requisites`.
674 writeClosure [ (writeScriptBin "hi" ''${hello}/bin/hello'') ]
677 produces an output path `/nix/store/<hash>-runtime-deps` containing
680 /nix/store/<hash>-hello-2.10
682 /nix/store/<hash>-libidn2-2.3.0
683 /nix/store/<hash>-libunistring-0.9.10
684 /nix/store/<hash>-glibc-2.32-40
687 You can see that this includes `hi`, the original input path,
688 `hello`, which is a direct reference, but also
689 the other paths that are indirectly required to run `hello`.
691 ## `writeDirectReferencesToFile` {#trivial-builder-writeDirectReferencesToFile}
693 Writes the set of references to the output file, that is, their immediate dependencies.
695 This produces the equivalent of `nix-store -q --references`.
700 writeDirectReferencesToFile (writeScriptBin "hi" ''${hello}/bin/hello'')
703 produces an output path `/nix/store/<hash>-runtime-references` containing
706 /nix/store/<hash>-hello-2.10
709 but none of `hello`'s dependencies because those are not referenced directly