mirror of
https://github.com/NixOS/nix
synced 2025-06-26 11:41:15 +02:00
Enable syntax highlighting
This commit is contained in:
parent
0c94c17644
commit
1d0a7b54fa
46 changed files with 1770 additions and 1155 deletions
|
@ -6,7 +6,9 @@ Derivations can declare some infrequently used optional attributes.
|
|||
The optional attribute `allowedReferences` specifies a list of legal
|
||||
references (dependencies) of the output of the builder. For example,
|
||||
|
||||
allowedReferences = [];
|
||||
```nix
|
||||
allowedReferences = [];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have any runtime
|
||||
dependencies on its inputs. To allow an output to have a runtime
|
||||
|
@ -20,7 +22,9 @@ Derivations can declare some infrequently used optional attributes.
|
|||
the legal requisites of the whole closure, so all the dependencies
|
||||
recursively. For example,
|
||||
|
||||
allowedRequisites = [ foobar ];
|
||||
```nix
|
||||
allowedRequisites = [ foobar ];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have any other
|
||||
runtime dependency than `foobar`, and in addition it enforces that
|
||||
|
@ -31,7 +35,9 @@ Derivations can declare some infrequently used optional attributes.
|
|||
illegal references (dependencies) of the output of the builder. For
|
||||
example,
|
||||
|
||||
disallowedReferences = [ foo ];
|
||||
```nix
|
||||
disallowedReferences = [ foo ];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have a direct
|
||||
runtime dependencies on the derivation `foo`.
|
||||
|
@ -41,7 +47,9 @@ Derivations can declare some infrequently used optional attributes.
|
|||
specifies illegal requisites for the whole closure, so all the
|
||||
dependencies recursively. For example,
|
||||
|
||||
disallowedRequisites = [ foobar ];
|
||||
```nix
|
||||
disallowedRequisites = [ foobar ];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have any runtime
|
||||
dependency on `foobar` or any other derivation depending recursively
|
||||
|
@ -50,20 +58,20 @@ Derivations can declare some infrequently used optional attributes.
|
|||
- `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 by `nix-store
|
||||
--register-validity` (with the deriver fields left empty). For
|
||||
example, when the following derivation is built:
|
||||
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 by `nix-store --register-validity`
|
||||
(with the deriver fields left empty). For example, when the
|
||||
following derivation is built:
|
||||
|
||||
derivation {
|
||||
...
|
||||
exportReferencesGraph = [ "libfoo-graph" libfoo ];
|
||||
};
|
||||
```nix
|
||||
derivation {
|
||||
...
|
||||
exportReferencesGraph = [ "libfoo-graph" libfoo ];
|
||||
};
|
||||
```
|
||||
|
||||
the references graph of `libfoo` is placed in the file
|
||||
`libfoo-graph` in the temporary build directory.
|
||||
|
@ -84,7 +92,9 @@ Derivations can declare some infrequently used optional attributes.
|
|||
environment variables to be passed unmodified. For example,
|
||||
`fetchurl` in Nixpkgs has the line
|
||||
|
||||
impureEnvVars = [ "http_proxy" "https_proxy" ... ];
|
||||
```nix
|
||||
impureEnvVars = [ "http_proxy" "https_proxy" ... ];
|
||||
```
|
||||
|
||||
to make it use the proxy server configuration specified by the user
|
||||
in the environment variables `http_proxy` and friends.
|
||||
|
@ -116,19 +126,23 @@ Derivations can declare some infrequently used optional attributes.
|
|||
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";
|
||||
}
|
||||
```nix
|
||||
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";
|
||||
}
|
||||
```nix
|
||||
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*
|
||||
|
@ -147,23 +161,25 @@ Derivations can declare some infrequently used optional attributes.
|
|||
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;
|
||||
}
|
||||
```nix
|
||||
{ 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
|
||||
|
@ -196,21 +212,19 @@ Derivations can declare some infrequently used optional attributes.
|
|||
A list of names of attributes that should be passed via files rather
|
||||
than environment variables. For example, if you have
|
||||
|
||||
```
|
||||
```nix
|
||||
passAsFile = ["big"];
|
||||
big = "a very long string";
|
||||
|
||||
```
|
||||
|
||||
then when the builder runs, the environment variable `bigPath` will
|
||||
contain the absolute path to a temporary file containing `a very
|
||||
long
|
||||
string`. That is, for any attribute *x* listed in `passAsFile`, Nix
|
||||
will pass an environment variable `xPath` 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).
|
||||
then when the builder runs, the environment variable `bigPath`
|
||||
will contain the absolute path to a temporary file containing `a
|
||||
very long string`. That is, for any attribute *x* listed in
|
||||
`passAsFile`, Nix will pass an environment variable `xPath`
|
||||
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 to `true` and [distributed building is
|
||||
|
|
|
@ -8,25 +8,27 @@ packages are imported and called with the appropriate arguments. Here
|
|||
are some fragments of `all-packages.nix`, with annotations of what
|
||||
they mean:
|
||||
|
||||
...
|
||||
|
||||
rec { ①
|
||||
|
||||
hello = import ../applications/misc/hello/ex-1 ② { ③
|
||||
inherit fetchurl stdenv perl;
|
||||
};
|
||||
|
||||
perl = import ../development/interpreters/perl { ④
|
||||
inherit fetchurl stdenv;
|
||||
};
|
||||
|
||||
fetchurl = import ../build-support/fetchurl {
|
||||
inherit stdenv; ...
|
||||
};
|
||||
|
||||
stdenv = ...;
|
||||
|
||||
}
|
||||
```nix
|
||||
...
|
||||
|
||||
rec { ①
|
||||
|
||||
hello = import ../applications/misc/hello/ex-1 ② { ③
|
||||
inherit fetchurl stdenv perl;
|
||||
};
|
||||
|
||||
perl = import ../development/interpreters/perl { ④
|
||||
inherit fetchurl stdenv;
|
||||
};
|
||||
|
||||
fetchurl = import ../build-support/fetchurl {
|
||||
inherit stdenv; ...
|
||||
};
|
||||
|
||||
stdenv = ...;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
1. This file defines a set of attributes, all of which are concrete
|
||||
derivations (i.e., not functions). In fact, we define a *mutually
|
||||
|
@ -64,11 +66,15 @@ they mean:
|
|||
> calls a function, filling in any missing arguments by passing the
|
||||
> corresponding attribute from the Nixpkgs set, like this:
|
||||
>
|
||||
> hello = callPackage ../applications/misc/hello/ex-1 { };
|
||||
> ```nix
|
||||
> hello = callPackage ../applications/misc/hello/ex-1 { };
|
||||
> ```
|
||||
>
|
||||
> If necessary, you can set or override arguments:
|
||||
>
|
||||
> hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
|
||||
> ```nix
|
||||
> hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
|
||||
> ```
|
||||
|
||||
4. Likewise, we have to instantiate Perl, `fetchurl`, and the standard
|
||||
environment.
|
||||
|
|
|
@ -3,15 +3,17 @@
|
|||
Here is the builder referenced from Hello's Nix expression (stored in
|
||||
`pkgs/applications/misc/hello/ex-1/builder.sh`):
|
||||
|
||||
source $stdenv/setup ①
|
||||
|
||||
PATH=$perl/bin:$PATH ②
|
||||
|
||||
tar xvfz $src ③
|
||||
cd hello-*
|
||||
./configure --prefix=$out ④
|
||||
make ⑤
|
||||
make install
|
||||
```bash
|
||||
source $stdenv/setup ①
|
||||
|
||||
PATH=$perl/bin:$PATH ②
|
||||
|
||||
tar xvfz $src ③
|
||||
cd hello-*
|
||||
./configure --prefix=$out ④
|
||||
make ⑤
|
||||
make install
|
||||
```
|
||||
|
||||
The builder can actually be made a lot shorter by using the *generic
|
||||
builder* functions provided by `stdenv`, but here we write out the build
|
||||
|
|
|
@ -51,7 +51,9 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
You can use `builtins` to test for the availability of features in
|
||||
the Nix installation, e.g.,
|
||||
|
||||
if builtins ? getEnv then builtins.getEnv "PATH" else ""
|
||||
```nix
|
||||
if builtins ? getEnv then builtins.getEnv "PATH" else ""
|
||||
```
|
||||
|
||||
This allows a Nix expression to fall back gracefully on older Nix
|
||||
installations that don’t have the desired built-in function.
|
||||
|
@ -114,9 +116,11 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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 { … }
|
||||
```nix
|
||||
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
|
||||
|
@ -124,19 +128,21 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
of seconds` or in the Nix configuration file with this option: `
|
||||
number of seconds to cache `.
|
||||
|
||||
Note that when obtaining the hash with ` nix-prefetch-url
|
||||
` the option `--unpack` is required.
|
||||
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 { … }
|
||||
```nix
|
||||
with import (fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz";
|
||||
sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2";
|
||||
}) {};
|
||||
|
||||
stdenv.mkDerivation { … }
|
||||
```
|
||||
|
||||
This function is not available if [restricted evaluation
|
||||
mode](../command-ref/conf-file.md) is enabled.
|
||||
|
@ -172,18 +178,22 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
|
||||
- To fetch a private repository over SSH:
|
||||
|
||||
builtins.fetchGit {
|
||||
url = "git@github.com:my-secret/repository.git";
|
||||
ref = "master";
|
||||
rev = "adab8b916a45068c044658c4158d81878f9ed1c3";
|
||||
}
|
||||
```nix
|
||||
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";
|
||||
}
|
||||
```nix
|
||||
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
|
||||
|
@ -193,11 +203,13 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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";
|
||||
}
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "https://github.com/nixos/nix.git";
|
||||
rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452";
|
||||
ref = "1.11-maintenance";
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
|
@ -211,24 +223,30 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
- 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";
|
||||
}
|
||||
```nix
|
||||
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";
|
||||
}
|
||||
```nix
|
||||
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
|
||||
builtins.fetchGit {
|
||||
url = "ssh://git@github.com/nixos/nix.git";
|
||||
ref = "master";
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
|
@ -248,10 +266,12 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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;
|
||||
}
|
||||
```nix
|
||||
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
|
||||
|
@ -259,10 +279,10 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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;
|
||||
```nix
|
||||
src = builtins.filterSource
|
||||
(path: type: type != "directory" || baseNameOf path != ".svn")
|
||||
./source-dir;
|
||||
```
|
||||
|
||||
Thus, the first argument *e1* must be a predicate function that is
|
||||
|
@ -279,10 +299,10 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
|
||||
- `builtins.foldl’` *op* *nul* *list*
|
||||
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) ...`. The operator is applied strictly, i.e.,
|
||||
its arguments are evaluated first. For example, `foldl’ (x: y: x +
|
||||
y) 0 [1 2 3]` evaluates to 6.
|
||||
e.g. `foldl’ op nul [x0 x1 x2 ...] = op (op (op nul x0) x1) x2)
|
||||
...`. The operator is applied strictly, i.e., its arguments are
|
||||
evaluated first. For example, `foldl’ (x: y: x + y) 0 [1 2 3]`
|
||||
evaluates to 6.
|
||||
|
||||
- `builtins.functionArgs` *f*
|
||||
Return a set containing the names of the formal arguments expected
|
||||
|
@ -298,16 +318,19 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
- `builtins.fromJSON` *e*
|
||||
Convert a JSON string to a Nix value. For example,
|
||||
|
||||
builtins.fromJSON ''{"x": [1, 2, 3], "y": null}''
|
||||
```nix
|
||||
builtins.fromJSON ''{"x": [1, 2, 3], "y": null}''
|
||||
```
|
||||
|
||||
returns the value `{ x = [ 1 2 3 ]; y = null;
|
||||
}`.
|
||||
returns the value `{ x = [ 1 2 3 ]; y = null; }`.
|
||||
|
||||
- `builtins.genList` *generator* *length*
|
||||
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
|
||||
```nix
|
||||
builtins.genList (x: x * x) 5
|
||||
```
|
||||
|
||||
returns the list `[ 0 1 4 9 16 ]`.
|
||||
|
||||
|
@ -369,26 +392,34 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
variables that are in scope at the call site. For instance, if you
|
||||
have a calling expression
|
||||
|
||||
rec {
|
||||
x = 123;
|
||||
y = import ./foo.nix;
|
||||
}
|
||||
```nix
|
||||
rec {
|
||||
x = 123;
|
||||
y = import ./foo.nix;
|
||||
}
|
||||
```
|
||||
|
||||
then the following `foo.nix` will give an error:
|
||||
|
||||
x + 456
|
||||
```nix
|
||||
x + 456
|
||||
```
|
||||
|
||||
since `x` is not in scope in `foo.nix`. If you want `x` to be
|
||||
available in `foo.nix`, you should pass it as a function argument:
|
||||
|
||||
rec {
|
||||
x = 123;
|
||||
y = import ./foo.nix x;
|
||||
}
|
||||
```nix
|
||||
rec {
|
||||
x = 123;
|
||||
y = import ./foo.nix x;
|
||||
}
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
x: x + 456
|
||||
```nix
|
||||
x: x + 456
|
||||
```
|
||||
|
||||
(The function argument doesn’t have to be called `x` in `foo.nix`;
|
||||
any name would work.)
|
||||
|
@ -442,23 +473,28 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
string-valued attribute `name` specifying the name of the attribute,
|
||||
and an attribute `value` specifying its value. Example:
|
||||
|
||||
builtins.listToAttrs
|
||||
[ { name = "foo"; value = 123; }
|
||||
{ name = "bar"; value = 456; }
|
||||
]
|
||||
```nix
|
||||
builtins.listToAttrs
|
||||
[ { name = "foo"; value = 123; }
|
||||
{ name = "bar"; value = 456; }
|
||||
]
|
||||
```
|
||||
|
||||
evaluates to
|
||||
|
||||
{ foo = 123; bar = 456; }
|
||||
```nix
|
||||
{ foo = 123; bar = 456; }
|
||||
```
|
||||
|
||||
- `map` *f* *list*; `builtins.map` *f* *list*
|
||||
Apply the function *f* to each element in the list *list*. For
|
||||
example,
|
||||
|
||||
map (x: "foo" + x) [ "bar" "bla" "abc" ]
|
||||
```nix
|
||||
map (x: "foo" + x) [ "bar" "bla" "abc" ]
|
||||
```
|
||||
|
||||
evaluates to `[ "foobar" "foobla" "fooabc"
|
||||
]`.
|
||||
evaluates to `[ "foobar" "foobla" "fooabc" ]`.
|
||||
|
||||
- `builtins.match` *regex* *str*
|
||||
Returns a list if the [extended POSIX regular
|
||||
|
@ -466,19 +502,27 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
*regex* matches *str* precisely, otherwise returns `null`. Each item
|
||||
in the list is a regex group.
|
||||
|
||||
builtins.match "ab" "abc"
|
||||
```nix
|
||||
builtins.match "ab" "abc"
|
||||
```
|
||||
|
||||
Evaluates to `null`.
|
||||
|
||||
builtins.match "abc" "abc"
|
||||
```nix
|
||||
builtins.match "abc" "abc"
|
||||
```
|
||||
|
||||
Evaluates to `[ ]`.
|
||||
|
||||
builtins.match "a(b)(c)" "abc"
|
||||
```nix
|
||||
builtins.match "a(b)(c)" "abc"
|
||||
```
|
||||
|
||||
Evaluates to `[ "b" "c" ]`.
|
||||
|
||||
builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO "
|
||||
```nix
|
||||
builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO "
|
||||
```
|
||||
|
||||
Evaluates to `[ "foo" ]`.
|
||||
|
||||
|
@ -534,11 +578,12 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
- `builtins.readDir` *path*
|
||||
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
|
||||
directory `A` contains a regular file `B` and another directory
|
||||
`C`, then `builtins.readDir ./A` will return the set
|
||||
|
||||
{ B = "regular"; C = "directory"; }
|
||||
```nix
|
||||
{ B = "regular"; C = "directory"; }
|
||||
```
|
||||
|
||||
The possible values for the file type are `"regular"`,
|
||||
`"directory"`, `"symlink"` and `"unknown"`.
|
||||
|
@ -550,7 +595,9 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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" ]
|
||||
```nix
|
||||
removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]
|
||||
```
|
||||
|
||||
evaluates to `{ y = 2; }`.
|
||||
|
||||
|
@ -558,7 +605,9 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
Given string *s*, replace every occurrence of the strings in *from*
|
||||
with the corresponding string in *to*. For example,
|
||||
|
||||
builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar"
|
||||
```nix
|
||||
builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar"
|
||||
```
|
||||
|
||||
evaluates to `"fabir"`.
|
||||
|
||||
|
@ -572,10 +621,11 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
if the first element is less than the second, and `false` otherwise.
|
||||
For example,
|
||||
|
||||
builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
|
||||
```nix
|
||||
builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
|
||||
```
|
||||
|
||||
produces the list `[ 42 77 147 249 483 526
|
||||
]`.
|
||||
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.
|
||||
|
@ -587,19 +637,27 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
*regex* matches of *str*. Each item in the lists of matched
|
||||
sequences is a regex group.
|
||||
|
||||
builtins.split "(a)b" "abc"
|
||||
```nix
|
||||
builtins.split "(a)b" "abc"
|
||||
```
|
||||
|
||||
Evaluates to `[ "" [ "a" ] "c" ]`.
|
||||
|
||||
builtins.split "([ac])" "abc"
|
||||
```nix
|
||||
builtins.split "([ac])" "abc"
|
||||
```
|
||||
|
||||
Evaluates to `[ "" [ "a" ] "b" [ "c" ] "" ]`.
|
||||
|
||||
builtins.split "(a)|(c)" "abc"
|
||||
```nix
|
||||
builtins.split "(a)|(c)" "abc"
|
||||
```
|
||||
|
||||
Evaluates to `[ "" [ "a" null ] "b" [ null "c" ] "" ]`.
|
||||
|
||||
builtins.split "([[:upper:]]+)" " FOO "
|
||||
```nix
|
||||
builtins.split "([[:upper:]]+)" " FOO "
|
||||
```
|
||||
|
||||
Evaluates to `[ " " [ "FOO" ] " " ]`.
|
||||
|
||||
|
@ -623,7 +681,9 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
substring up to the end of the string is returned. *start* must be
|
||||
non-negative. For example,
|
||||
|
||||
builtins.substring 0 3 "nixos"
|
||||
```nix
|
||||
builtins.substring 0 3 "nixos"
|
||||
```
|
||||
|
||||
evaluates to `"nix"`.
|
||||
|
||||
|
@ -645,45 +705,47 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
“inline”. For instance, the following Nix expression combines the
|
||||
[Nix expression for GNU Hello](expression-syntax.md) and its
|
||||
[build script](build-script.md) 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;
|
||||
}
|
||||
|
||||
```nix
|
||||
{ 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
|
||||
```nix
|
||||
builder = let
|
||||
configFile = builtins.toFile "foo.conf" "
|
||||
# This is some dummy configuration file.
|
||||
...
|
||||
cp ${configFile} $out/etc/foo.conf
|
||||
";
|
||||
```
|
||||
in builtins.toFile "builder.sh" "
|
||||
source $stdenv/setup
|
||||
...
|
||||
cp ${configFile} $out/etc/foo.conf
|
||||
";
|
||||
```
|
||||
|
||||
Note that `${configFile}` is an
|
||||
[antiquotation](language-values.md), so the result of the
|
||||
|
@ -694,10 +756,12 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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
|
||||
```nix
|
||||
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`.
|
||||
|
@ -744,40 +808,42 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
|
||||
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"; }
|
||||
];
|
||||
})
|
||||
```nix
|
||||
{ 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](http://jetty.mortbay.org/). A servlet
|
||||
|
@ -796,27 +862,29 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
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>
|
||||
```xml
|
||||
<?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
|
||||
|
@ -830,13 +898,13 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
|
||||
- `builtins.tryEval` *e*
|
||||
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. 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
|
||||
attributes `success` (`true` if *e* evaluated successfully,
|
||||
`false` if an error was thrown) and `value`, equalling *e* if
|
||||
successful and `false` otherwise. 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`.
|
||||
|
||||
- `builtins.typeOf` *e*
|
||||
|
|
|
@ -57,23 +57,34 @@ the attributes of which specify the inputs of the build.
|
|||
and it doesn’t need the documentation at build time. Thus, the
|
||||
library package could specify:
|
||||
|
||||
outputs = [ "lib" "headers" "doc" ];
|
||||
```nix
|
||||
outputs = [ "lib" "headers" "doc" ];
|
||||
```
|
||||
|
||||
This will cause Nix to pass environment variables `lib`, `headers`
|
||||
and `doc` to the builder containing the intended store paths of each
|
||||
output. The builder would typically do something like
|
||||
|
||||
./configure --libdir=$lib/lib --includedir=$headers/include --docdir=$doc/share/doc
|
||||
```bash
|
||||
./configure \
|
||||
--libdir=$lib/lib \
|
||||
--includedir=$headers/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.
|
||||
|
||||
buildInputs = [ pkg.lib pkg.headers ];
|
||||
```nix
|
||||
buildInputs = [ pkg.lib pkg.headers ];
|
||||
```
|
||||
|
||||
The first element of `outputs` determines the *default output*.
|
||||
Thus, you could also write
|
||||
|
||||
buildInputs = [ pkg pkg.headers ];
|
||||
```nix
|
||||
buildInputs = [ pkg pkg.headers ];
|
||||
```
|
||||
|
||||
since `pkg` is equivalent to `pkg.lib`.
|
||||
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
Here is a Nix expression for GNU Hello:
|
||||
|
||||
{ stdenv, fetchurl, perl }: ①
|
||||
|
||||
stdenv.mkDerivation { ②
|
||||
name = "hello-2.1.1"; ③
|
||||
builder = ./builder.sh; ④
|
||||
src = fetchurl { ⑤
|
||||
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
};
|
||||
inherit perl; ⑥
|
||||
}
|
||||
```nix
|
||||
{ stdenv, fetchurl, perl }: ①
|
||||
|
||||
stdenv.mkDerivation { ②
|
||||
name = "hello-2.1.1"; ③
|
||||
builder = ./builder.sh; ④
|
||||
src = fetchurl { ⑤
|
||||
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
};
|
||||
inherit perl; ⑥
|
||||
}
|
||||
```
|
||||
|
||||
This file is actually already in the Nix Packages collection in
|
||||
`pkgs/applications/misc/hello/ex-1/default.nix`. It is customary to
|
||||
|
@ -31,31 +33,27 @@ elements (referenced from the figure by number):
|
|||
etc. `fetchurl` is a function that downloads files. `perl` is the
|
||||
Perl interpreter.
|
||||
|
||||
Nix functions generally have the form `{ x, y, ...,
|
||||
z }: e` where `x`, `y`, etc. are the names of the expected
|
||||
arguments, and where *e* is the body of the function. So here, the
|
||||
entire remainder of the file is the body of the function; when given
|
||||
the required arguments, the body should describe how to build an
|
||||
instance of the Hello package.
|
||||
Nix functions generally have the form `{ x, y, ..., z }: e` where
|
||||
`x`, `y`, etc. are the names of the expected arguments, and where
|
||||
*e* is the body of the function. So here, the entire remainder of
|
||||
the file is the body of the function; when given the required
|
||||
arguments, the body should describe how to build an instance of
|
||||
the Hello package.
|
||||
|
||||
2. So we have to build a package. Building something from other stuff
|
||||
is called a *derivation* in Nix (as opposed to sources, which are
|
||||
built by humans instead of computers). We perform a derivation by
|
||||
calling `stdenv.mkDerivation`. `mkDerivation` is a function provided
|
||||
by `stdenv` that builds a package from a set of *attributes*. A set
|
||||
is just a list of key/value pairs where each key is a string and
|
||||
each value is an arbitrary Nix expression. They take the general
|
||||
form `{
|
||||
name1 =
|
||||
expr1; ...
|
||||
nameN =
|
||||
exprN; }`.
|
||||
calling `stdenv.mkDerivation`. `mkDerivation` is a function
|
||||
provided by `stdenv` that builds a package from a set of
|
||||
*attributes*. A set is just a list of key/value pairs where each
|
||||
key is a string and each value is an arbitrary Nix
|
||||
expression. They take the general form `{ name1 = expr1; ...
|
||||
nameN = exprN; }`.
|
||||
|
||||
3. The attribute `name` specifies the symbolic name and version of the
|
||||
package. Nix doesn't really care about these things, but they are
|
||||
used by for instance `nix-env
|
||||
-q` to show a “human-readable” name for packages. This attribute is
|
||||
required by `mkDerivation`.
|
||||
3. The attribute `name` specifies the symbolic name and version of
|
||||
the package. Nix doesn't really care about these things, but they
|
||||
are used by for instance `nix-env -q` to show a “human-readable”
|
||||
name for packages. This attribute is required by `mkDerivation`.
|
||||
|
||||
4. The attribute `builder` specifies the builder. This attribute can
|
||||
sometimes be omitted, in which case `mkDerivation` will fill in a
|
||||
|
@ -83,8 +81,10 @@ elements (referenced from the figure by number):
|
|||
`perl` function argument to the builder. All attributes in the set
|
||||
are actually passed as environment variables to the builder, so
|
||||
declaring an attribute
|
||||
|
||||
perl = perl;
|
||||
|
||||
```nix
|
||||
perl = perl;
|
||||
```
|
||||
|
||||
will do the trick: it binds an attribute `perl` to the function
|
||||
argument which also happens to be called `perl`. However, it looks a
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
Recall that the [build script for GNU Hello](build-script.md) looked
|
||||
something like this:
|
||||
|
||||
PATH=$perl/bin:$PATH
|
||||
tar xvfz $src
|
||||
cd hello-*
|
||||
./configure --prefix=$out
|
||||
make
|
||||
make install
|
||||
```bash
|
||||
PATH=$perl/bin:$PATH
|
||||
tar xvfz $src
|
||||
cd hello-*
|
||||
./configure --prefix=$out
|
||||
make
|
||||
make install
|
||||
```
|
||||
|
||||
The builders for almost all Unix packages look like this — set up some
|
||||
environment variables, unpack the sources, configure, build, and
|
||||
|
@ -16,11 +18,13 @@ install. For this reason the standard environment provides some Bash
|
|||
functions that automate the build process. Here is what a builder using
|
||||
the generic build facilities looks like:
|
||||
|
||||
buildInputs="$perl" ①
|
||||
|
||||
source $stdenv/setup ②
|
||||
|
||||
genericBuild ③
|
||||
```bash
|
||||
buildInputs="$perl" ①
|
||||
|
||||
source $stdenv/setup ②
|
||||
|
||||
genericBuild ③
|
||||
```
|
||||
|
||||
Here is what each line means:
|
||||
|
||||
|
@ -45,15 +49,17 @@ Here is what each line means:
|
|||
Discerning readers will note that the `buildInputs` could just as well
|
||||
have been set in the Nix expression, like this:
|
||||
|
||||
```
|
||||
```nix
|
||||
buildInputs = [ perl ];
|
||||
```
|
||||
|
||||
The `perl` attribute can then be removed, and the builder becomes even
|
||||
shorter:
|
||||
|
||||
source $stdenv/setup
|
||||
genericBuild
|
||||
```bash
|
||||
source $stdenv/setup
|
||||
genericBuild
|
||||
```
|
||||
|
||||
In fact, `mkDerivation` provides a default builder that looks exactly
|
||||
like that, so it is actually possible to omit the builder for Hello
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
Recursive sets are just normal sets, but the attributes can refer to
|
||||
each other. For example,
|
||||
|
||||
rec {
|
||||
x = y;
|
||||
y = 123;
|
||||
}.x
|
||||
```nix
|
||||
rec {
|
||||
x = y;
|
||||
y = 123;
|
||||
}.x
|
||||
```
|
||||
|
||||
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
|
||||
|
@ -19,10 +21,12 @@ recursive set, they are.
|
|||
Recursive sets of course introduce the danger of infinite recursion. For
|
||||
example, the expression
|
||||
|
||||
rec {
|
||||
x = y;
|
||||
y = x;
|
||||
}.x
|
||||
```nix
|
||||
rec {
|
||||
x = y;
|
||||
y = x;
|
||||
}.x
|
||||
```
|
||||
|
||||
will crash with an `infinite recursion encountered` error message.
|
||||
|
||||
|
@ -31,10 +35,12 @@ will crash with an `infinite recursion encountered` error message.
|
|||
A let-expression allows you to define local variables for an expression.
|
||||
For instance,
|
||||
|
||||
let
|
||||
x = "foo";
|
||||
y = "bar";
|
||||
in x + y
|
||||
```nix
|
||||
let
|
||||
x = "foo";
|
||||
y = "bar";
|
||||
in x + y
|
||||
```
|
||||
|
||||
evaluates to `"foobar"`.
|
||||
|
||||
|
@ -45,38 +51,42 @@ copy variables from the surrounding lexical scope (e.g., when you want
|
|||
to propagate attributes). This can be shortened using the `inherit`
|
||||
keyword. For instance,
|
||||
|
||||
let x = 123; in
|
||||
{ inherit x;
|
||||
y = 456;
|
||||
}
|
||||
```nix
|
||||
let x = 123; in
|
||||
{ inherit x;
|
||||
y = 456;
|
||||
}
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
let x = 123; in
|
||||
{ x = x;
|
||||
y = 456;
|
||||
}
|
||||
```nix
|
||||
let x = 123; in
|
||||
{ x = x;
|
||||
y = 456;
|
||||
}
|
||||
```
|
||||
|
||||
and both evaluate to `{ x = 123; y = 456; }`. (Note that this works
|
||||
because `x` is added to the lexical scope by the `let` construct.) It is
|
||||
also possible to inherit attributes from another set. For instance, in
|
||||
this fragment from `all-packages.nix`,
|
||||
|
||||
```
|
||||
graphviz = (import ../tools/graphics/graphviz) {
|
||||
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
|
||||
inherit (xlibs) libXaw;
|
||||
};
|
||||
```nix
|
||||
graphviz = (import ../tools/graphics/graphviz) {
|
||||
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
|
||||
inherit (xlibs) libXaw;
|
||||
};
|
||||
|
||||
xlibs = {
|
||||
libX11 = ...;
|
||||
libXaw = ...;
|
||||
...
|
||||
}
|
||||
|
||||
libpng = ...;
|
||||
libjpg = ...;
|
||||
xlibs = {
|
||||
libX11 = ...;
|
||||
libXaw = ...;
|
||||
...
|
||||
}
|
||||
|
||||
libpng = ...;
|
||||
libjpg = ...;
|
||||
...
|
||||
```
|
||||
|
||||
the set used in the function call to the function defined in
|
||||
|
@ -86,17 +96,21 @@ surrounding scope (`fetchurl` ... `yacc`), but also inherits `libXaw`
|
|||
|
||||
Summarizing the fragment
|
||||
|
||||
...
|
||||
inherit x y z;
|
||||
inherit (src-set) a b c;
|
||||
...
|
||||
```nix
|
||||
...
|
||||
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;
|
||||
...
|
||||
```nix
|
||||
...
|
||||
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.
|
||||
|
@ -105,7 +119,9 @@ defining a set.
|
|||
|
||||
Functions have the following form:
|
||||
|
||||
pattern: body
|
||||
```nix
|
||||
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
|
||||
|
@ -114,42 +130,51 @@ 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 ""
|
||||
```nix
|
||||
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" ]
|
||||
```nix
|
||||
map (concat "foo") [ "bar" "bla" "abc" ]
|
||||
```
|
||||
|
||||
evaluates to `[ "foobar" "foobla"
|
||||
"fooabc" ]`.
|
||||
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
|
||||
```nix
|
||||
{ x, y, z }: z + y + x
|
||||
```
|
||||
|
||||
can only be called with a set containing exactly the attributes `x`,
|
||||
`y` and `z`. No other attributes are allowed. If you want to allow
|
||||
additional arguments, you can use an ellipsis (`...`):
|
||||
|
||||
{ x, y, z, ... }: z + y + x
|
||||
```nix
|
||||
{ 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,
|
||||
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
|
||||
```nix
|
||||
{ x, y ? "foo", z ? "bar" }: z + y + x
|
||||
```
|
||||
|
||||
specifies a function that only requires an attribute named `x`, but
|
||||
optionally accepts `y` and `z`.
|
||||
|
@ -157,14 +182,14 @@ three kinds of patterns:
|
|||
- An `@`-pattern provides a means of referring to the whole value
|
||||
being matched:
|
||||
|
||||
```
|
||||
args@{ x, y, z, ... }: z + y + x + args.a
|
||||
```nix
|
||||
args@{ x, y, z, ... }: z + y + x + args.a
|
||||
```
|
||||
|
||||
but can also be written as:
|
||||
|
||||
```
|
||||
{ x, y, z, ... } @ args: z + y + x + args.a
|
||||
```nix
|
||||
{ x, y, z, ... } @ args: z + y + x + args.a
|
||||
```
|
||||
|
||||
Here `args` is bound to the entire argument, which is further
|
||||
|
@ -182,24 +207,30 @@ three kinds of patterns:
|
|||
>
|
||||
> For instance
|
||||
>
|
||||
> let
|
||||
> function = args@{ a ? 23, ... }: args;
|
||||
> in
|
||||
> function {}
|
||||
> ```nix
|
||||
> let
|
||||
> function = args@{ a ? 23, ... }: args;
|
||||
> in
|
||||
> function {}
|
||||
> ````
|
||||
>
|
||||
> will evaluate to an empty attribute set.
|
||||
|
||||
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"; }
|
||||
```nix
|
||||
let concat = { x, y }: x + y;
|
||||
in concat { x = "foo"; y = "bar"; }
|
||||
```
|
||||
|
||||
## Conditionals
|
||||
|
||||
Conditionals look like this:
|
||||
|
||||
if e1 then e2 else e3
|
||||
```nix
|
||||
if e1 then e2 else e3
|
||||
```
|
||||
|
||||
where *e1* is an expression that should evaluate to a Boolean value
|
||||
(`true` or `false`).
|
||||
|
@ -209,7 +240,9 @@ where *e1* is an expression that should evaluate to a Boolean value
|
|||
Assertions are generally used to check that certain requirements on or
|
||||
between features and dependencies hold. They look like this:
|
||||
|
||||
assert e1; e2
|
||||
```nix
|
||||
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
|
||||
|
@ -218,29 +251,31 @@ 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; ④
|
||||
...
|
||||
}
|
||||
```nix
|
||||
{ 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:
|
||||
|
||||
|
@ -273,19 +308,25 @@ The points of interest are:
|
|||
|
||||
A *with-expression*,
|
||||
|
||||
with e1; e2
|
||||
```nix
|
||||
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
|
||||
```nix
|
||||
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); ...
|
||||
```nix
|
||||
with (import ./definitions.nix); ...
|
||||
```
|
||||
|
||||
makes all attributes defined in the file `definitions.nix` available as
|
||||
if they were defined locally in a `let`-expression.
|
||||
|
@ -293,14 +334,17 @@ 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; }; ...
|
||||
```nix
|
||||
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 ...
|
||||
```nix
|
||||
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 `/*
|
||||
... */`.
|
||||
inline/multi-line, enclosed within `/* ... */`.
|
||||
|
|
|
@ -19,24 +19,30 @@ Nix has the following basic data types:
|
|||
into a string (meaning that it must be a string, a path, or a
|
||||
derivation). For instance, rather than writing
|
||||
|
||||
"--with-freetype2-library=" + freetype + "/lib"
|
||||
```nix
|
||||
"--with-freetype2-library=" + freetype + "/lib"
|
||||
```
|
||||
|
||||
(where `freetype` is a derivation), you can instead write the more
|
||||
natural
|
||||
|
||||
"--with-freetype2-library=${freetype}/lib"
|
||||
```nix
|
||||
"--with-freetype2-library=${freetype}/lib"
|
||||
```
|
||||
|
||||
The latter is automatically translated to the former. A more
|
||||
complicated example (from the Nix expression for
|
||||
[Qt](http://www.trolltech.com/products/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"}
|
||||
";
|
||||
```nix
|
||||
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 antiquotations that
|
||||
|
@ -46,11 +52,13 @@ Nix has the following basic data types:
|
|||
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.
|
||||
''
|
||||
```nix
|
||||
''
|
||||
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
|
||||
|
@ -60,7 +68,9 @@ Nix has the following basic data types:
|
|||
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"
|
||||
```nix
|
||||
"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.
|
||||
|
@ -82,17 +92,19 @@ Nix has the following basic data types:
|
|||
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 ""}
|
||||
'';
|
||||
...
|
||||
}
|
||||
```nix
|
||||
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](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
|
||||
|
@ -136,13 +148,17 @@ Nix has the following basic data types:
|
|||
Lists are formed by enclosing a whitespace-separated list of values
|
||||
between square brackets. For example,
|
||||
|
||||
[ 123 ./foo.nix "abc" (f { x = y; }) ]
|
||||
```nix
|
||||
[ 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; } ]
|
||||
```nix
|
||||
[ 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.
|
||||
|
@ -159,10 +175,12 @@ Sets are just a list of name/value pairs (called *attributes*) enclosed
|
|||
in curly brackets, where each value is an arbitrary expression
|
||||
terminated by a semicolon. For example:
|
||||
|
||||
{ x = 123;
|
||||
text = "Hello";
|
||||
y = f { bla = 456; };
|
||||
}
|
||||
```nix
|
||||
{ x = 123;
|
||||
text = "Hello";
|
||||
y = f { bla = 456; };
|
||||
}
|
||||
```
|
||||
|
||||
This defines a set with attributes named `x`, `text`, `y`. The order of
|
||||
the attributes is irrelevant. An attribute name may only occur once.
|
||||
|
@ -170,24 +188,32 @@ the attributes is irrelevant. An attribute name may only occur once.
|
|||
Attributes can be selected from a set using the `.` operator. For
|
||||
instance,
|
||||
|
||||
{ a = "Foo"; b = "Bar"; }.a
|
||||
```nix
|
||||
{ a = "Foo"; b = "Bar"; }.a
|
||||
```
|
||||
|
||||
evaluates to `"Foo"`. It is possible to provide a default value in an
|
||||
attribute selection using the `or` keyword. For example,
|
||||
|
||||
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
||||
```nix
|
||||
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
||||
```
|
||||
|
||||
will evaluate to `"Xyzzy"` because there is no `c` attribute in the set.
|
||||
|
||||
You can use arbitrary double-quoted strings as attribute names:
|
||||
|
||||
{ "foo ${bar}" = 123; "nix-1.0" = 456; }."foo ${bar}"
|
||||
```nix
|
||||
{ "foo ${bar}" = 123; "nix-1.0" = 456; }."foo ${bar}"
|
||||
```
|
||||
|
||||
This will evaluate to `123` (Assuming `bar` is antiquotable). In the
|
||||
case where an attribute name is just a single antiquotation, the quotes
|
||||
can be dropped:
|
||||
|
||||
{ foo = 123; }.${bar} or 456
|
||||
```nix
|
||||
{ foo = 123; }.${bar} or 456
|
||||
```
|
||||
|
||||
This will evaluate to `123` if `bar` evaluates to `"foo"` when coerced
|
||||
to a string and `456` otherwise (again assuming `bar` is antiquotable).
|
||||
|
@ -196,7 +222,9 @@ In the special case where an attribute name inside of a set declaration
|
|||
evaluates to `null` (which is normally an error, as `null` is not
|
||||
antiquotable), that attribute is simply not added to the set:
|
||||
|
||||
{ ${if foo then "bar" else null} = true; }
|
||||
```nix
|
||||
{ ${if foo then "bar" else null} = true; }
|
||||
```
|
||||
|
||||
This will evaluate to `{}` if `foo` evaluates to `false`.
|
||||
|
||||
|
@ -205,9 +233,11 @@ 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
|
||||
```nix
|
||||
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
|
||||
|
|
|
@ -6,18 +6,20 @@ yet. The best way to test the package is by using the command
|
|||
`nix-build`, which builds a Nix expression and creates a symlink named
|
||||
`result` in the current directory:
|
||||
|
||||
$ nix-build -A hello
|
||||
building path `/nix/store/632d2b22514d...-hello-2.1.1'
|
||||
hello-2.1.1/
|
||||
hello-2.1.1/intl/
|
||||
hello-2.1.1/intl/ChangeLog
|
||||
...
|
||||
|
||||
$ ls -l result
|
||||
lrwxrwxrwx ... 2006-09-29 10:43 result -> /nix/store/632d2b22514d...-hello-2.1.1
|
||||
|
||||
$ ./result/bin/hello
|
||||
Hello, world!
|
||||
```console
|
||||
$ nix-build -A hello
|
||||
building path `/nix/store/632d2b22514d...-hello-2.1.1'
|
||||
hello-2.1.1/
|
||||
hello-2.1.1/intl/
|
||||
hello-2.1.1/intl/ChangeLog
|
||||
...
|
||||
|
||||
$ ls -l result
|
||||
lrwxrwxrwx ... 2006-09-29 10:43 result -> /nix/store/632d2b22514d...-hello-2.1.1
|
||||
|
||||
$ ./result/bin/hello
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
The `-A` option selects the `hello` attribute. This is faster than
|
||||
using the symbolic package name specified by the `name` attribute
|
||||
|
@ -50,8 +52,10 @@ simultaneously, and they try to build the same derivation, the first Nix
|
|||
instance that gets there will perform the build, while the others block
|
||||
(or perform other derivations if available) until the build finishes:
|
||||
|
||||
$ nix-build -A hello
|
||||
waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'
|
||||
```console
|
||||
$ nix-build -A hello
|
||||
waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'
|
||||
```
|
||||
|
||||
So it is always safe to run multiple instances of Nix in parallel (which
|
||||
isn’t the case with, say, `make`).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue