Nix-Language
Nix Language
The Nix language is designed for conveniently creating and composing derivations – precise descriptions of how contents of existing files are used to derive new files. It is:
domain-specific
It comes with built-in functions to integrate with the Nix store, which manages files and performs the derivations declared in the Nix language.
declarative
There is no notion of executing sequential steps. Dependencies between operations are established only through data.
pure
Values cannot change during computation. Functions always produce the same output if their input does not change.
functional
Functions are like any other value. Functions can be assigned to names, taken as arguments, or returned by functions.
lazy
Values are only computed when they are needed.
dynamically typed
Type errors are only detected when expressions are evaluated.
Overview
This is an incomplete overview of language features, by example.
Example | Description |
---|---|
Basic values | |
"hello world" | A string |
'' multi line string '' | A multi-line string. Strips common prefixed whitespace. Evaluates to "multi\n line\n string" . |
"hello ${ { a = "world"; }.a }" | |
"1 2 ${toString 3}" | |
"${pkgs.bash}/bin/sh" | String interpolation (expands to "hello world" , "1 2 3" , "/nix/store/<hash>-bash-<version>/bin/sh" ) |
true , false | Booleans |
null | Null value |
123 | An integer |
3.141 | A floating point number |
/etc | An absolute path |
./foo.png | A path relative to the file containing this Nix expression |
~/.config | A home path. Evaluates to the "<user's home directory>/.config" . |
<nixpkgs> | Search path for Nix files. Value determined by $NIX_PATH environment variable. |
Compound values | |
{ x = 1; y = 2; } | A set with attributes named x and y |
{ foo.bar = 1; } | A nested set, equivalent to { foo = { bar = 1; }; } |
rec { x = "foo"; y = x + "bar"; } | A recursive set, equivalent to { x = "foo"; y = "foobar"; } |
[ "foo" "bar" "baz" ] | |
[ 1 2 3 ] | |
[ (f 1) { a = 1; b = 2; } [ "c" ] ] | Lists with three elements. |
Operators | |
"foo" + "bar" | String concatenation |
1 + 2 | Integer addition |
"foo" == "f" + "oo" | Equality test (evaluates to true ) |
"foo" != "bar" | Inequality test (evaluates to true ) |
!true | Boolean negation |
{ x = 1; y = 2; }.x | Attribute selection (evaluates to 1 ) |
{ x = 1; y = 2; }.z or 3 | Attribute selection with default (evaluates to 3 ) |
{ x = 1; y = 2; } // { z = 3; } | Merge two sets (attributes in the right-hand set taking precedence) |
Control structures | |
if 1 + 1 == 2 then "yes!" else "no!" | Conditional expression |
assert 1 + 1 == 2; "yes!" | Assertion check (evaluates to "yes!" ). |
let x = "foo"; y = "bar"; in x + y | Variable definition |
with builtins; head [ 1 2 3 ] | Add all attributes from the given set to the scope (evaluates to 1 ) |
Functions (lambdas) | |
x: x + 1 | A function that expects an integer and returns it increased by 1 |
x: y: x + y | Curried function, equivalent to x: (y: x + y) . Can be used like a function that takes two arguments and returns their sum. |
(x: x + 1) 100 | A function call (evaluates to 101) |
let inc = x: x + 1; in inc (inc (inc 100)) | A function bound to a variable and subsequently called by name (evaluates to 103) |
{ x, y }: x + y | A function that expects a set with required attributes x and y and concatenates them |
{ x, y ? "bar" }: x + y | A function that expects a set with required attribute x and optional y , using "bar" as default value for y |
{ x, y, ... }: x + y | A function that expects a set with required attributes x and y and ignores any other attributes |
{ x, y } @ args: x + y | |
args @ { x, y }: x + y | A function that expects a set with required attributes x and y , and binds the whole set to args |
Built-in functions | |
import ./foo.nix | Load and return Nix expression in given file |
map (x: x + x) [ 1 2 3 ] | Apply a function to every element of a list (evaluates to [ 2 4 6 ] ) |
Data Types
Primitives
-
Strings can be written in three ways.
The most common way is to enclose the string between double quotes, e.g.,
"foo bar"
. Strings can span multiple lines. The special characters"
and\
and the character sequence${
must be escaped by prefixing them with a backslash (\
). Newlines, carriage returns and tabs can be written as\n
,\r
and\t
, respectively.You can include the results of other expressions into a string by enclosing them in
${ }
, a feature known as string interpolation.The second way to write string literals is as an indented string, which is enclosed between pairs of double single-quotes, like so:
'' This is the first line. This is the second line. This is the third line. ''
This kind of string literal intelligently strips indentation from the start of each line. To be precise, it strips from each line a number of spaces equal to the minimal indentation of the string as a whole (disregarding the indentation of empty lines). For instance, the first and second line are indented two spaces, while the third line is indented four spaces. Thus, two spaces are stripped from each line, so the resulting string is
"This is the first line.\nThis is the second line.\n This is the third line.\n"
Note that the whitespace and newline following the opening
''
is ignored if there is no non-whitespace text on the initial line.Indented strings support string interpolation.
Since
${
and''
have special meaning in indented strings, you need a way to quote them.$
can be escaped by prefixing it with''
(that is, two single quotes), i.e.,''$
.''
can be escaped by prefixing it with'
, i.e.,'''
.$
removes any special meaning from the following$
. Linefeed, carriage-return and tab characters can be written as''\n
,''\r
,''\t
, and''\
escapes any other character.Indented strings are primarily useful in that they allow multi-line string literals to follow the indentation of the enclosing Nix expression, and that less escaping is typically necessary for strings representing languages such as shell scripts and configuration files because
''
is much less common than"
. Example:stdenv.mkDerivation { ... postInstall = '' mkdir $out/bin $out/etc cp foo $out/bin echo "Hello World" > $out/etc/foo.conf ${if enableBar then "cp bar $out/bin" else ""} ''; ... }
Finally, as a convenience, URIs as defined in appendix B of RFC 2396 can be written as is, without quotes. For instance, the string
"http://example.org/foo.tar.bz2"
can also be written ashttp://example.org/foo.tar.bz2
. -
Numbers, which can be integers (like
123
) or floating point (like123.43
or.27e13
).See arithmetic and comparison operators for semantics.
-
Paths, e.g.,
/bin/sh
or./builder.sh
. A path must contain at least one slash to be recognised as such. For instance,builder.sh
is not a path: it's parsed as an expression that selects the attributesh
from the variablebuilder
. If the file name is relative, i.e., if it does not begin with a slash, it is made absolute at parse time relative to the directory of the Nix expression that contained it. For instance, if a Nix expression in/foo/bar/bla.nix
refers to../xyzzy/fnord.nix
, the absolute path is/foo/xyzzy/fnord.nix
.If the first component of a path is a
~
, it is interpreted as if the rest of the path were relative to the user's home directory. e.g.~/foo
would be equivalent to/home/edolstra/foo
for a user whose home directory is/home/edolstra
.For instance, evaluating
"${./foo.txt}"
will causefoo.txt
in the current directory to be copied into the Nix store and result in the string"/nix/store/<hash>-foo.txt"
.Note that the Nix language assumes that all input files will remain unchanged while evaluating a Nix expression. For example, assume you used a file path in an interpolated string during a
nix repl
session. Later in the same session, after having changed the file contents, evaluating the interpolated string with the file path again might not return a new store path, since Nix might not re-read the file contents.Paths can include string interpolation and can themselves be [interpolated in other expressions]. [interpolated in other expressions]: ./string-interpolation.md#interpolated-expressions
At least one slash (
/
) must appear before any interpolated expression for the result to be recognized as a path.a.${foo}/b.${bar}
is a syntactically valid division operation../a.${foo}/b.${bar}
is a path.Lookup paths such as
<nixpkgs>
resolve to path values. -
Booleans with values
true
andfalse
. -
The null value, denoted as
null
.
List
Lists are formed by enclosing a whitespace-separated list of values between square brackets. For example,
[ 123 ./foo.nix "abc" (f { x = y; }) ]
defines a list of four elements, the last being the result of a call to the function f
. Note that function calls have to be enclosed in parentheses. If they had been omitted, e.g.,
[ 123 ./foo.nix "abc" f { x = y; } ]
the result would be a list of five elements, the fourth one being a function and the fifth being a set.
Note that lists are only lazy in values, and they are strict in length.
Attribute Set
An attribute set is a collection of name-value-pairs (called attributes) enclosed in curly brackets ({ }
).
An attribute name can be an identifier or a string. An identifier must start with a letter (a-z
, A-Z
) or underscore (_
), and can otherwise contain letters (a-z
, A-Z
), numbers (0-9
), underscores (_
), apostrophes ('
), or dashes (-
).
Syntax
name = identifier | string
identifier ~[a-zA-Z_][a-zA-Z0-9_'-]*
Names and values are separated by an equal sign (=
). Each value is an arbitrary expression terminated by a semicolon (;
).
Syntax
attrset =
{
[ name=
expr;
]...}
Attributes can appear in any order. An attribute name may only occur once.
Example:
{ x = 123; text = "Hello"; y = f { bla = 456; }; }
This defines a set with attributes named x
, text
, y
.
Attributes can be accessed with the . operator.
Example:
{ a = "Foo"; b = "Bar"; }.a
This evaluates to "Foo"
.
It is possible to provide a default value in an attribute selection using the or
keyword.
Example:
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"`
{ a = "Foo"; b = "Bar"; }.c.d.e.f.g or "Xyzzy"
will both evaluate to "Xyzzy"
because there is no c
attribute in the set.
You can use arbitrary double-quoted strings as attribute names:
{ "$!@#?" = 123; }."$!@#?"
let bar = "bar"; in
{ "foo ${bar}" = 123; }."foo ${bar}"
Both will evaluate to 123
.
Attribute names support string interpolation:
let bar = "foo"; in
{ foo = 123; }.${bar}
let bar = "foo"; in
{ ${bar} = 123; }.foo
Both will evaluate to 123
.
In the special case where an attribute name inside of a set declaration evaluates to null
(which is normally an error, as null
cannot be coerced to a string), that attribute is simply not added to the set:
{ ${if foo then "bar" else null} = true; }
This will evaluate to {}
if foo
evaluates to false
.
A set that has a __functor
attribute whose value is callable (i.e. is itself a function or a set with a __functor
attribute whose value is callable) can be applied as if it were a function, with the set itself passed in first , e.g.,
let add = { __functor = self: x: x + self.x; };
inc = add // { x = 1; };
in inc 1
evaluates to 2
. This can be used to attach metadata to a function without the caller needing to treat it specially, or to implement a form of object-oriented programming, for example.
Language Constructs
Recursive sets
Recursive sets are like normal attribute sets, but the attributes can refer to each other.
rec-attrset =
rec { [ _name_ = _expr_ ; ]... }
Example:
rec {
x = y;
y = 123;
}.x
This evaluates to 123
.
Note that without rec
the binding x = y;
would refer to the variable y
in the surrounding scope, if one exists, and would be invalid if no such variable exists. That is, in a normal (non-recursive) set, attributes are not added to the lexical scope; in a recursive set, they are.
Recursive sets of course introduce the danger of infinite recursion. For example, the expression
rec {
x = y;
y = x;
}.x
will crash with an infinite recursion encountered
error message.
Let-expressions
A let-expression allows you to define local variables for an expression.
let-in =
let
[ identifier = expr ]...in
expr
Example:
let
x = "foo";
y = "bar";
in x + y
This evaluates to "foobar"
.
Inheriting attributes
When defining an attribute set or in a let-expression it is often convenient to copy variables from the surrounding lexical scope (e.g., when you want to propagate attributes). This can be shortened using the inherit
keyword.
Example:
let x = 123;
in {
inherit x;
y = 456;
}
is equivalent to
let x = 123;
in {
x = x;
y = 456;
}
and both evaluate to { x = 123; y = 456; }
.
Note
This works because
x
is added to the lexical scope by thelet
construct.
It is also possible to inherit attributes from another attribute set.
Example:
In this fragment from all-packages.nix
,
graphviz = (import ../tools/graphics/graphviz) {
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
inherit (xorg) libXaw;
};
xorg = {
libX11 = ...;
libXaw = ...;
...
}
libpng = ...;
libjpg = ...;
...
the set used in the function call to the function defined in ../tools/graphics/graphviz
inherits a number of variables from the surrounding scope (fetchurl
... yacc
), but also inherits libXaw
(the X Athena Widgets) from the xorg
set.
Summarizing the fragment
...
inherit x y z;
inherit (src-set) a b c;
...
is equivalent to
...
x = x; y = y; z = z;
a = src-set.a; b = src-set.b; c = src-set.c;
...
when used while defining local variables in a let-expression or while defining a set.
Functions
Functions have the following form:
pattern: body
The pattern specifies what the argument of the function must look like, and binds variables in the body to (parts of) the argument. There are three kinds of patterns:
If a pattern is a single identifier, then the function matches any argument. Example:
let negate = x: !x; concat = x: y: x + y; in if negate true then concat "foo" "bar" else ""
Note that
concat
is a function that takes one argument and returns a function that takes another argument. This allows partial parameterisation (i.e., only filling some of the arguments of a function); e.g.,map (concat "foo") [ "bar" "bla" "abc" ]
evaluates to
[ "foobar" "foobla" "fooabc" ]
.A set pattern of the form
{ name1, name2, …, nameN }
matches a set containing the listed attributes, and binds the values of those attributes to variables in the function body. For example, the function{ x, y, z }: z + y + x
can only be called with a set containing exactly the attributes
x
,y
andz
. No other attributes are allowed. If you want to allow additional arguments, you can use an ellipsis (...
):{ x, y, z, ... }: z + y + x
This works on any set that contains at least the three named attributes.
It is possible to provide default values for attributes, in which case they are allowed to be missing. A default value is specified by writing
name ? e
, where e is an arbitrary expression. For example,{ x, y ? "foo", z ? "bar" }: z + y + x
specifies a function that only requires an attribute named
x
, but optionally acceptsy
andz
.An
@
-pattern provides a means of referring to the whole value being matched:args@{ x, y, z, ... }: z + y + x + args.a
but can also be written as:
{ x, y, z, ... } @ args: z + y + x + args.a
Here
args
is bound to the argument as passed, which is further matched against the pattern{ x, y, z, ... }
. The@
-pattern makes mainly sense with an ellipsis(...
) as you can access attribute names asa
, usingargs.a
, which was given as an additional attribute to the function.Warning
args@
binds the nameargs
to the attribute set that is passed to the function. In particular,args
does not include any default values specified with?
in the function's set pattern.For instance
let f = args@{ a ? 23, ... }: [ a args ]; in f {}
is equivalent to
let f = args @ { ... }: [ (args.a or 23) args ]; in f {}
and both expressions will evaluate to:
[ 23 {} ]
Note that functions do not have names. If you want to give them a name, you can bind them to an attribute, e.g.,
let concat = { x, y }: x + y;
in concat { x = "foo"; y = "bar"; }
Conditionals
Conditionals look like this:
if e1 then e2 else e3
where e1 is an expression that should evaluate to a Boolean value (true
or false
).
Assertions
Assertions are generally used to check that certain requirements on or between features and dependencies hold. They look like this:
assert e1; e2
where e1 is an expression that should evaluate to a Boolean value. If it evaluates to true
, e2 is returned; otherwise expression evaluation is aborted and a backtrace is printed.
Here is a Nix expression for the Subversion package that shows how assertions can be used:.
{ localServer ? false
, httpServer ? false
, sslSupport ? false
, pythonBindings ? false
, javaSwigBindings ? false
, javahlBindings ? false
, stdenv, fetchurl
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null }:
assert localServer -> db4 != null; ①
assert httpServer -> httpd != null && httpd.expat == expat; ②
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); ③
assert pythonBindings -> swig != null && swig.pythonSupport;
assert javaSwigBindings -> swig != null && swig.javaSupport;
assert javahlBindings -> j2sdk != null;
stdenv.mkDerivation {
name = "subversion-1.1.1";
...
openssl = if sslSupport then openssl else null; ④
...
}
The points of interest are:
This assertion states that if Subversion is to have support for local repositories, then Berkeley DB is needed. So if the Subversion function is called with the
localServer
argument set totrue
but thedb4
argument set tonull
, then the evaluation fails.Note that
->
is the logical implication Boolean operation.This is a more subtle condition: if Subversion is built with Apache (
httpServer
) support, then the Expat library (an XML library) used by Subversion should be same as the one used by Apache. This is because in this configuration Subversion code ends up being linked with Apache code, and if the Expat libraries do not match, a build- or runtime link error or incompatibility might occur.This assertion says that in order for Subversion to have SSL support (so that it can access
https
URLs), an OpenSSL library must be passed. Additionally, it says that if Apache support is enabled, then Apache's OpenSSL should match Subversion's. (Note that if Apache support is not enabled, we don't care about Apache's OpenSSL.)The conditional here is not really related to assertions, but is worth pointing out: it ensures that if SSL support is disabled, then the Subversion derivation is not dependent on OpenSSL, even if a non-
null
value was passed. This prevents an unnecessary rebuild of Subversion if OpenSSL changes.
With-expressions
A with-expression,
with e1; e2
introduces the set e1 into the lexical scope of the expression e2. For instance,
let as = { x = "foo"; y = "bar"; };
in with as; x + y
evaluates to "foobar"
since the with
adds the x
and y
attributes of as
to the lexical scope in the expression x + y
. The most common use of with
is in conjunction with the import
function. E.g.,
with (import ./definitions.nix); ...
makes all attributes defined in the file definitions.nix
available as if they were defined locally in a let
-expression.
The bindings introduced by with
do not shadow bindings introduced by other means, e.g.
let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...
establishes the same scope as
let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...
Comments
Comments can be single-line, started with a #
character, or inline/multi-line, enclosed within /* ... */
.
String interpolation
String interpolation is a language feature where a string, path, or attribute name can contain expressions enclosed in ${ }
(dollar-sign with curly brackets).
Such a construct is called interpolated string, and the expression inside is an interpolated expression.
Examples
String
Rather than writing
"--with-freetype2-library=" + freetype + "/lib"
(where freetype
is a [derivation]), you can instead write
"--with-freetype2-library=${freetype}/lib"
The latter is automatically translated to the former.
A more complicated example (from the Nix expression for Qt):
configureFlags = "
-system-zlib -system-libpng -system-libjpeg
${if openglSupport then "-dlopen-opengl
-L${mesa}/lib -I${mesa}/include
-L${libXmu}/lib -I${libXmu}/include" else ""}
${if threadSupport then "-thread" else "-no-thread"}
";
Note that Nix expressions and strings can be arbitrarily nested; in this case the outer string contains various interpolated expressions that themselves contain strings (e.g., "-thread"
), some of which in turn contain interpolated expressions (e.g., ${mesa}
).
Path
Rather than writing
./. + "/" + foo + "-" + bar + ".nix"
or
./. + "/${foo}-${bar}.nix"
you can instead write
./${foo}-${bar}.nix
Attribute name
Attribute names can be interpolated strings.
Example
let name = "foo"; in { ${name} = 123; }
{ foo = 123; }
Attributes can be selected with interpolated strings.
Example
let name = "foo"; in { foo = 123; }.${name}
123
Interpolated expression
An expression that is interpolated must evaluate to one of the following:
a string
a path
an attribute set that has a
__toString
attribute or anoutPath
attribute__toString
must be a function that takes the attribute set itself and returns a stringoutPath
must be a string This includes derivations or flake inputs (experimental).
A string interpolates to itself.
A path in an interpolated expression is first copied into the Nix store, and the resulting string is the store path of the newly created store object.
Example
$ mkdir foo
Reference the empty directory in an interpolated expression:
"${./foo}"
"/nix/store/2hhl2nz5v0khbn06ys82nrk99aa1xxdw-foo"
A derivation interpolates to the store path of its first output.
Example
let pkgs = import <nixpkgs> {}; in "${pkgs.hello}"
"/nix/store/4xpfqf29z4m8vbhrqcz064wfmb46w5r7-hello-2.12.1"
An attribute set interpolates to the return value of the function in the __toString
applied to the attribute set itself.
Example
let a = { value = 1; __toString = self: toString (self.value + 1); }; in "${a}"
"2"
An attribute set also interpolates to the value of its outPath
attribute.
Example
let a = { outPath = "foo"; }; in "${a}"
"foo"
If both __toString
and outPath
are present in an attribute set, __toString
takes precedence.
Example
let a = { __toString = _: "yes"; outPath = throw "no"; }; in "${a}"
"yes"
If neither is present, an error is thrown.
Example
let a = {}; in "${a}"
error: cannot coerce a set to a string at «string»:4:2: 3| in 4| "${a}" | ^
Lookup path
Syntax
lookup-path =
<
identifier [/
identifier ]...>
A lookup path is an identifier with an optional path suffix that resolves to a path value if the identifier matches a search path entry.
The value of a lookup path is determined by builtins.nixPath
.
See builtins.findFile
for details on lookup path resolution.
Example
<nixpkgs>
/nix/var/nix/profiles/per-user/root/channels/nixpkgs
Example
<nixpkgs/nixos>
/nix/var/nix/profiles/per-user/root/channels/nixpkgs/nixos
Operators
Name | Syntax | Associativity | Precedence |
---|---|---|---|
Attribute selection | attrset . attrpath [ or expr ] | none | 1 |
Function application | func expr | left | 2 |
Arithmetic negation | - number | none | 3 |
Has attribute | attrset ? attrpath | none | 4 |
List concatenation | list ++ list | right | 5 |
Multiplication | number * number | left | 6 |
Division | number / number | left | 6 |
Subtraction | number - number | left | 7 |
Addition | number + number | left | 7 |
String concatenation | string + string | left | 7 |
Path concatenation | path + path | left | 7 |
Path and string concatenation | path + string | left | 7 |
String and path concatenation | string + path | left | 7 |
Logical negation (NOT ) | ! bool | none | 8 |
Update | attrset // attrset | right | 9 |
Less than | expr < expr | none | 10 |
Less than or equal to | expr <= expr | none | 10 |
Greater than | expr > expr | none | 10 |
Greater than or equal to | expr >= expr | none | 10 |
Equality | expr == expr | none | 11 |
Inequality | expr != expr | none | 11 |
Logical conjunction (AND ) | bool && bool | left | 12 |
Logical disjunction (OR ) | bool \| bool | left | 13 |
Logical implication | bool -> bool | none | 14 |
Attribute selection
Syntax
attrset
.
attrpath [or
expr ]
Select the attribute denoted by attribute path attrpath from attribute set attrset. If the attribute doesn’t exist, return the expr after or
if provided, otherwise abort evaluation.
An attribute path is a dot-separated list of attribute names.
Syntax
attrpath = name [
.
name ]...
Has attribute
Syntax
attrset
?
attrpath
Test whether attribute set attrset contains the attribute denoted by attrpath. The result is a Boolean value.
Arithmetic
Numbers are type-compatible: Pure integer operations will always return integers, whereas any operation involving at least one floating point number return a floating point number.
See also Comparison and Equality.
The +
operator is overloaded to also work on strings and paths.
String concatenation
Syntax
string
+
string
Concatenate two strings and merge their string contexts.
Path concatenation
Syntax
path
+
path
Concatenate two paths. The result is a path.
Path and string concatenation
Syntax
path + string
Concatenate path with string. The result is a path.
Note
The string must not have a string context that refers to a store path.
String and path concatenation
Syntax
string + path
Concatenate string with path. The result is a string.
Important
The file or directory at path must exist and is copied to the store. The path appears in the result as the corresponding store path.
Update
Syntax
attrset1 // attrset2
Update attribute set attrset1 with names and values from attrset2.
The returned attribute set will have of all the attributes in attrset1 and attrset2. If an attribute name is present in both, the attribute value from the latter is taken.
Comparison
Comparison is
- arithmetic for numbers
- lexicographic for strings and paths
- item-wise lexicographic for lists: elements at the same index in both lists are compared according to their type and skipped if they are equal.
All comparison operators are implemented in terms of <
, and the following equivalencies hold:
comparison | implementation |
---|---|
a <= b | ! ( b < a ) |
a > b | b < a |
a >= b | ! ( a < b ) |
Equality
- Attribute sets and lists are compared recursively, and therefore are fully evaluated.
- Comparison of functions always returns
false
. - Numbers are type-compatible, see arithmetic operators.
- Floating point numbers only differ up to a limited precision.
Logical implication
Equivalent to !
b1 ||
b2.
Derivations
The most important built-in function is derivation
, which is used to describe a single derivation: a specification for running an executable on precisely defined input files to repeatably produce output files at uniquely determined file system paths.
It takes as input an attribute set, the attributes of which specify the inputs to the process. It outputs an attribute set, and produces a store derivation as a side effect of evaluation.
Input attributes
Required
-
A symbolic name for the derivation. It is added to the store derivation's path and its output paths.
Example:
name = "hello";
The store derivation's path will be
/nix/store/<hash>-hello.drv
, and the output paths will be of the form/nix/store/<hash>-hello[-<output>]
-
The system type on which the
builder
executable is meant to be run.A necessary condition for Nix to build derivations locally is that the
system
attribute matches the currentsystem
configuration option. It can automatically build on other platforms by forwarding build requests to other machines.Examples:
system = "x86_64-linux";
system = builtins.currentSystem;
builtins.currentSystem
has the value of thesystem
configuration option, and defaults to the system type of the current Nix installation. -
Path to an executable that will perform the build.
Examples:
builder = "/bin/bash";
builder = ./builder.sh;
builder = "${pkgs.python}/bin/python";
Optional
args
(List of String) Default:[ ]
Command-line arguments to be passed to the
builder
executable.Example:
args = [ "-c" "echo hello world > $out" ];
outputs
(List of String) Default:[ "out" ]
Symbolic outputs of the derivation. Each output name is passed to the
builder
executable as an environment variable with its value set to the corresponding output path.By default, a derivation produces a single output path called
out
. However, derivations can produce multiple output paths. This allows the associated store objects and their closures to be copied or garbage-collected separately.Examples:
Imagine a library package that provides a dynamic library, header files, and documentation. A program that links against such a library doesn’t need the header files and documentation at runtime, and it doesn’t need the documentation at build time. Thus, the library package could specify:
derivation { # ... outputs = [ "lib" "dev" "doc" ]; # ... }
This will cause Nix to pass environment variables
lib
,dev
, anddoc
to the builder containing the intended store paths of each output. The builder would typically do something like./configure \ --libdir=$lib/lib \ --includedir=$dev/include \ --docdir=$doc/share/doc
for an Autoconf-style package.
You can refer to each output of a derivation by selecting it as an attribute, e.g.
myPackage.lib
ormyPackage.doc
.The first element of
outputs
determines the default output. Therefore, in the given example,myPackage
is equivalent tomyPackage.lib
.See Advanced Attributes for more, infrequently used, optional attributes.
Every other attribute is passed as an environment variable to the builder. Attribute values are translated to environment variables as follows:
Strings are passed unchanged.
Integral numbers are converted to decimal notation.
Floating point numbers are converted to simple decimal or scientific notation with a preset precision.
A path (e.g.,
../foo/sources.tar
) causes the referenced file to be copied to the store; its location in the store is put in the environment variable. The idea is that all sources should reside in the Nix store, since all inputs to a derivation should reside in the Nix store.A derivation causes that derivation to be built prior to the present derivation; its default output path is put in the environment variable.
Lists of the previous types are also allowed. They are simply concatenated, separated by spaces.
true
is passed as the string1
,false
andnull
are passed as an empty string.
Builder execution
The builder
is executed as follows:
A temporary directory is created under the directory specified by
TMPDIR
(default/tmp
) where the build will take place. The current directory is changed to this directory.The environment is cleared and set to the derivation attributes, as specified above.
In addition, the following variables are set:
NIX_BUILD_TOP
contains the path of the temporary directory for this build.Also,
TMPDIR
,TEMPDIR
,TMP
,TEMP
are set to point to the temporary directory. This is to prevent the builder from accidentally writing temporary files anywhere else. Doing so might cause interference by other processes.PATH
is set to/path-not-set
to prevent shells from initialising it to their built-in default value.HOME
is set to/homeless-shelter
to prevent programs from using/etc/passwd
or the like to find the user's home directory, which could cause impurity. Usually, whenHOME
is set, it is used as the location of the home directory, even if it points to a non-existent path.NIX_STORE
is set to the path of the top-level Nix store directory (typically,/nix/store
).NIX_ATTRS_JSON_FILE
&NIX_ATTRS_SH_FILE
if__structuredAttrs
is set totrue
for the dervation. A detailed explanation of this behavior can be found in the section about structured attrs.For each output declared in
outputs
, the corresponding environment variable is set to point to the intended path in the Nix store for that output. Each output path is a concatenation of the cryptographic hash of all build inputs, thename
attribute and the output name. (The output name is omitted if it’sout
.)
If an output path already exists, it is removed. Also, locks are acquired to prevent multiple Nix instances from performing the same build at the same time.
A log of the combined standard output and error is written to
/nix/var/log/nix
.The builder is executed with the arguments specified by the attribute
args
. If it exits with exit code 0, it is considered to have succeeded.The temporary directory is removed (unless the
-K
option was specified).If the build was successful, Nix scans each output path for references to input paths by looking for the hash parts of the input paths. Since these are potential runtime dependencies, Nix registers them as dependencies of the output paths.
After the build, Nix sets the last-modified timestamp on all files in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to the default group, and sets the mode of the file to 0444 or 0555 (i.e., read-only, with execute permission enabled if the file was originally executable). Note that possible
setuid
andsetgid
bits are cleared. Setuid and setgid programs are not currently supported by Nix. This is because the Nix archives used in deployment have no concept of ownership information, and because it makes the build result dependent on the user performing the build.
Advanced Attributes
Derivations can declare some infrequently used optional attributes.
allowedReferences
The optional attributeallowedReferences
specifies a list of legal references (dependencies) of the output of the builder. For example,allowedReferences = [];
enforces that the output of a derivation cannot have any runtime dependencies on its inputs. To allow an output to have a runtime dependency on itself, use
"out"
as a list item. This is used in NixOS to check that generated files such as initial ramdisks for booting Linux don’t have accidental dependencies on other paths in the Nix store.allowedRequisites
This attribute is similar toallowedReferences
, but it specifies the legal requisites of the whole closure, so all the dependencies recursively. For example,allowedRequisites = [ foobar ];
enforces that the output of a derivation cannot have any other runtime dependency than
foobar
, and in addition it enforces thatfoobar
itself doesn't introduce any other dependency itself.disallowedReferences
The optional attributedisallowedReferences
specifies a list of illegal references (dependencies) of the output of the builder. For example,disallowedReferences = [ foo ];
enforces that the output of a derivation cannot have a direct runtime dependencies on the derivation
foo
.disallowedRequisites
This attribute is similar todisallowedReferences
, but it specifies illegal requisites for the whole closure, so all the dependencies recursively. For example,disallowedRequisites = [ foobar ];
enforces that the output of a derivation cannot have any runtime dependency on
foobar
or any other derivation depending recursively onfoobar
.exportReferencesGraph
This attribute allows builders access to the references graph of their inputs. The attribute is a list of inputs in the Nix store whose references graph the builder needs to know. The value of this attribute should be a list of pairs[ name1 path1 name2 path2 ... ]
. The references graph of each pathN will be stored in a text file nameN in the temporary build directory. The text files have the format used bynix-store --register-validity
(with the deriver fields left empty). For example, when the following derivation is built:derivation { ... exportReferencesGraph = [ "libfoo-graph" libfoo ]; };
the references graph of
libfoo
is placed in the filelibfoo-graph
in the temporary build directory.exportReferencesGraph
is useful for builders that want to do something with the closure of a store path. Examples include the builders in NixOS that generate the initial ramdisk for booting Linux (acpio
archive containing the closure of the boot script) and the ISO-9660 image for the installation CD (which is populated with a Nix store containing the closure of a bootable NixOS configuration).impureEnvVars
This attribute allows you to specify a list of environment variables that should be passed from the environment of the calling user to the builder. Usually, the environment is cleared completely when the builder is executed, but with this attribute you can allow specific environment variables to be passed unmodified. For example,fetchurl
in Nixpkgs has the lineimpureEnvVars = [ "http_proxy" "https_proxy" ... ];
to make it use the proxy server configuration specified by the user in the environment variables
http_proxy
and friends.This attribute is only allowed in fixed-output derivations (see below), where impurities such as these are okay since (the hash of) the output is known in advance. It is ignored for all other derivations.
Warning
impureEnvVars
implementation takes environment variables from the current builder process. When a daemon is building its environmental variables are used. Without the daemon, the environmental variables come from the environment of thenix-build
.If the
configurable-impure-env
experimental feature is enabled, these environment variables can also be controlled through theimpure-env
configuration setting.outputHash
;outputHashAlgo
;outputHashMode
These attributes declare that the derivation is a so-called fixed-output derivation, which means that a cryptographic hash of the output is already known in advance. When the build of a fixed-output derivation finishes, Nix computes the cryptographic hash of the output and compares it to the hash declared with these attributes. If there is a mismatch, the build fails.The rationale for fixed-output derivations is derivations such as those produced by the
fetchurl
function. This function downloads a file from a given URL. To ensure that the downloaded file has not been modified, the caller must also specify a cryptographic hash of the file. For example,fetchurl { url = "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz"; sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465"; }
It sometimes happens that the URL of the file changes, e.g., because servers are reorganised or no longer available. We then must update the call to
fetchurl
, e.g.,fetchurl { url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz"; sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465"; }
If a
fetchurl
derivation was treated like a normal derivation, the output paths of the derivation and all derivations depending on it would change. For instance, if we were to change the URL of the Glibc source distribution in Nixpkgs (a package on which almost all other packages depend) massive rebuilds would be needed. This is unfortunate for a change which we know cannot have a real effect as it propagates upwards through the dependency graph.For fixed-output derivations, on the other hand, the name of the output path only depends on the
outputHash*
andname
attributes, while all other attributes are ignored for the purpose of computing the output path. (Thename
attribute is included because it is part of the path.)As an example, here is the (simplified) Nix expression for
fetchurl
:{ stdenv, curl }: # The curl program is used for downloading. { url, sha256 }: stdenv.mkDerivation { name = baseNameOf (toString url); builder = ./builder.sh; buildInputs = [ curl ]; # This is a fixed-output derivation; the output must be a regular # file with SHA256 hash sha256. outputHashMode = "flat"; outputHashAlgo = "sha256"; outputHash = sha256; inherit url; }
The
outputHashAlgo
attribute specifies the hash algorithm used to compute the hash. It can currently be"sha1"
,"sha256"
or"sha512"
.The
outputHashMode
attribute determines how the hash is computed. It must be one of the following two values:"flat"
The output must be a non-executable regular file. If it isn’t, the build fails. The hash is simply computed over the contents of that file (so it’s equal to what Unix commands likesha256sum
orsha1sum
produce).This is the default.
"recursive"
The hash is computed over the NAR archive dump of the output (i.e., the result ofnix-store --dump
). In this case, the output can be anything, including a directory tree.
The
outputHash
attribute, finally, must be a string containing the hash in either hexadecimal or base-32 notation. (See thenix-hash
command for information about converting to and from base-32 notation.)-
Warning This attribute is part of an experimental feature.
To use this attribute, you must enable the
ca-derivations
experimental feature. For example, in nix.conf you could add:extra-experimental-features = ca-derivations
If this attribute is set to
true
, then the derivation outputs will be stored in a content-addressed location rather than the traditional input-addressed one.Setting this attribute also requires setting
outputHashMode
andoutputHashAlgo
like for fixed-output derivations (see above).It also implicitly requires that the machine to build the derivation must have the
ca-derivations
system feature. passAsFile
A list of names of attributes that should be passed via files rather than environment variables. For example, if you havepassAsFile = ["big"]; big = "a very long string";
then when the builder runs, the environment variable
bigPath
will contain the absolute path to a temporary file containinga very long string
. That is, for any attribute x listed inpassAsFile
, Nix will pass an environment variablexPath
holding the path of the file containing the value of attribute x. This is useful when you need to pass large strings to a builder, since most operating systems impose a limit on the size of the environment (typically, a few hundred kilobyte).preferLocalBuild
If this attribute is set totrue
and distributed building is enabled, then, if possible, the derivation will be built locally instead of forwarded to a remote machine. This is appropriate for trivial builders where the cost of doing a download or remote build would exceed the cost of building locally.allowSubstitutes
If this attribute is set tofalse
, then Nix will always build this derivation; it will not try to substitute its outputs. This is useful for very trivial derivations (such aswriteText
in Nixpkgs) that are cheaper to build than to substitute from a binary cache.Note
You need to have a builder configured which satisfies the derivation’s
system
attribute, since the derivation cannot be substituted. Thus it is usually a good idea to alignsystem
withbuiltins.currentSystem
when settingallowSubstitutes
tofalse
. For most trivial derivations this should be the case.__structuredAttrs
If the special attribute__structuredAttrs
is set totrue
, the other derivation attributes are serialised into a file in JSON format. The environment variableNIX_ATTRS_JSON_FILE
points to the exact location of that file both in a build and anix-shell
. This obviates the need forpassAsFile
since JSON files have no size restrictions, unlike process environments.It also makes it possible to tweak derivation settings in a structured way; see
outputChecks
for example.As a convenience to Bash builders, Nix writes a script that initialises shell variables corresponding to all attributes that are representable in Bash. The environment variable
NIX_ATTRS_SH_FILE
points to the exact location of the script, both in a build and anix-shell
. This includes non-nested (associative) arrays. For example, the attributehardening.format = true
ends up as the Bash associative array element${hardening[format]}
.outputChecks
When using structured attributes, theoutputChecks
attribute allows defining checks per-output.In addition to
allowedReferences
,allowedRequisites
,disallowedReferences
anddisallowedRequisites
, the following attributes are available:maxSize
defines the maximum size of the resulting store object.maxClosureSize
defines the maximum size of the output's closure.ignoreSelfRefs
controls whether self-references should be considered when checking for allowed references/requisites. Example:
__structuredAttrs = true; outputChecks.out = { # The closure of 'out' must not be larger than 256 MiB. maxClosureSize = 256 * 1024 * 1024; # It must not refer to the C compiler or to the 'dev' output. disallowedRequisites = [ stdenv.cc "dev" ]; }; outputChecks.dev = { # The 'dev' output must not be larger than 128 KiB. maxSize = 128 * 1024; };
-
When using structured attributes, the attribute
unsafeDiscardReferences
is an attribute set with a boolean value for each output name. If set totrue
, it disables scanning the output for runtime dependencies.Example:
__structuredAttrs = true; unsafeDiscardReferences.out = true;
This is useful, for example, when generating self-contained filesystem images with their own embedded Nix store: hashes found inside such an image refer to the embedded store and not to the host's Nix store.
-
If a derivation has the
requiredSystemFeatures
attribute, then Nix will only build it on a machine that has the corresponding features set in itssystem-features
configuration.For example, setting
requiredSystemFeatures = [ "kvm" ];
ensures that the derivation can only be built on a machine with the
kvm
feature.
Import From Derivation
The value of a Nix expression can depend on the contents of a store object.
Passing an expression expr
that evaluates to a store path to any built-in function which reads from the filesystem constitutes Import From Derivation (IFD):
import
expr
builtins.readFile
expr
builtins.readFileType
expr
builtins.readDir
expr
builtins.pathExists
expr
builtins.filterSource
f expr
builtins.path
{ path = expr; }
builtins.hashFile
t expr
builtins.scopedImport x drv
When the store path needs to be accessed, evaluation will be paused, the corresponding store object realised, and then evaluation resumed.
This has performance implications: Evaluation can only finish when all required store objects are realised. Since the Nix language evaluator is sequential, it only finds store paths to read from one at a time. While realisation is always parallel, in this case it cannot be done for all required store paths at once, and is therefore much slower than otherwise.
Realising store objects during evaluation can be disabled by setting allow-import-from-derivation
to false
. Without IFD it is ensured that evaluation is complete and Nix can produce a build plan before starting any realisation.
Example
In the following Nix expression, the inner derivation drv
produces a file with contents hello
.
# IFD.nix
let
drv = derivation {
name = "hello";
builder = "/bin/sh";
args = [ "-c" "echo -n hello > $out" ];
system = builtins.currentSystem;
};
in "${builtins.readFile drv} world"
nix-instantiate IFD.nix --eval --read-write-mode
building '/nix/store/348q1cal6sdgfxs8zqi9v8llrsn4kqkq-hello.drv'...
"hello world"
The contents of the derivation's output have to be realised before they can be read with readFile
. Only then evaluation can continue to produce the final result.
Illustration
As a first approximation, the following data flow graph shows how evaluation and building are interleaved, if the value of a Nix expression depends on realising a [store object]. Boxes are data structures, arrow labels are transformations.
+----------------------+ +------------------------+
| Nix evaluator | | Nix store |
| .----------------. | | |
| | Nix expression | | | |
| '----------------' | | |
| | | | |
| evaluate | | |
| | | | |
| V | | |
| .------------. | | .------------------. |
| | derivation |----|-instantiate-|->| store derivation | |
| '------------' | | '------------------' |
| | | | |
| | | realise |
| | | | |
| | | V |
| .----------------. | | .--------------. |
| | Nix expression |<-|----read-----|----| store object | |
| '----------------' | | '--------------' |
| | | | |
| evaluate | | |
| | | | |
| V | | |
| .------------. | | |
| | value | | | |
| '------------' | | |
+----------------------+ +------------------------+
In more detail, the following sequence diagram shows how the expression is evaluated step by step, and where evaluation is blocked to wait for the build output to appear.
.-------. .-------------. .---------.
|Nix CLI| |Nix evaluator| |Nix store|
'-------' '-------------' '---------'
| | |
|evaluate IFD.nix| |
|--------------->| |
| | |
| evaluate `"${readFile drv} world"` |
| | |
| evaluate `readFile drv` |
| | |
| evaluate `drv` as string |
| | |
| |instantiate /nix/store/...-hello.drv|
| |----------------------------------->|
| : |
| : realise /nix/store/...-hello.drv |
| :----------------------------------->|
| : |
| |--------.
| : | |
| (evaluation blocked) | echo hello > $out
| : | |
| |<-------'
| : /nix/store/...-hello |
| |<-----------------------------------|
| | |
| resume `readFile /nix/store/...-hello` |
| | |
| | readFile /nix/store/...-hello |
| |----------------------------------->|
| | |
| | hello |
| |<-----------------------------------|
| | |
| resume `"${"hello"} world"` |
| | |
| resume `"hello world"` |
| | |
| "hello world" | |
|<---------------| |
.-------. .-------------. .---------.
|Nix CLI| |Nix evaluator| |Nix store|
'-------' '-------------' '---------'
Built-in Constants
These constants are built into the Nix language evaluator:
builtins
(set)
Contains all the built-in functions and values.
Since built-in functions were added over time, testing for attributes in builtins
can be used for graceful fallback on older Nix installations:
# if hasContext is not available, we assume `s` has a context
if builtins ? hasContext then builtins.hasContext s else true
currentSystem
(string)
The value of the system
configuration option.
It can be used to set the system
attribute for builtins.derivation
such that the resulting derivation can be built on the same system that evaluates the Nix expression:
builtins.derivation {
# ...
system = builtins.currentSystem;
}
It can be overridden in order to create derivations for different system than the current one:
$ nix-instantiate --system "mips64-linux" --eval --expr 'builtins.currentSystem' "mips64-linux"
Note
Not available in pure evaluation mode.
currentTime
(integer)
Return the Unix time at first evaluation. Repeated references to that name will re-use the initially obtained value.
Example:
$ nix repl
Welcome to Nix 2.15.1 Type :? for help.
nix-repl> builtins.currentTime
1683705525
nix-repl> builtins.currentTime
1683705525
The store path of a derivation depending on currentTime
will differ for each evaluation, unless both evaluate builtins.currentTime
in the same second.
Note
Not available in pure evaluation mode.
false
(Boolean)
Primitive value.
It can be returned by comparison operators and used in conditional expressions.
The name false
is not special, and can be shadowed:
nix-repl> let false = 1; in false
1
langVersion
(integer)
The current version of the Nix language.
nixPath
(list)
List of search path entries used to resolve lookup paths.
Lookup path expressions can be desugared using this and builtins.findFile
:
<nixpkgs>
is equivalent to:
builtins.findFile builtins.nixPath "nixpkgs"
nixVersion
(string)
The version of Nix.
For example, where the command line returns the current Nix version,
$ nix --version nix (Nix)
2.16.0
the Nix language evaluator returns the same value:
nix-repl> builtins.nixVersion
"2.16.0"
null
(null)
Primitive value.
The name null
is not special, and can be shadowed:
nix-repl> let null = 1; in null
1
storeDir
(string)
Logical file system location of the Nix store currently in use.
This value is determined by the store
parameter in Store URLs:
$ nix-instantiate --store 'dummy://?store=/blah' --eval --expr builtins.storeDir "/blah"
true
(Boolean)
Primitive value.
It can be returned by comparison operators and used in conditional expressions.
The name true
is not special, and can be shadowed:
nix-repl> let true = 1; in true
1
Built-in Functions
This section lists the functions built into the Nix language evaluator. All built-in functions are available through the global builtins
constant.
For convenience, some built-ins can be accessed directly:
derivation is described in its own section.
Abort Nix expression evaluation and print the error message s.
Return the sum of the numbers e1 and e2.
Return true
if the function pred returns true
for all elements of list, and false
otherwise.
Return true
if the function pred returns true
for at least one element of list, and false
otherwise.
Return the names of the attributes in the set set in an alphabetically sorted list. For instance, builtins.attrNames { y = 1; x = "foo"; }
evaluates to [ "x" "y" ]
.
Return the values of the attributes in the set set in the order corresponding to the sorted attribute names.
Return the base name of the string s, that is, everything following the final slash in the string. This is similar to the GNU basename
command.
Return the bitwise AND of the integers e1 and e2.
Return the bitwise OR of the integers e1 and e2.
Return the bitwise XOR of the integers e1 and e2.
In debug mode (enabled using --debugger
), pause Nix expression evaluation and enter the REPL. Otherwise, return the argument v
.
Collect each attribute named attr from a list of attribute sets. Attrsets that don't contain the named attribute are ignored. For example,
builtins.catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
evaluates to [1 2]
.
Converts an IEEE-754 double-precision floating-point number (double) to the next higher integer.
If the datatype is neither an integer nor a "float", an evaluation error will be thrown.
Compare two strings representing versions and return -1
if version s1 is older than version s2, 0
if they are the same, and 1
if s1 is newer than s2. The version comparison algorithm is the same as the one used by nix-env -u
.
Concatenate a list of lists into a single list.
This function is equivalent to builtins.concatLists (map f list)
but is more efficient.
concatStringsSep separator list
Concatenate a list of strings with a separator between each element, e.g. concatStringsSep "/" ["usr" "local" "bin"] == "usr/local/bin"
.
This is like seq e1 e2
, except that e1 is evaluated deeply: if it’s a list or set, its elements or attributes are also evaluated recursively.
Return the directory part of the string s, that is, everything before the final slash in the string. This is similar to the GNU dirname
command.
Return the quotient of the numbers e1 and e2.
Return true
if a value equal to x occurs in the list xs, and false
otherwise.
Return element n from the list xs. Elements are counted starting from 0. A fatal error occurs if the index is out of bounds.
Fetch a store path closure from a binary cache, and return the store path as a string with context.
This function can be invoked in three ways, that we will discuss in order of preference.
Fetch a content-addressed store path
Example:
builtins.fetchClosure {
fromStore = "https://cache.nixos.org";
fromPath = /nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1;
}
This is the simplest invocation, and it does not require the user of the expression to configure trusted-public-keys
to ensure their authenticity.
If your store path is input addressed instead of content addressed, consider the other two invocations.
Fetch any store path and rewrite it to a fully content-addressed store path
Example:
builtins.fetchClosure {
fromStore = "https://cache.nixos.org";
fromPath = /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1;
toPath = /nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1;
}
This example fetches /nix/store/r2jd...
from the specified binary cache, and rewrites it into the content-addressed store path /nix/store/ldbh...
.
Like the previous example, no extra configuration or privileges are required.
To find out the correct value for toPath
given a fromPath
, use nix store make-content-addressed
:
# nix store make-content-addressed --from https://cache.nixos.org /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1
rewrote '/nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1' to '/nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1'
Alternatively, set toPath = ""
and find the correct toPath
in the error message.
Fetch an input-addressed store path as is
Example:
builtins.fetchClosure {
fromStore = "https://cache.nixos.org";
fromPath = /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1;
inputAddressed = true;
}
It is possible to fetch an input-addressed store path and return it as is. However, this is the least preferred way of invoking fetchClosure
, because it requires that the input-addressed paths are trusted by the Nix configuration.
builtins.storePath
fetchClosure
is similar to builtins.storePath
in that it allows you to use a previously built store path in a Nix expression. However, fetchClosure
is more reproducible because it specifies a binary cache from which the path can be fetched. Also, using content-addressed store paths does not require users to configure trusted-public-keys
to ensure their authenticity.
This function is only available if the fetch-closure experimental feature is enabled.
Fetch a path from git. args can be a URL, in which case the HEAD of the repo at that URL is fetched. Otherwise, it can be an attribute with the following attributes (all except url
optional):
url
The URL of the repo.
name
(default: basename of the URL)The name of the directory the repo should be exported to in the store.
rev
(default: the tip ofref
)The Git revision to fetch. This is typically a commit hash.
ref
(default:HEAD
)The Git reference under which to look for the requested revision. This is often a branch or tag name.
By default, the
ref
value is prefixed withrefs/heads/
. As of 2.3.0, Nix will not prefixrefs/heads/
ifref
starts withrefs/
.submodules
(default:false
)A Boolean parameter that specifies whether submodules should be checked out.
shallow
(default:false
)A Boolean parameter that specifies whether fetching a shallow clone is allowed.
allRefs
Whether to fetch all references of the repository. With this argument being true, it's possible to load a
rev
from anyref
(by default onlyrev
s from the specifiedref
are supported).
Here are some examples of how to use fetchGit
.
To fetch a private repository over SSH:
builtins.fetchGit { url = "git@github.com:my-secret/repository.git"; ref = "master"; rev = "adab8b916a45068c044658c4158d81878f9ed1c3"; }
To fetch an arbitrary reference:
builtins.fetchGit { url = "https://github.com/NixOS/nix.git"; ref = "refs/heads/0.5-release"; }
If the revision you're looking for is in the default branch of the git repository you don't strictly need to specify the branch name in the
ref
attribute.However, if the revision you're looking for is in a future branch for the non-default branch you will need to specify the the
ref
attribute as well.builtins.fetchGit { url = "https://github.com/nixos/nix.git"; rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452"; ref = "1.11-maintenance"; }
Note
It is nice to always specify the branch which a revision belongs to. Without the branch being specified, the fetcher might fail if the default branch changes. Additionally, it can be confusing to try a commit from a non-default branch and see the fetch fail. If the branch is specified the fault is much more obvious.
If the revision you're looking for is in the default branch of the git repository you may omit the
ref
attribute.builtins.fetchGit { url = "https://github.com/nixos/nix.git"; rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452"; }
To fetch a specific tag:
builtins.fetchGit { url = "https://github.com/nixos/nix.git"; ref = "refs/tags/1.9"; }
To fetch the latest version of a remote branch:
builtins.fetchGit { url = "ssh://git@github.com/nixos/nix.git"; ref = "master"; }
Nix will refetch the branch according to the
tarball-ttl
setting.This behavior is disabled in pure evaluation mode.
To fetch the content of a checked-out work directory:
builtins.fetchGit ./work-dir
If the URL points to a local directory, and no ref
or rev
is given, fetchGit
will use the current content of the checked-out files, even if they are not committed or added to Git's index. It will only consider files added to the Git repository, as listed by git ls-files
.
Download the specified URL, unpack it and return the path of the unpacked tree. The file must be a tape archive (.tar
) compressed with gzip
, bzip2
or xz
. The top-level path component of the files in the tarball is removed, so it is best if the tarball contains a single directory at top level. The typical use of the function is to obtain external Nix expression dependencies, such as a particular version of Nixpkgs, e.g.
with import (fetchTarball https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz) {};
stdenv.mkDerivation { … }
The fetched tarball is cached for a certain amount of time (1 hour by default) in ~/.cache/nix/tarballs/
. You can change the cache timeout either on the command line with --tarball-ttl
number-of-seconds or in the Nix configuration file by adding the line tarball-ttl =
number-of-seconds.
Note that when obtaining the hash with nix-prefetch-url
the option --unpack
is required.
This function can also verify the contents against a hash. In that case, the function takes a set instead of a URL. The set requires the attribute url
and the attribute sha256
, e.g.
with import (fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz";
sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2"; }) {};
stdenv.mkDerivation { … }
Not available in restricted evaluation mode.
Fetch a source tree or a plain file using one of the supported backends. input can be an attribute set representation of flake reference or a URL. The input should be "locked", that is, it should contain a commit hash or content hash unless impure evaluation (--impure
) is allowed.
Here are some examples of how to use fetchTree
:
Fetch a GitHub repository:
builtins.fetchTree { type = "github"; owner = "NixOS"; repo = "nixpkgs"; rev = "ae2e6b3958682513d28f7d633734571fb18285dd"; }
This evaluates to attribute set:
{ lastModified = 1686503798; lastModifiedDate = "20230611171638"; narHash = "sha256-rA9RqKP9OlBrgGCPvfd5HVAXDOy8k2SmPtB/ijShNXc="; outPath = "/nix/store/l5m6qlvfs9sdw14ja3qbzpglcjlb6j1x-source"; rev = "ae2e6b3958682513d28f7d633734571fb18285dd"; shortRev = "ae2e6b3"; }
Fetch a single file from a URL:
builtins.fetchTree "https://example.com/"
This function is only available if the flakes experimental feature is enabled.
Download the specified URL and return the path of the downloaded file.
Not available in restricted evaluation mode.
Return a list consisting of the elements of list for which the function f returns true
.
Warning
filterSource
should not be used to filter store paths. SincefilterSource
uses the name of the input directory while naming the output directory, doing so will produce a directory name in the form of<hash2>-<hash>-<name>
, where<hash>-<name>
is the name of the input directory. Since<hash>
depends on the unfiltered directory, the name of the output directory will indirectly depend on files that are filtered out by the function. This will trigger a rebuild even when a filtered out file is changed. Usebuiltins.path
instead, which allows specifying the name of the output directory.
This function allows you to copy sources into the Nix store while filtering certain files. For instance, suppose that you want to use the directory source-dir
as an input to a Nix expression, e.g.
stdenv.mkDerivation {
...
src = ./source-dir;
}
However, if source-dir
is a Subversion working copy, then all those annoying .svn
subdirectories will also be copied to the store. Worse, the contents of those directories may change a lot, causing lots of spurious rebuilds. With filterSource
you can filter out the .svn
directories:
src = builtins.filterSource
(path: type: type != "directory" || baseNameOf path != ".svn")
./source-dir;
Thus, the first argument e1 must be a predicate function that is called for each regular file, directory or symlink in the source tree e2. If the function returns true
, the file is copied to the Nix store, otherwise it is omitted. The function is called with two arguments. The first is the full path of the file. The second is a string that identifies the type of the file, which is either "regular"
, "directory"
, "symlink"
or "unknown"
(for other kinds of files such as device nodes or fifos — but note that those cannot be copied to the Nix store, so if the predicate returns true
for them, the copy will fail). If you exclude a directory, the entire corresponding subtree of e2 will be excluded.
findFile search-path lookup-path
Find lookup-path in search-path.
A search path is represented list of attribute sets with two attributes:
prefix
is a relative path.path
denotes a file system location The exact syntax depends on the command line interface.
Examples of search path attribute sets:
1
{ prefix = "nixos-config"; path = "/etc/nixos/configuration.nix"; }
2
{ prefix = ""; path = "/nix/var/nix/profiles/per-user/root/channels"; }
The lookup algorithm checks each entry until a match is found, returning a path value of the match:
- If lookup-path matches
prefix
, then the remainder of lookup-path (the "suffix") is searched for within the directory denoted bypath
. Note that thepath
may need to be downloaded at this point to look inside. - If the suffix is found inside that directory, then the entry is a match. The combined absolute path of the directory (now downloaded if need be) and the suffix is returned.
Lookup path expressions can be desugared using this and builtins.nixPath
:
<nixpkgs>
is equivalent to:
builtins.findFile builtins.nixPath "nixpkgs"
Convert a flake reference from attribute set format to URL format.
For example:
builtins.flakeRefToString {
dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github";
}
evaluates to
"github:NixOS/nixpkgs/23.05?dir=lib"
This function is only available if the flakes experimental feature is enabled.
Converts an IEEE-754 double-precision floating-point number (double) to the next lower integer.
If the datatype is neither an integer nor a "float", an evaluation error will be thrown.
Reduce a list by applying a binary operator, from left to right, e.g. foldl' op nul [x0 x1 x2 ...] = op (op (op nul x0) x1) x2) ...
. For example, foldl' (x: y: x + y) 0 [1 2 3]
evaluates to 6. The return value of each application of op
is evaluated immediately, even for intermediate values.
Convert a JSON string to a Nix value. For example,
builtins.fromJSON ''{"x": [1, 2, 3], "y": null}''
returns the value { x = [ 1 2 3 ]; y = null; }
.
Convert a TOML string to a Nix value. For example,
builtins.fromTOML ''
x=1
s="a"
[table]
y=2
''
returns the value { s = "a"; table = { y = 2; }; x = 1; }
.
Return a set containing the names of the formal arguments expected by the function f. The value of each attribute is a Boolean denoting whether the corresponding argument has a default value. For instance, functionArgs ({ x, y ? 123}: ...) = { x = false; y = true; }
.
"Formal argument" here refers to the attributes pattern-matched by the function. Plain lambdas are not included, e.g. functionArgs (x: ...) = { }
.
Generate list of size length, with each element i equal to the value returned by generator i
. For example,
builtins.genList (x: x * x) 5
returns the list [ 0 1 4 9 16 ]
.
Take an attrset with values named startSet
and operator
in order to return a list of attrsets by starting with the startSet
and recursively applying the operator
function to each item
. The attrsets in the startSet
and the attrsets produced by operator
must contain a value named key
which is comparable. The result is produced by calling operator
for each item
with a value for key
that has not been called yet including newly produced item
s. The function terminates when no new item
s are produced. The resulting list of attrsets contains only attrsets with a unique key. For example,
builtins.genericClosure {
startSet = [ {key = 5;} ];
operator = item: [{
key = if (item.key / 2 ) * 2 == item.key
then item.key / 2
else 3 * item.key + 1;
}];
}
evaluates to
[ { key = 5; } { key = 16; } { key = 8; } { key = 4; } { key = 2; } { key = 1; } ]
getAttr
returns the attribute named s from set. Evaluation aborts if the attribute doesn’t exist. This is a dynamic version of the .
operator, since s is an expression rather than an identifier.
Return the string context of s.
The string context tracks references to derivations within a string. It is represented as an attribute set of store derivation paths mapping to output names.
Using string interpolation on a derivation will add that derivation to the string context. For example,
builtins.getContext "${derivation { name = "a"; builder = "b"; system = "c"; }}"
evaluates to
{ "/nix/store/arhvjaf6zmlyn8vh8fgn55rpwnxq0n7l-a.drv" = { outputs = [ "out" ]; }; }
getEnv
returns the value of the environment variable s, or an empty string if the variable doesn’t exist. This function should be used with care, as it can introduce all sorts of nasty environment dependencies in your Nix expression.
getEnv
is used in Nix Packages to locate the file ~/.nixpkgs/config.nix
, which contains user-local settings for Nix Packages. (That is, it does a getEnv "HOME"
to locate the user’s home directory.)
Fetch a flake from a flake reference, and return its output attributes and some metadata. For example:
(builtins.getFlake "nix/55bc52401966fbffa525c574c14f67b00bc4fb3a").packages.x86_64-linux.nix
Unless impure evaluation is allowed (--impure
), the flake reference must be "locked", e.g. contain a Git revision or content hash. An example of an unlocked usage is:
(builtins.getFlake "github:edolstra/dwarffs").rev
This function is only available if the flakes experimental feature is enabled.
Groups elements of list together by the string returned from the function f called on each element. It returns an attribute set where each attribute value contains the elements of list that are mapped to the same corresponding attribute name returned by f.
For example,
builtins.groupBy (builtins.substring 0 1) ["foo" "bar" "baz"]
evaluates to
{ b = [ "bar" "baz" ]; f = [ "foo" ]; }
hasAttr
returns true
if set has an attribute named s, and false
otherwise. This is a dynamic version of the ?
operator, since s is an expression rather than an identifier.
Return true
if string s has a non-empty context. The context can be obtained with getContext
.
Return a base-16 representation of the cryptographic hash of the file at path p. The hash algorithm specified by type must be one of "md5"
, "sha1"
, "sha256"
or "sha512"
.
Return a base-16 representation of the cryptographic hash of string s. The hash algorithm specified by type must be one of "md5"
, "sha1"
, "sha256"
or "sha512"
.
Return the first element of a list; abort evaluation if the argument isn’t a list or is an empty list. You can test whether a list is empty by comparing it with []
.
Load, parse, and return the Nix expression in the file path.
Note
Unlike some languages,
import
is a regular function in Nix.
The path argument must meet the same criteria as an interpolated expression.
If path is a directory, the file default.nix
in that directory is used if it exists.
Example
$ echo 123 > default.nix
Import
default.nix
from the current directory.
import ./.
123
Evaluation aborts if the file doesn’t exist or contains an invalid Nix expression.
A Nix expression loaded by import
must not contain any free variables, that is, identifiers that are not defined in the Nix expression itself and are not built-in. Therefore, it cannot refer to variables that are in scope at the call site.
Example
If you have a calling expression
rec { x = 123; y = import ./foo.nix; }
then the following
foo.nix
will give an error:
# foo.nix x + 456
since
x
is not in scope infoo.nix
. If you wantx
to be available infoo.nix
, pass it as a function argument:
rec { x = 123; y = import ./foo.nix x; }
and
# foo.nix x: x + 456
The function argument doesn’t have to be called
x
infoo.nix
; any name would work.
Return a set consisting of the attributes in the set e2 which have the same name as some attribute in e1.
Performs in O(n log m) where n is the size of the smaller set and m the larger set's size.
Return true
if e evaluates to a set, and false
otherwise.
Return true
if e evaluates to a bool, and false
otherwise.
Return true
if e evaluates to a float, and false
otherwise.
Return true
if e evaluates to a function, and false
otherwise.
Return true
if e evaluates to an integer, and false
otherwise.
Return true
if e evaluates to a list, and false
otherwise.
Return true
if e evaluates to null
, and false
otherwise.
Warning
This function is deprecated; just write
e == null
instead.
Return true
if e evaluates to a path, and false
otherwise.
Return true
if e evaluates to a string, and false
otherwise.
Return the length of the list e.
Return true
if the number e1 is less than the number e2, and false
otherwise. Evaluation aborts if either e1 or e2 does not evaluate to a number.
Construct a set from a list specifying the names and values of each attribute. Each element of the list should be a set consisting of a string-valued attribute name
specifying the name of the attribute, and an attribute value
specifying its value.
In case of duplicate occurrences of the same name, the first takes precedence.
Example:
builtins.listToAttrs
[ { name = "foo"; value = 123; }
{ name = "bar"; value = 456; }
{ name = "bar"; value = 420; }
]
evaluates to
{ foo = 123; bar = 456; }
Apply the function f to each element in the list list. For example,
map (x: "foo" + x) [ "bar" "bla" "abc" ]
evaluates to [ "foobar" "foobla" "fooabc" ]
.
Apply function f to every element of attrset. For example,
builtins.mapAttrs (name: value: value * 10) { a = 1; b = 2; }
evaluates to { a = 10; b = 20; }
.
Returns a list if the extended POSIX regular expression regex matches str precisely, otherwise returns null
. Each item in the list is a regex group.
builtins.match "ab" "abc"
Evaluates to null
.
builtins.match "abc" "abc"
Evaluates to [ ]
.
builtins.match "a(b)(c)" "abc"
Evaluates to [ "b" "c" ]
.
builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO "
Evaluates to [ "FOO" ]
.
Return the product of the numbers e1 and e2.
outputOf derivation-reference output-name
Return the output path of a derivation, literally or using a placeholder if needed.
If the derivation has a statically-known output path (i.e. the derivation output is input-addressed, or fixed content-addresed), the output path will just be returned. But if the derivation is content-addressed or if the derivation is itself not-statically produced (i.e. is the output of another derivation), a placeholder will be returned instead.
derivation reference
must be a string that may contain a regular store path to a derivation, or may be a placeholder reference. If the derivation is produced by a derivation, you must explicitly select drv.outPath
. This primop can be chained arbitrarily deeply. For instance,
builtins.outputOf
(builtins.outputOf myDrv "out)
"out"
will return a placeholder for the output of the output of myDrv
.
This primop corresponds to the ^
sigil for derivable paths, e.g. as part of installable syntax on the command line.
This function is only available if the dynamic-derivations experimental feature is enabled.
Split the string s into a package name and version. The package name is everything up to but not including the first dash not followed by a letter, and the version is everything following that dash. The result is returned in a set { name, version }
. Thus, builtins.parseDrvName "nix-0.12pre12876"
returns { name = "nix"; version = "0.12pre12876"; }
.
Parse a flake reference, and return its exploded form.
For example:
builtins.parseFlakeRef "github:NixOS/nixpkgs/23.05?dir=lib"
evaluates to:
{ dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github"; }
This function is only available if the flakes experimental feature is enabled.
Given a predicate function pred, this function returns an attrset containing a list named right
, containing the elements in list for which pred returned true
, and a list named wrong
, containing the elements for which it returned false
. For example,
builtins.partition (x: x > 10) [1 23 9 3 42]
evaluates to
{ right = [ 23 42 ]; wrong = [ 1 9 3 ]; }
An enrichment of the built-in path type, based on the attributes present in args. All are optional except path
:
path
The underlying path.name
The name of the path when added to the store. This can used to reference paths that have nix-illegal characters in their names, like@
.filter
A function of the type expected bybuiltins.filterSource
, with the same semantics.recursive
Whenfalse
, whenpath
is added to the store it is with a flat hash, rather than a hash of the NAR serialization of the file. Thus,path
must refer to a regular file, not a directory. This allows similar behavior tofetchurl
. Defaults totrue
.sha256
When provided, this is the expected hash of the file at the path. Evaluation will fail if the hash is incorrect, and providing a hash allowsbuiltins.path
to be used even when thepure-eval
nix config option is on.
Return true
if the path path exists at evaluation time, and false
otherwise.
Return a placeholder string for the specified output that will be substituted by the corresponding output path at build time. Typical outputs would be "out"
, "bin"
or "dev"
.
Return the contents of the directory path as a set mapping directory entries to the corresponding file type. For instance, if directory A
contains a regular file B
and another directory C
, then builtins.readDir ./A
will return the set
{ B = "regular"; C = "directory"; }
The possible values for the file type are "regular"
, "directory"
, "symlink"
and "unknown"
.
Return the contents of the file path as a string.
Determine the directory entry type of a filesystem node, being one of "directory", "regular", "symlink", or "unknown".
Remove the attributes listed in list from set. The attributes don’t have to exist in set. For instance,
removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]
evaluates to { y = 2; }
.
Given string s, replace every occurrence of the strings in from with the corresponding string in to.
The argument to is lazy, that is, it is only evaluated when its corresponding pattern in from is matched in the string s
Example:
builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar"
evaluates to "fabir"
.
Evaluate e1, then evaluate and return e2. This ensures that a computation is strict in the value of e1.
Return list in sorted order. It repeatedly calls the function comparator with two elements. The comparator should return true
if the first element is less than the second, and false
otherwise. For example,
builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
produces the list [ 42 77 147 249 483 526 ]
.
This is a stable sort: it preserves the relative order of elements deemed equal by the comparator.
Returns a list composed of non matched strings interleaved with the lists of the extended POSIX regular expression regex matches of str. Each item in the lists of matched sequences is a regex group.
builtins.split "(a)b" "abc"
Evaluates to [ "" [ "a" ] "c" ]
.
builtins.split "([ac])" "abc"
Evaluates to [ "" [ "a" ] "b" [ "c" ] "" ]
.
builtins.split "(a)|(c)" "abc"
Evaluates to [ "" [ "a" null ] "b" [ null "c" ] "" ]
.
builtins.split "([[:upper:]]+)" " FOO "
Evaluates to [ " " [ "FOO" ] " " ]
.
Split a string representing a version into its components, by the same version splitting logic underlying the version comparison in nix-env -u
.
This function allows you to define a dependency on an already existing store path. For example, the derivation attribute src = builtins.storePath /nix/store/f1d18v1y…-source
causes the derivation to depend on the specified path, which must exist or be substitutable. Note that this differs from a plain path (e.g. src = /nix/store/f1d18v1y…-source
) in that the latter causes the path to be copied again to the Nix store, resulting in a new path (e.g. /nix/store/ld01dnzc…-source-source
).
Not available in pure evaluation mode.
See also builtins.fetchClosure
.
Return the length of the string e. If e is not a string, evaluation is aborted.
Return the difference between the numbers e1 and e2.
Return the substring of s from character position start (zero-based) up to but not including start + len. If start is greater than the length of the string, an empty string is returned, and if start + len lies beyond the end of the string, only the substring up to the end of the string is returned. start must be non-negative. For example,
builtins.substring 0 3 "nixos"
evaluates to "nix"
.
Return the list without its first item; abort evaluation if the argument isn’t a list or is an empty list.
Warning
This function should generally be avoided since it's inefficient: unlike Haskell's
tail
, it takes O(n) time, so recursing over a list by repeatedly callingtail
takes O(n^2) time.
Throw an error message s. This usually aborts Nix expression evaluation, but in nix-env -qa
and other commands that try to evaluate a set of derivations to get information about those derivations, a derivation that throws an error is silently skipped (which is not the case for abort
).
Store the string s in a file in the Nix store and return its path. The file has suffix name. This file can be used as an input to derivations. One application is to write builders “inline”. For instance, the following Nix expression combines the Nix expression for GNU Hello and its build script into one file:
{ stdenv, fetchurl, perl }:
stdenv.mkDerivation {
name = "hello-2.1.1";
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
PATH=$perl/bin:$PATH
tar xvfz $src
cd hello-*
./configure --prefix=$out
make
make install
";
src = fetchurl {
url = "http://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
};
inherit perl;
}
It is even possible for one file to refer to another, e.g.,
builder = let
configFile = builtins.toFile "foo.conf" "
# This is some dummy configuration file.
...
";
in builtins.toFile "builder.sh" "
source $stdenv/setup
...
cp ${configFile} $out/etc/foo.conf
";
Note that ${configFile}
is a string interpolation, so the result of the expression configFile
(i.e., a path like /nix/store/m7p7jfny445k...-foo.conf
) will be spliced into the resulting string.
It is however not allowed to have files mutually referring to each other, like so:
let
foo = builtins.toFile "foo" "...${bar}...";
bar = builtins.toFile "bar" "...${foo}...";
in foo
This is not allowed because it would cause a cyclic dependency in the computation of the cryptographic hashes for foo
and bar
.
It is also not possible to reference the result of a derivation. If you are using Nixpkgs, the writeTextFile
function is able to do that.
Return a string containing a JSON representation of e. Strings, integers, floats, booleans, nulls and lists are mapped to their JSON equivalents. Sets (except derivations) are represented as objects. Derivations are translated to a JSON string containing the derivation’s output path. Paths are copied to the store and represented as a JSON string of the resulting store path.
DEPRECATED. Use /. + "/path"
to convert a string into an absolute path. For relative paths, use ./. + "/path"
.
Convert the expression e to a string. e can be:
A string (in which case the string is returned unmodified).
A path (e.g.,
toString /foo/bar
yields"/foo/bar"
.A set containing
{ __toString = self: ...; }
or{ outPath = ...; }
.An integer.
A list, in which case the string representations of its elements are joined with spaces.
A Boolean (
false
yields""
,true
yields"1"
).null
, which yields the empty string.
Return a string containing an XML representation of e. The main application for toXML
is to communicate information with the builder in a more structured format than plain environment variables.
Here is an example where this is the case:
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
stdenv.mkDerivation (rec {
name = "web-server";
buildInputs = [ libxslt ];
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
mkdir $out
echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml ①
";
stylesheet = builtins.toFile "stylesheet.xsl" ②
"<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/'>
<Configure>
<xsl:for-each select='/expr/list/attrs'>
<Call name='addWebApplication'>
<Arg><xsl:value-of select=\"attr[@name = 'path']/string/@value\" /></Arg>
<Arg><xsl:value-of select=\"attr[@name = 'war']/path/@value\" /></Arg>
</Call>
</xsl:for-each>
</Configure>
</xsl:template>
</xsl:stylesheet>
";
servlets = builtins.toXML [ ③
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
];
})
The builder is supposed to generate the configuration file for a Jetty servlet container. A servlet container contains a number of servlets (*.war
files) each exported under a specific URI prefix. So the servlet configuration is a list of sets containing the path
and war
of the servlet (①). This kind of information is difficult to communicate with the normal method of passing information through an environment variable, which just concatenates everything together into a string (which might just work in this case, but wouldn’t work if fields are optional or contain lists themselves). Instead the Nix expression is converted to an XML representation with toXML
, which is unambiguous and can easily be processed with the appropriate tools. For instance, in the example an XSLT stylesheet (at point ②) is applied to it (at point ①) to generate the XML configuration file for the Jetty server. The XML representation produced at point ③ by toXML
is as follows:
<?xml version='1.0' encoding='utf-8'?>
<expr>
<list>
<attrs>
<attr name="path">
<string value="/bugtracker" />
</attr>
<attr name="war">
<path value="/nix/store/d1jh9pasa7k2...-jira/lib/atlassian-jira.war" />
</attr>
</attrs>
<attrs>
<attr name="path">
<string value="/wiki" />
</attr>
<attr name="war">
<path value="/nix/store/y6423b1yi4sx...-uberwiki/uberwiki.war" />
</attr>
</attrs>
</list>
</expr>
Note that we used the toFile
built-in to write the builder and the stylesheet “inline” in the Nix expression. The path of the stylesheet is spliced into the builder using the syntax xsltproc ${stylesheet}
.
Evaluate e1 and print its abstract syntax representation on standard error. Then return e2. This function is useful for debugging.
Evaluate e1 and print its abstract syntax representation on standard error if --trace-verbose
is enabled. Then return e2. This function is useful for debugging.
Try to shallowly evaluate e. Return a set containing the attributes success
(true
if e evaluated successfully, false
if an error was thrown) and value
, equalling e if successful and false
otherwise. tryEval
will only prevent errors created by throw
or assert
from being thrown. Errors tryEval
will not catch are for example those created by abort
and type errors generated by builtins. Also note that this doesn't evaluate e deeply, so let e = { x = throw ""; }; in (builtins.tryEval e).success
will be true
. Using builtins.deepSeq
one can get the expected result: let e = { x = throw ""; }; in (builtins.tryEval (builtins.deepSeq e e)).success
will be false
.
Return a string representing the type of the value e, namely "int"
, "bool"
, "string"
, "path"
, "null"
, "set"
, "list"
, "lambda"
or "float"
.
Transpose a list of attribute sets into an attribute set of lists, then apply mapAttrs
.
f
receives two arguments: the attribute name and a non-empty list of all values encountered for that attribute name.
The result is an attribute set where the attribute names are the union of the attribute names in each element of list
. The attribute values are the return values of f
.
builtins.zipAttrsWith
(name: values: { inherit name values; })
[ { a = "x"; } { a = "y"; b = "z"; } ]
evaluates to
{
a = { name = "a"; values = [ "x" "y" ]; };
b = { name = "b"; values = [ "z" ]; };
}