Derivations: Difference between revisions
→Low-level derivations: aaaand remove highlights ugh |
Finish rewriting the first section |
||
Line 40: | Line 40: | ||
]; | ]; | ||
}</nowiki>}} | }</nowiki>}} | ||
=== The result of a derivation === | |||
When building a derivation, its result will be added to the Nix store, and a symlink will be provided in the current directory, called <code>result</code>. | |||
The <code>$out</code> variable above has a special meaning in the Nix context: it points to the file that will become the result of the derivation. Thus executing <code>chmod +x $out</code> makes the derivation executable. Because directories on POSIX systems are files themselves, the derivation's result can be an entire directory of files. | |||
The actual directory of <code>$out</code> is an implementation detail abstracted away by Nix and the stdenv builder. Anything placed within <code>$out</code> will then be part of the final derivation. Most derivation aim to follow a FHS-like structure, with the following common subdirectories: | |||
* <code>$out/bin</code> contains binaries; | |||
* <code>$out/lib</code> contains shared objects | |||
* <code>$out/include</code> contains headers | |||
In the context of systems like NixOS or [[Home Manager]], these paths will usually be symlinked into the top-level derivation's directories (the resulting system build). | |||
=== Standard environment derivations === | === Standard environment derivations === | ||
The standard environment provides us with a useful utility function for creating derivations called <code>stdenv.mkDerivation</code>. Among other things, it ensures we have all the common binaries and libraries we might expect from a Linux build environment already available to us. For example, the derivation above can be rewritten, removing the need to point to the bash and <code>coreutil</code> paths ourselves, as follows:{{File|example.nix|nix|<nowiki> | |||
{ pkgs ? import </nowiki><<nowiki>nixpkgs</nowiki>><nowiki> {} }: | |||
== | pkgs.stdenv.mkDerivation { | ||
name = "hello-world"; | |||
buildCommand = '' | |||
echo '#!/bin/bash' </nowiki>><nowiki> $out | |||
echo 'echo "Hello, World!"' </nowiki>>><nowiki> $out | |||
chmod +x $out | |||
''; | |||
} | |||
</nowiki>|highlight=}} | |||
==== Including source code ==== | |||
{{Main|Fetchers}} | |||
However, when building applications, packages, or derivations in general, we are almost never manually writing the source code ourselves within the derivation's build steps. Usually, we need to point to the derivation's source code. The <code>stdenv.mkDerivation</code> function takes in an attribute called <code>src</code>, which points to a location that should be included as one of the derivation's inputs. | |||
When building the derivation, the source code will be copied in the Nix store before proceeding with the build. The reason for this is due to the nature of source code (and external files in general themselves): they ''change over time''. Source code gets edited, improved, reverted, etc. By copying the source code ''at the time of the derivation'' to the Nix store, it becomes ''immutable''; any subsequent changes would result in it getting copied to a ''different path'' in the store. Thus, Nix ensures the guarantees we expect from a derivation: it still is a deterministic output, a function of its inputs. | |||
Grabbing the source code can be done in a number of different ways: it can be a store path, a location on the current system, or it can be downloaded via a [https://nixos.org/manual/nixpkgs/unstable/#chap-pkgs-fetchers fetcher], which is a special-purpose utility function for exactly this task:<syntaxhighlight lang="nix"> | |||
stdenv.mkDerivation { | stdenv.mkDerivation { | ||
src = ./relative-path/to/src; | |||
# or | |||
src = fetchFromGitHub { | src = fetchFromGitHub { | ||
owner = "torvalds"; | owner = "torvalds"; | ||
Line 61: | Line 91: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== | === Nixpkgs packages === | ||
The Nixpkgs repository is relevant in two main ways: it itself contains many higher-level utilities that abstract over the <code>stdenv.mkDerivation</code> requirements for the most common use cases, and every [[Nixpkgs]] package is a derivation in of itself. | |||
==== Utility functions ==== | |||
For example, the derivation at the beginning of this section can be rewritten in just four lines using the <code>writeShellScript</code> utility package. It handles most of the little setup required by the standard environment for us. The majority of the derivations that need to be written almost definitely can make use of one of these utility packages. For example:{{File|example.nix|nix|{ pkgs ? import <nixpkgs> {} }: | |||
} | |||
pkgs.writeShellScript "hello-world" '' | |||
echo "Hello, World!" | |||
''}} | |||
==== Package metadata ==== | |||
Derivations meant to be included as part of Nixpkgs usually include some metadata under the meta attribute. Common fields include: | |||
* <code>meta.homepage</code> and <code>meta.description</code> are used to describe and link to relevant information about the upstream source this derivation builds; | |||
* <code>meta.platforms</code> is useful for Nixpkgs to determine whether a package can be built on a different system (and whether to allow so in evaluation); | |||
* and <code>meta.licenses</code> is useful to check if a package has a suitable license that allows for re-distribution (caching in the official [[Binary Cache|binary cache]]<nowiki/>or one of the community caches); | |||
* <code>meta.mainProgram</code> describes the binary that can be considered the "main" program. For example, the cmake derivation would have this attribute set to <code>cmake</code>, which would be resolved as <code>$out/bin/cmake</code> when needed. | |||
A fully exhaustive documentation on all meta-attributes can be found in the [https://nixos.org/manual/nixpkgs/unstable/#chap-meta Nixpkgs manual]. | A fully exhaustive documentation on all meta-attributes can be found in the [https://nixos.org/manual/nixpkgs/unstable/#chap-meta Nixpkgs manual]. |