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.