1# Trivial build helpers {#chap-trivial-builders}
2
3Nixpkgs provides a variety of wrapper functions that help build commonly useful derivations.
4Like [`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`.
5
6## `runCommand` {#trivial-builder-runCommand}
7
8`runCommand :: String -> AttrSet -> String -> Derivation`
9
10The result of `runCommand name drvAttrs buildCommand` is a derivation that is built by running the specified shell commands.
11
12By default `runCommand` runs in a stdenv with no compiler environment, whereas [`runCommandCC`](#trivial-builder-runCommandCC) uses the default stdenv, `pkgs.stdenv`.
13
14`name :: String`
15: The name that Nix will append to the store path in the same way that `stdenv.mkDerivation` uses its `name` attribute.
16
17`drvAttr :: AttrSet`
18: Attributes to pass to the underlying call to [`stdenv.mkDerivation`](#chap-stdenv).
19
20`buildCommand :: String`
21: Shell commands to run in the derivation builder.
22
23 ::: {.note}
24 You have to create a file or directory `$out` for Nix to be able to run the builder successfully.
25 :::
26
27::: {.example #ex-runcommand-simple}
28# Invocation of `runCommand`
29
30```nix
31(import <nixpkgs> {}).runCommand "my-example" {} ''
32 echo My example command is running
33
34 mkdir $out
35
36 echo I can write data to the Nix store > $out/message
37
38 echo I can also run basic commands like:
39
40 echo ls
41 ls
42
43 echo whoami
44 whoami
45
46 echo date
47 date
48''
49```
50:::
51
52## `runCommandCC` {#trivial-builder-runCommandCC}
53
54This 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.
55
56## `runCommandLocal` {#trivial-builder-runCommandLocal}
57
58Variant 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.
59
60::: {.note}
61This 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`.
62:::
63
64## Writing text files {#trivial-builder-text-writing}
65
66Nixpkgs provides the following functions for producing derivations which write text files or executable scripts into the Nix store.
67They are useful for creating files from Nix expression, and are all implemented as convenience wrappers around `writeTextFile`.
68
69Each of these functions will cause a derivation to be produced.
70When 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.
71
72:::: {.note}
73Some 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).
74If you need to refer to the resulting files somewhere else in a Nix expression, append their path to the derivation's store path.
75
76For example, if the file destination is a directory:
77
78```nix
79{
80 my-file = writeTextFile {
81 name = "my-file";
82 text = ''
83 Contents of File
84 '';
85 destination = "/share/my-file";
86 };
87}
88```
89
90Remember to append "/share/my-file" to the resulting store path when using it elsewhere:
91
92```nix
93writeShellScript "evaluate-my-file.sh" ''
94 cat ${my-file}/share/my-file
95''
96```
97::::
98
99### `makeDesktopItem` {#trivial-builder-makeDesktopItem}
100
101Write an [XDG desktop file](https://specifications.freedesktop.org/desktop-entry-spec/1.4/) to the Nix store.
102
103This function is usually used to add desktop items to a package through the `copyDesktopItems` hook.
104
105`makeDesktopItem` adheres to version 1.4 of the specification.
106
107#### Inputs {#trivial-builder-makeDesktopItem-inputs}
108
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).
110
111All 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`.
112
113The "Version" field is hardcoded to the version `makeDesktopItem` currently adheres to.
114
115The 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`:
116
117`name` (String)
118
119: The name of the desktop file in the Nix store.
120
121`type` (String; _optional_)
122
123: Default value: `"Application"`
124
125`desktopName` (String)
126
127: Corresponds to the "Name" field of the specification.
128
129`actions` (List of Attribute set; _optional_)
130
131: A list of attribute sets {name, exec?, icon?}
132
133`extraConfig` (Attribute set; _optional_)
134
135: Additional key/value pairs to be added verbatim to the desktop file. Attributes need to be prefixed with 'X-'.
136
137#### Examples {#trivial-builder-makeDesktopItem-examples}
138
139::: {.example #ex-makeDesktopItem}
140# Usage 1 of `makeDesktopItem`
141
142Write a desktop file `/nix/store/<store path>/my-program.desktop` to the Nix store.
143
144```nix
145{makeDesktopItem}:
146makeDesktopItem {
147 name = "my-program";
148 desktopName = "My Program";
149 genericName = "Video Player";
150 noDisplay = false;
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";
158 terminal = false;
159 actions.example = {
160 name = "New Window";
161 exec = "my-program --new-window";
162 icon = "/some/icon";
163 };
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";
172}
173```
174
175:::
176
177::: {.example #ex2-makeDesktopItem}
178# Usage 2 of `makeDesktopItem`
179
180Override the `hello` package to add a desktop item.
181
182```nix
183{ copyDesktopItems
184, hello
185, makeDesktopItem }:
186
187hello.overrideAttrs {
188 nativeBuildInputs = [ copyDesktopItems ];
189
190 desktopItems = [(makeDesktopItem {
191 name = "hello";
192 desktopName = "Hello";
193 exec = "hello";
194 })];
195}
196```
197
198:::
199
200### `writeTextFile` {#trivial-builder-writeTextFile}
201
202Write a text file to the Nix store.
203
204`writeTextFile` takes an attribute set with the following possible attributes:
205
206`name` (String)
207
208: Corresponds to the name used in the Nix store path identifier.
209
210`text` (String)
211
212: The contents of the file.
213
214`executable` (Bool, _optional_)
215
216: Make this file have the executable bit set.
217
218 Default: `false`
219
220`destination` (String, _optional_)
221
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.
224
225 By default, the store path itself will be a file containing the text contents.
226
227 Default: `""`
228
229`checkPhase` (String, _optional_)
230
231: Commands to run after generating the file.
232
233 Default: `""`
234
235`meta` (Attribute set, _optional_)
236
237: Additional metadata for the derivation.
238
239 Default: `{}`
240
241`allowSubstitutes` (Bool, _optional_)
242
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`.
245
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.
248
249 Default: `false`
250
251`preferLocalBuild` (Bool, _optional_)
252
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.
254
255 Passed through to [`preferLocalBuild`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-preferLocalBuild) of the underlying call to `builtins.derivation`.
256
257 It defaults to `true` for the same reason `allowSubstitutes` defaults to `false`.
258
259 Default: `true`
260
261`derivationArgs` (Attribute set, _optional_)
262
263: Extra arguments to pass to the underlying call to `stdenv.mkDerivation`.
264
265 Default: `{}`
266
267The 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.
268
269::: {.example #ex-writeTextFile}
270# Usage 1 of `writeTextFile`
271
272Write `my-file` to `/nix/store/<store path>/some/subpath/my-cool-script`, making it executable.
273Also run a check on the resulting file in a `checkPhase`, and supply values for the less-used options.
274
275```nix
276writeTextFile {
277 name = "my-cool-script";
278 text = ''
279 #!/bin/sh
280 echo "This is my cool script!"
281 '';
282 executable = true;
283 destination = "/some/subpath/my-cool-script";
284 checkPhase = ''
285 ${pkgs.shellcheck}/bin/shellcheck $out/some/subpath/my-cool-script
286 '';
287 meta = {
288 license = pkgs.lib.licenses.cc0;
289 };
290 allowSubstitutes = true;
291 preferLocalBuild = false;
292}
293```
294:::
295
296::: {.example #ex2-writeTextFile}
297# Usage 2 of `writeTextFile`
298
299Write the string `Contents of File` to `/nix/store/<store path>`.
300See also the [](#trivial-builder-writeText) helper function.
301
302```nix
303writeTextFile {
304 name = "my-file";
305 text = ''
306 Contents of File
307 '';
308}
309```
310:::
311
312::: {.example #ex3-writeTextFile}
313# Usage 3 of `writeTextFile`
314
315Write an executable script `my-script` to `/nix/store/<store path>/bin/my-script`.
316See also the [](#trivial-builder-writeScriptBin) helper function.
317
318```nix
319writeTextFile {
320 name = "my-script";
321 text = ''
322 echo "hi"
323 '';
324 executable = true;
325 destination = "/bin/my-script";
326}
327```
328:::
329
330### `writeText` {#trivial-builder-writeText}
331
332Write a text file to the Nix store
333
334`writeText` takes the following arguments:
335a string.
336
337`name` (String)
338
339: The name used in the Nix store path.
340
341`text` (String)
342
343: The contents of the file.
344
345The store path will include the name, and it will be a file.
346
347::: {.example #ex-writeText}
348# Usage of `writeText`
349
350Write the string `Contents of File` to `/nix/store/<store path>`:
351
352```nix
353writeText "my-file"
354 ''
355 Contents of File
356 ''
357```
358:::
359
360This is equivalent to:
361
362```nix
363writeTextFile {
364 name = "my-file";
365 text = ''
366 Contents of File
367 '';
368}
369```
370
371### `writeTextDir` {#trivial-builder-writeTextDir}
372
373Write a text file within a subdirectory of the Nix store.
374
375`writeTextDir` takes the following arguments:
376
377`path` (String)
378
379: The destination within the Nix store path under which to create the file.
380
381`text` (String)
382
383: The contents of the file.
384
385The store path will be a directory.
386
387::: {.example #ex-writeTextDir}
388# Usage of `writeTextDir`
389
390Write the string `Contents of File` to `/nix/store/<store path>/share/my-file`:
391
392```nix
393writeTextDir "share/my-file"
394 ''
395 Contents of File
396 ''
397```
398:::
399
400This is equivalent to:
401
402```nix
403writeTextFile {
404 name = "my-file";
405 text = ''
406 Contents of File
407 '';
408 destination = "share/my-file";
409}
410```
411
412### `writeScript` {#trivial-builder-writeScript}
413
414Write an executable script file to the Nix store.
415
416`writeScript` takes the following arguments:
417
418`name` (String)
419
420: The name used in the Nix store path.
421
422`text` (String)
423
424: The contents of the file.
425
426The created file is marked as executable.
427The store path will include the name, and it will be a file.
428
429::: {.example #ex-writeScript}
430# Usage of `writeScript`
431
432Write the string `Contents of File` to `/nix/store/<store path>` and make the file executable.
433
434```nix
435writeScript "my-file"
436 ''
437 Contents of File
438 ''
439```
440:::
441
442This is equivalent to:
443
444```nix
445writeTextFile {
446 name = "my-file";
447 text = ''
448 Contents of File
449 '';
450 executable = true;
451}
452```
453
454### `writeScriptBin` {#trivial-builder-writeScriptBin}
455
456Write a script within a `bin` subirectory of a directory in the Nix store.
457This is for consistency with the convention of software packages placing executables under `bin`.
458
459`writeScriptBin` takes the following arguments:
460
461`name` (String)
462
463: The name used in the Nix store path and within the file created under the store path.
464
465`text` (String)
466
467: The contents of the file.
468
469The created file is marked as executable.
470The file's contents will be put into `/nix/store/<store path>/bin/<name>`.
471The store path will include the the name, and it will be a directory.
472
473::: {.example #ex-writeScriptBin}
474# Usage of `writeScriptBin`
475
476```nix
477writeScriptBin "my-script"
478 ''
479 echo "hi"
480 ''
481```
482:::
483
484This is equivalent to:
485
486```nix
487writeTextFile {
488 name = "my-script";
489 text = ''
490 echo "hi"
491 '';
492 executable = true;
493 destination = "bin/my-script";
494}
495```
496
497### `writeShellScript` {#trivial-builder-writeShellScript}
498
499Write a Bash script to the store.
500
501`writeShellScript` takes the following arguments:
502
503`name` (String)
504
505: The name used in the Nix store path.
506
507`text` (String)
508
509: The contents of the file.
510
511The created file is marked as executable.
512The store path will include the name, and it will be a file.
513
514This 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 -->
516
517::: {.example #ex-writeShellScript}
518# Usage of `writeShellScript`
519
520```nix
521writeShellScript "my-script"
522 ''
523 echo "hi"
524 ''
525```
526:::
527
528This is equivalent to:
529
530```nix
531writeTextFile {
532 name = "my-script";
533 text = ''
534 #! ${pkgs.runtimeShell}
535 echo "hi"
536 '';
537 executable = true;
538}
539```
540
541### `writeShellScriptBin` {#trivial-builder-writeShellScriptBin}
542
543Write a Bash script to a "bin" subdirectory of a directory in the Nix store.
544
545`writeShellScriptBin` takes the following arguments:
546
547`name` (String)
548
549: The name used in the Nix store path and within the file generated under the store path.
550
551`text` (String)
552
553: The contents of the file.
554
555The file's contents will be put into `/nix/store/<store path>/bin/<name>`.
556The store path will include the the name, and it will be a directory.
557
558This function is a combination of [](#trivial-builder-writeShellScript) and [](#trivial-builder-writeScriptBin).
559
560::: {.example #ex-writeShellScriptBin}
561# Usage of `writeShellScriptBin`
562
563```nix
564writeShellScriptBin "my-script"
565 ''
566 echo "hi"
567 ''
568```
569:::
570
571This is equivalent to:
572
573```nix
574writeTextFile {
575 name = "my-script";
576 text = ''
577 #! ${pkgs.runtimeShell}
578 echo "hi"
579 '';
580 executable = true;
581 destination = "bin/my-script";
582}
583```
584
585## `concatTextFile`, `concatText`, `concatScript` {#trivial-builder-concatText}
586
587These 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`.
589
590Here are a few examples:
591```nix
592
593# Writes my-file to /nix/store/<store path>
594concatTextFile {
595 name = "my-file";
596 files = [ drv1 "${drv2}/path/to/file" ];
597}
598# See also the `concatText` helper function below.
599
600# Writes executable my-file to /nix/store/<store path>/bin/my-file
601concatTextFile {
602 name = "my-file";
603 files = [ drv1 "${drv2}/path/to/file" ];
604 executable = true;
605 destination = "/bin/my-file";
606}
607# Writes contents of files to /nix/store/<store path>
608concatText "my-file" [ file1 file2 ]
609
610# Writes contents of files to /nix/store/<store path>
611concatScript "my-file" [ file1 file2 ]
612```
613
614## `writeShellApplication` {#trivial-builder-writeShellApplication}
615
616`writeShellApplication` is similar to `writeShellScriptBin` and `writeScriptBin` but supports runtime dependencies with `runtimeInputs`.
617Writes 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.
618Some basic Bash options are set by default (`errexit`, `nounset`, and `pipefail`), but can be overridden with `bashOptions`.
619
620Extra 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.
621Runtime environment variables can be set with the `runtimeEnv` argument.
622
623For example, the following shell application can refer to `curl` directly, rather than needing to write `${curl}/bin/curl`:
624
625```nix
626writeShellApplication {
627 name = "show-nixos-org";
628
629 runtimeInputs = [ curl w3m ];
630
631 text = ''
632 curl -s 'https://nixos.org' | w3m -dump -T text/html
633 '';
634}
635```
636
637## `symlinkJoin` {#trivial-builder-symlinkJoin}
638
639This 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.
640Here is an example:
641```nix
642# adds symlinks of hello and stack to current build and prints "links added"
643symlinkJoin { name = "myexample"; paths = [ pkgs.hello pkgs.stack ]; postBuild = "echo links added"; }
644```
645This creates a derivation with a directory structure like the following:
646```
647/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample
648|-- bin
649| |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello
650| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack
651`-- share
652 |-- bash-completion
653 | `-- completions
654 | `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack
655 |-- fish
656 | `-- vendor_completions.d
657 | `-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish
658...
659```
660
661## `writeReferencesToFile` {#trivial-builder-writeReferencesToFile}
662
663Deprecated. Use [`writeClosure`](#trivial-builder-writeClosure) instead.
664
665## `writeClosure` {#trivial-builder-writeClosure}
666
667Given 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.
668
669The result is equivalent to the output of `nix-store -q --requisites`.
670
671For example,
672
673```nix
674writeClosure [ (writeScriptBin "hi" ''${hello}/bin/hello'') ]
675```
676
677produces an output path `/nix/store/<hash>-runtime-deps` containing
678
679```
680/nix/store/<hash>-hello-2.10
681/nix/store/<hash>-hi
682/nix/store/<hash>-libidn2-2.3.0
683/nix/store/<hash>-libunistring-0.9.10
684/nix/store/<hash>-glibc-2.32-40
685```
686
687You can see that this includes `hi`, the original input path,
688`hello`, which is a direct reference, but also
689the other paths that are indirectly required to run `hello`.
690
691## `writeDirectReferencesToFile` {#trivial-builder-writeDirectReferencesToFile}
692
693Writes the set of references to the output file, that is, their immediate dependencies.
694
695This produces the equivalent of `nix-store -q --references`.
696
697For example,
698
699```nix
700writeDirectReferencesToFile (writeScriptBin "hi" ''${hello}/bin/hello'')
701```
702
703produces an output path `/nix/store/<hash>-runtime-references` containing
704
705```
706/nix/store/<hash>-hello-2.10
707```
708
709but none of `hello`'s dependencies because those are not referenced directly
710by `hi`'s output.