mirror of
https://github.com/NixOS/nix
synced 2025-06-25 06:31:14 +02:00
Rename doc/manual{src -> source}
This is needed to avoid this https://github.com/mesonbuild/meson/issues/13774 when we go back to making our subproject directory `src`.
This commit is contained in:
parent
d5c45952ac
commit
eb7d7780b1
221 changed files with 75 additions and 74 deletions
375
doc/manual/source/language/advanced-attributes.md
Normal file
375
doc/manual/source/language/advanced-attributes.md
Normal file
|
@ -0,0 +1,375 @@
|
|||
# Advanced Attributes
|
||||
|
||||
Derivations can declare some infrequently used optional attributes.
|
||||
|
||||
- [`allowedReferences`]{#adv-attr-allowedReferences}\
|
||||
The optional attribute `allowedReferences` specifies a list of legal
|
||||
references (dependencies) of the output of the builder. For example,
|
||||
|
||||
```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
|
||||
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`]{#adv-attr-allowedRequisites}\
|
||||
This attribute is similar to `allowedReferences`, but it specifies
|
||||
the legal requisites of the whole closure, so all the dependencies
|
||||
recursively. For example,
|
||||
|
||||
```nix
|
||||
allowedRequisites = [ foobar ];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have any other
|
||||
runtime dependency than `foobar`, and in addition it enforces that
|
||||
`foobar` itself doesn't introduce any other dependency itself.
|
||||
|
||||
- [`disallowedReferences`]{#adv-attr-disallowedReferences}\
|
||||
The optional attribute `disallowedReferences` specifies a list of
|
||||
illegal references (dependencies) of the output of the builder. For
|
||||
example,
|
||||
|
||||
```nix
|
||||
disallowedReferences = [ foo ];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have a direct
|
||||
runtime dependencies on the derivation `foo`.
|
||||
|
||||
- [`disallowedRequisites`]{#adv-attr-disallowedRequisites}\
|
||||
This attribute is similar to `disallowedReferences`, but it
|
||||
specifies illegal requisites for the whole closure, so all the
|
||||
dependencies recursively. For example,
|
||||
|
||||
```nix
|
||||
disallowedRequisites = [ foobar ];
|
||||
```
|
||||
|
||||
enforces that the output of a derivation cannot have any runtime
|
||||
dependency on `foobar` or any other derivation depending recursively
|
||||
on `foobar`.
|
||||
|
||||
- [`exportReferencesGraph`]{#adv-attr-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:
|
||||
|
||||
```nix
|
||||
derivation {
|
||||
...
|
||||
exportReferencesGraph = [ "libfoo-graph" libfoo ];
|
||||
};
|
||||
```
|
||||
|
||||
the references graph of `libfoo` is placed in the file
|
||||
`libfoo-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 (a `cpio` 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`]{#adv-attr-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 line
|
||||
|
||||
```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.
|
||||
|
||||
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 the
|
||||
> `nix-build`.
|
||||
|
||||
If the [`configurable-impure-env` experimental
|
||||
feature](@docroot@/development/experimental-features.md#xp-feature-configurable-impure-env)
|
||||
is enabled, these environment variables can also be controlled
|
||||
through the
|
||||
[`impure-env`](@docroot@/command-ref/conf-file.md#conf-impure-env)
|
||||
configuration setting.
|
||||
|
||||
- [`outputHash`]{#adv-attr-outputHash}; [`outputHashAlgo`]{#adv-attr-outputHashAlgo}; [`outputHashMode`]{#adv-attr-outputHashMode}\
|
||||
These attributes declare that the derivation is a so-called *fixed-output derivation* (FOD), which means that a cryptographic hash of the output is already known in advance.
|
||||
|
||||
As opposed to regular derivations, the [`builder`] executable of a fixed-output derivation has access to the network.
|
||||
Nix computes a cryptographic hash of its output and compares that to the hash declared with these attributes.
|
||||
If there is a mismatch, the derivation 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,
|
||||
|
||||
```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.,
|
||||
|
||||
```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*
|
||||
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*` and `name` attributes,
|
||||
while all other attributes are ignored for the purpose of computing
|
||||
the output path. (The `name` attribute is included because it is
|
||||
part of the path.)
|
||||
|
||||
As an example, here is the (simplified) Nix expression for
|
||||
`fetchurl`:
|
||||
|
||||
```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 `outputHash` attribute must be a string containing the hash in either hexadecimal or "nix32" encoding, or following the format for integrity metadata as defined by [SRI](https://www.w3.org/TR/SRI/).
|
||||
The "nix32" encoding is an adaptation of base-32 encoding.
|
||||
The [`convertHash`](@docroot@/language/builtins.md#builtins-convertHash) function shows how to convert between different encodings, and the [`nix-hash` command](../command-ref/nix-hash.md) has information about obtaining the hash for some contents, as well as converting to and from encodings.
|
||||
|
||||
The `outputHashAlgo` attribute specifies the hash algorithm used to compute the hash.
|
||||
It can currently be `"sha1"`, `"sha256"`, `"sha512"`, or `null`.
|
||||
`outputHashAlgo` can only be `null` when `outputHash` follows the SRI format.
|
||||
|
||||
The `outputHashMode` attribute determines how the hash is computed.
|
||||
It must be one of the following values:
|
||||
|
||||
- [`"flat"`](@docroot@/store/store-object/content-address.md#method-flat)
|
||||
|
||||
This is the default.
|
||||
|
||||
- [`"recursive"` or `"nar"`](@docroot@/store/store-object/content-address.md#method-nix-archive)
|
||||
|
||||
> **Compatibility**
|
||||
>
|
||||
> `"recursive"` is the traditional way of indicating this,
|
||||
> and is supported since 2005 (virtually the entire history of Nix).
|
||||
> `"nar"` is more clear, and consistent with other parts of Nix (such as the CLI),
|
||||
> however support for it is only added in Nix version 2.21.
|
||||
|
||||
- [`"text"`](@docroot@/store/store-object/content-address.md#method-text)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> The use of this method for derivation outputs is part of the [`dynamic-derivations`][xp-feature-dynamic-derivations] experimental feature.
|
||||
|
||||
- [`"git"`](@docroot@/store/store-object/content-address.md#method-git)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature.
|
||||
|
||||
- [`__contentAddressed`]{#adv-attr-__contentAddressed}
|
||||
|
||||
> **Warning**
|
||||
> This attribute is part of an [experimental feature](@docroot@/development/experimental-features.md).
|
||||
>
|
||||
> To use this attribute, you must enable the
|
||||
> [`ca-derivations`][xp-feature-ca-derivations] experimental feature.
|
||||
> For example, in [nix.conf](../command-ref/conf-file.md) 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`](#adv-attr-outputHashMode)
|
||||
and
|
||||
[`outputHashAlgo`](#adv-attr-outputHashAlgo)
|
||||
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](@docroot@/command-ref/conf-file.md#conf-system-features).
|
||||
|
||||
- [`passAsFile`]{#adv-attr-passAsFile}\
|
||||
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).
|
||||
|
||||
- [`preferLocalBuild`]{#adv-attr-preferLocalBuild}\
|
||||
If this attribute is set to `true` and [distributed building is enabled](@docroot@/command-ref/conf-file.md#conf-builders), then, if possible, the derivation will be built locally instead of being forwarded to a remote machine.
|
||||
This is useful for derivations that are cheapest to build locally.
|
||||
|
||||
- [`allowSubstitutes`]{#adv-attr-allowSubstitutes}\
|
||||
If this attribute is set to `false`, then Nix will always build this derivation (locally or remotely); it will not try to substitute its outputs.
|
||||
This is useful for derivations that are cheaper to build than to substitute.
|
||||
|
||||
This attribute can be ignored by setting [`always-allow-substitutes`](@docroot@/command-ref/conf-file.md#conf-always-allow-substitutes) to `true`.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> If set to `false`, the [`builder`] should be able to run on the system type specified in the [`system` attribute](./derivations.md#attr-system), since the derivation cannot be substituted.
|
||||
|
||||
[`builder`]: ./derivations.md#attr-builder
|
||||
|
||||
- [`__structuredAttrs`]{#adv-attr-structuredAttrs}\
|
||||
If the special attribute `__structuredAttrs` is set to `true`, the other derivation
|
||||
attributes are serialised into a file in JSON format. The environment variable
|
||||
`NIX_ATTRS_JSON_FILE` points to the exact location of that file both in a build
|
||||
and a [`nix-shell`](../command-ref/nix-shell.md). This obviates the need for
|
||||
[`passAsFile`](#adv-attr-passAsFile) 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`](#adv-attr-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 a
|
||||
[`nix-shell`](../command-ref/nix-shell.md). This includes non-nested
|
||||
(associative) arrays. For example, the attribute `hardening.format = true`
|
||||
ends up as the Bash associative array element `${hardening[format]}`.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> If set to `true`, other advanced attributes such as [`allowedReferences`](#adv-attr-allowedReferences), [`allowedReferences`](#adv-attr-allowedReferences), [`allowedRequisites`](#adv-attr-allowedRequisites),
|
||||
[`disallowedReferences`](#adv-attr-disallowedReferences) and [`disallowedRequisites`](#adv-attr-disallowedRequisites), maxSize, and maxClosureSize.
|
||||
will have no effect.
|
||||
|
||||
- [`outputChecks`]{#adv-attr-outputChecks}\
|
||||
When using [structured attributes](#adv-attr-structuredAttrs), the `outputChecks`
|
||||
attribute allows defining checks per-output.
|
||||
|
||||
In addition to
|
||||
[`allowedReferences`](#adv-attr-allowedReferences), [`allowedRequisites`](#adv-attr-allowedRequisites),
|
||||
[`disallowedReferences`](#adv-attr-disallowedReferences) and [`disallowedRequisites`](#adv-attr-disallowedRequisites),
|
||||
the following attributes are available:
|
||||
|
||||
- `maxSize` defines the maximum size of the resulting [store object](@docroot@/store/store-object.md).
|
||||
- `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:
|
||||
|
||||
```nix
|
||||
__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;
|
||||
};
|
||||
```
|
||||
|
||||
- [`unsafeDiscardReferences`]{#adv-attr-unsafeDiscardReferences}\
|
||||
|
||||
When using [structured attributes](#adv-attr-structuredAttrs), the
|
||||
attribute `unsafeDiscardReferences` is an attribute set with a boolean value for each output name.
|
||||
If set to `true`, it disables scanning the output for runtime dependencies.
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
__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.
|
||||
|
||||
- [`requiredSystemFeatures`]{#adv-attr-requiredSystemFeatures}\
|
||||
|
||||
If a derivation has the `requiredSystemFeatures` attribute, then Nix will only build it on a machine that has the corresponding features set in its [`system-features` configuration](@docroot@/command-ref/conf-file.md#conf-system-features).
|
||||
|
||||
For example, setting
|
||||
|
||||
```nix
|
||||
requiredSystemFeatures = [ "kvm" ];
|
||||
```
|
||||
|
||||
ensures that the derivation can only be built on a machine with the `kvm` feature.
|
||||
|
||||
[xp-feature-ca-derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
|
||||
[xp-feature-dynamic-derivations]: @docroot@/development/experimental-features.md#xp-feature-dynamic-derivations
|
||||
[xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing
|
18
doc/manual/source/language/builtins-prefix.md
Normal file
18
doc/manual/source/language/builtins-prefix.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Built-ins
|
||||
|
||||
This section lists the values and functions built into the Nix language evaluator.
|
||||
All built-ins are available through the global [`builtins`](#builtins-builtins) constant.
|
||||
|
||||
Some built-ins are also exposed directly in the global scope:
|
||||
|
||||
<!-- TODO(@rhendric, #10970): this list is incomplete -->
|
||||
|
||||
- [`derivation`](#builtins-derivation)
|
||||
- [`import`](#builtins-import)
|
||||
- [`abort`](#builtins-abort)
|
||||
- [`throw`](#builtins-throw)
|
||||
|
||||
<dl>
|
||||
<dt id="builtins-derivation"><a href="#builtins-derivation"><code>derivation <var>attrs</var></code></a></dt>
|
||||
<dd><p><var>derivation</var> is described in
|
||||
<a href="derivations.md">its own section</a>.</p></dd>
|
1
doc/manual/source/language/builtins-suffix.md
Normal file
1
doc/manual/source/language/builtins-suffix.md
Normal file
|
@ -0,0 +1 @@
|
|||
</dl>
|
1
doc/manual/source/language/constructs.md
Normal file
1
doc/manual/source/language/constructs.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Language Constructs
|
24
doc/manual/source/language/constructs/lookup-path.md
Normal file
24
doc/manual/source/language/constructs/lookup-path.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Lookup path
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *lookup-path* = `<` *identifier* [ `/` *identifier* ]... `>`
|
||||
|
||||
A lookup path is an identifier with an optional path suffix that resolves to a [path value](@docroot@/language/types.md#type-path) if the identifier matches a search path entry in [`builtins.nixPath`](@docroot@/language/builtins.md#builtins-nixPath).
|
||||
The algorithm for lookup path resolution is described in the documentation on [`builtins.findFile`](@docroot@/language/builtins.md#builtins-findFile).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> <nixpkgs>
|
||||
>```
|
||||
>
|
||||
> /nix/var/nix/profiles/per-user/root/channels/nixpkgs
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> <nixpkgs/nixos>
|
||||
>```
|
||||
>
|
||||
> /nix/var/nix/profiles/per-user/root/channels/nixpkgs/nixos
|
315
doc/manual/source/language/derivations.md
Normal file
315
doc/manual/source/language/derivations.md
Normal file
|
@ -0,0 +1,315 @@
|
|||
# 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.
|
||||
|
||||
[store derivation]: @docroot@/glossary.md#gloss-store-derivation
|
||||
|
||||
## Input attributes
|
||||
|
||||
### Required
|
||||
|
||||
- [`name`]{#attr-name} ([String](@docroot@/language/types.md#type-string))
|
||||
|
||||
A symbolic name for the derivation.
|
||||
It is added to the [store path] of the corresponding [store derivation] as well as to its [output paths](@docroot@/glossary.md#gloss-output-path).
|
||||
|
||||
[store path]: @docroot@/store/store-path.md
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> name = "hello";
|
||||
> # ...
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> The store derivation's path will be `/nix/store/<hash>-hello.drv`.
|
||||
> The [output](#attr-outputs) paths will be of the form `/nix/store/<hash>-hello[-<output>]`
|
||||
|
||||
- [`system`]{#attr-system} ([String](@docroot@/language/types.md#type-string))
|
||||
|
||||
The system type on which the [`builder`](#attr-builder) executable is meant to be run.
|
||||
|
||||
A necessary condition for Nix to build derivations locally is that the `system` attribute matches the current [`system` configuration option].
|
||||
It can automatically [build on other platforms](@docroot@/language/derivations.md#attr-builder) by forwarding build requests to other machines.
|
||||
|
||||
[`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Declare a derivation to be built on a specific system type:
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> # ...
|
||||
> system = "x86_64-linux";
|
||||
> # ...
|
||||
> }
|
||||
> ```
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Declare a derivation to be built on the system type that evaluates the expression:
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> # ...
|
||||
> system = builtins.currentSystem;
|
||||
> # ...
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> [`builtins.currentSystem`](@docroot@/language/builtins.md#builtins-currentSystem) has the value of the [`system` configuration option], and defaults to the system type of the current Nix installation.
|
||||
|
||||
- [`builder`]{#attr-builder} ([Path](@docroot@/language/types.md#type-path) | [String](@docroot@/language/types.md#type-string))
|
||||
|
||||
Path to an executable that will perform the build.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Use the file located at `/bin/bash` as the builder executable:
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> # ...
|
||||
> builder = "/bin/bash";
|
||||
> # ...
|
||||
> };
|
||||
> ```
|
||||
|
||||
<!-- -->
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Copy a local file to the Nix store for use as the builder executable:
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> # ...
|
||||
> builder = ./builder.sh;
|
||||
> # ...
|
||||
> };
|
||||
> ```
|
||||
|
||||
<!-- -->
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Use a file from another derivation as the builder executable:
|
||||
>
|
||||
> ```nix
|
||||
> let pkgs = import <nixpkgs> {}; in
|
||||
> derivation {
|
||||
> # ...
|
||||
> builder = "${pkgs.python}/bin/python";
|
||||
> # ...
|
||||
> };
|
||||
> ```
|
||||
|
||||
### Optional
|
||||
|
||||
- [`args`]{#attr-args} ([List](@docroot@/language/types.md#type-list) of [String](@docroot@/language/types.md#type-string))
|
||||
|
||||
Default: `[ ]`
|
||||
|
||||
Command-line arguments to be passed to the [`builder`](#attr-builder) executable.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Pass arguments to Bash to interpret a shell command:
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> # ...
|
||||
> builder = "/bin/bash";
|
||||
> args = [ "-c" "echo hello world > $out" ];
|
||||
> # ...
|
||||
> };
|
||||
> ```
|
||||
|
||||
- [`outputs`]{#attr-outputs} ([List](@docroot@/language/types.md#type-list) of [String](@docroot@/language/types.md#type-string))
|
||||
|
||||
Default: `[ "out" ]`
|
||||
|
||||
Symbolic outputs of the derivation.
|
||||
Each output name is passed to the [`builder`](#attr-builder) executable as an environment variable with its value set to the corresponding [store path].
|
||||
|
||||
By default, a derivation produces a single output called `out`.
|
||||
However, derivations can produce multiple outputs.
|
||||
This allows the associated [store objects](@docroot@/store/store-object.md) and their [closures](@docroot@/glossary.md#gloss-closure) to be copied or garbage-collected separately.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> 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:
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> # ...
|
||||
> outputs = [ "lib" "dev" "doc" ];
|
||||
> # ...
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> This will cause Nix to pass environment variables `lib`, `dev`, and `doc` to the builder containing the intended store paths of each output.
|
||||
> The builder would typically do something like
|
||||
>
|
||||
> ```bash
|
||||
> ./configure \
|
||||
> --libdir=$lib/lib \
|
||||
> --includedir=$dev/include \
|
||||
> --docdir=$doc/share/doc
|
||||
> ```
|
||||
>
|
||||
> for an Autoconf-style package.
|
||||
|
||||
The name of an output is combined with the name of the derivation to create the name part of the output's store path, unless it is `out`, in which case just the name of the derivation is used.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
>
|
||||
> ```nix
|
||||
> derivation {
|
||||
> name = "example";
|
||||
> outputs = [ "lib" "dev" "doc" "out" ];
|
||||
> # ...
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> The store derivation path will be `/nix/store/<hash>-example.drv`.
|
||||
> The output paths will be
|
||||
> - `/nix/store/<hash>-example-lib`
|
||||
> - `/nix/store/<hash>-example-dev`
|
||||
> - `/nix/store/<hash>-example-doc`
|
||||
> - `/nix/store/<hash>-example`
|
||||
|
||||
You can refer to each output of a derivation by selecting it as an attribute.
|
||||
The first element of `outputs` determines the *default output* and ends up at the top-level.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> Select an output by attribute name:
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> myPackage = derivation {
|
||||
> name = "example";
|
||||
> outputs = [ "lib" "dev" "doc" "out" ];
|
||||
> # ...
|
||||
> };
|
||||
> in myPackage.dev
|
||||
> ```
|
||||
>
|
||||
> Since `lib` is the first output, `myPackage` is equivalent to `myPackage.lib`.
|
||||
|
||||
<!-- FIXME: refer to the output attributes when we have one -->
|
||||
|
||||
- See [Advanced Attributes](./advanced-attributes.md) for more, infrequently used, optional attributes.
|
||||
|
||||
<!-- FIXME: This should be moved here -->
|
||||
|
||||
- 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. The environment variable is set to the [store path] of the derivation's default [output](#attr-outputs).
|
||||
|
||||
- Lists of the previous types are also allowed. They are simply
|
||||
concatenated, separated by spaces.
|
||||
|
||||
- `true` is passed as the string `1`, `false` and `null` are
|
||||
passed as an empty string.
|
||||
|
||||
<!-- FIXME: add a section on output attributes -->
|
||||
|
||||
## Builder execution
|
||||
|
||||
The [`builder`](#attr-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, when `HOME` 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 to `true` for the derivation. A detailed explanation of this
|
||||
behavior can be found in the
|
||||
[section about structured attrs](./advanced-attributes.md#adv-attr-structuredAttrs).
|
||||
|
||||
- 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, the `name`
|
||||
attribute and the output name. (The output name is omitted if
|
||||
it’s `out`.)
|
||||
|
||||
- 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` and `setgid`
|
||||
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.
|
51
doc/manual/source/language/identifiers.md
Normal file
51
doc/manual/source/language/identifiers.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Identifiers
|
||||
|
||||
An *identifier* is an [ASCII](https://en.wikipedia.org/wiki/ASCII) character sequence that:
|
||||
- Starts with a letter (`a-z`, `A-Z`) or underscore (`_`)
|
||||
- Can contain any number of:
|
||||
- Letters (`a-z`, `A-Z`)
|
||||
- Digits (`0-9`)
|
||||
- Underscores (`_`)
|
||||
- Apostrophes (`'`)
|
||||
- Hyphens (`-`)
|
||||
- Is not one of the [keywords](#keywords)
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *identifier* ~ `[A-Za-z_][A-Za-z0-9_'-]*`
|
||||
|
||||
# Names
|
||||
|
||||
A *name* can be written as an [identifier](#identifier) or a [string literal](./string-literals.md).
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *name* → *identifier* | *string*
|
||||
|
||||
Names are used in [attribute sets](./syntax.md#attrs-literal), [`let` bindings](./syntax.md#let-expressions), and [`inherit`](./syntax.md#inheriting-attributes).
|
||||
Two names are the same if they represent the same sequence of characters, regardless of whether they are written as identifiers or strings.
|
||||
|
||||
# Keywords
|
||||
|
||||
These keywords are reserved and cannot be used as [identifiers](#identifiers):
|
||||
|
||||
- [`assert`](./syntax.md#assertions)
|
||||
- [`else`][if]
|
||||
- [`if`][if]
|
||||
- [`in`][let]
|
||||
- [`inherit`](./syntax.md#inheriting-attributes)
|
||||
- [`let`][let]
|
||||
- [`or`](./operators.md#attribute-selection) (see note)
|
||||
- [`rec`](./syntax.md#recursive-sets)
|
||||
- [`then`][if]
|
||||
- [`with`](./syntax.md#with-expressions)
|
||||
|
||||
[if]: ./syntax.md#conditionals
|
||||
[let]: ./syntax.md#let-expressions
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The Nix language evaluator currently allows `or` to be used as a name in some contexts, for backwards compatibility reasons.
|
||||
> Users are advised not to rely on this.
|
||||
>
|
||||
> There are long-standing issues with how `or` is parsed as a name, which can't be resolved without making a breaking change to the language.
|
141
doc/manual/source/language/import-from-derivation.md
Normal file
141
doc/manual/source/language/import-from-derivation.md
Normal file
|
@ -0,0 +1,141 @@
|
|||
# Import From Derivation
|
||||
|
||||
The value of a Nix expression can depend on the contents of a [store object].
|
||||
|
||||
[store object]: @docroot@/store/store-object.md
|
||||
|
||||
Passing an expression `expr` that evaluates to a [store path](@docroot@/store/store-path.md) to any built-in function which reads from the filesystem constitutes Import From Derivation (IFD):
|
||||
|
||||
- [`import`](./builtins.md#builtins-import)` expr`
|
||||
- [`builtins.readFile`](./builtins.md#builtins-readFile)` expr`
|
||||
- [`builtins.readFileType`](./builtins.md#builtins-readFileType)` expr`
|
||||
- [`builtins.readDir`](./builtins.md#builtins-readDir)` expr`
|
||||
- [`builtins.pathExists`](./builtins.md#builtins-pathExists)` expr`
|
||||
- [`builtins.filterSource`](./builtins.md#builtins-filterSource)` f expr`
|
||||
- [`builtins.path`](./builtins.md#builtins-path)` { path = expr; }`
|
||||
- [`builtins.hashFile`](./builtins.md#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.
|
||||
|
||||
[realised]: @docroot@/glossary.md#gloss-realise
|
||||
|
||||
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`](../command-ref/conf-file.md#conf-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`.
|
||||
|
||||
```nix
|
||||
# IFD.nix
|
||||
let
|
||||
drv = derivation {
|
||||
name = "hello";
|
||||
builder = "/bin/sh";
|
||||
args = [ "-c" "echo -n hello > $out" ];
|
||||
system = builtins.currentSystem;
|
||||
};
|
||||
in "${builtins.readFile drv} world"
|
||||
```
|
||||
|
||||
```shellSession
|
||||
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`](./builtins.md#builtins-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|
|
||||
'-------' '-------------' '---------'
|
||||
```
|
631
doc/manual/source/language/index.md
Normal file
631
doc/manual/source/language/index.md
Normal file
|
@ -0,0 +1,631 @@
|
|||
# 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.
|
||||
|
||||
> **Tip**
|
||||
>
|
||||
> These pages are written as a reference.
|
||||
> If you are learning Nix, nix.dev has a good [introduction to the Nix language](https://nix.dev/tutorials/nix-language).
|
||||
|
||||
The language is:
|
||||
|
||||
- *domain-specific*
|
||||
|
||||
It comes with [built-in functions](@docroot@/language/builtins.md) 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.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>
|
||||
Example
|
||||
</th>
|
||||
<th>
|
||||
Description
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
|
||||
*Basic values ([primitives](@docroot@/language/types.md#primitives))*
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`"hello world"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [string](@docroot@/language/types.md#type-string)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```
|
||||
''
|
||||
multi
|
||||
line
|
||||
string
|
||||
''
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<!-- FIXME: using two no-break spaces, because apparently mdBook swallows the second regular space! -->
|
||||
A multi-line string. Strips common prefixed whitespace. Evaluates to `"multi\n line\n string"`.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`# Explanation`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [comment](@docroot@/language/syntax.md#comments).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`"hello ${ { a = "world"; }.a }"`
|
||||
|
||||
`"1 2 ${toString 3}"`
|
||||
|
||||
`"${pkgs.bash}/bin/sh"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[String interpolation](@docroot@/language/string-interpolation.md) (expands to `"hello world"`, `"1 2 3"`, `"/nix/store/<hash>-bash-<version>/bin/sh"`)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`true`, `false`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Booleans](@docroot@/language/types.md#type-boolean)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`null`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Null](@docroot@/language/types.md#type-null) value
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`123`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
An [integer](@docroot@/language/types.md#type-int)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`3.141`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [floating point number](@docroot@/language/types.md#type-float)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`/etc`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
An absolute [path](@docroot@/language/types.md#type-path)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`./foo.png`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [path](@docroot@/language/types.md#type-path) relative to the file containing this Nix expression
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`~/.config`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A home [path](@docroot@/language/types.md#type-path). Evaluates to the `"<user's home directory>/.config"`.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`<nixpkgs>`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [lookup path](@docroot@/language/constructs/lookup-path.md) for Nix files. Value determined by [`$NIX_PATH` environment variable](../command-ref/env-common.md#env-NIX_PATH).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
*Compound values*
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x = 1; y = 2; }`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
An [attribute set](@docroot@/language/types.md#attribute-set) with attributes named `x` and `y`
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ foo.bar = 1; }`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A nested set, equivalent to `{ foo = { bar = 1; }; }`
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`rec { x = "foo"; y = x + "bar"; }`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [recursive set](@docroot@/language/syntax.md#recursive-sets), equivalent to `{ x = "foo"; y = "foobar"; }`.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`[ "foo" "bar" "baz" ]`
|
||||
|
||||
`[ 1 2 3 ]`
|
||||
|
||||
`[ (f 1) { a = 1; b = 2; } [ "c" ] ]`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Lists](@docroot@/language/types.md#list) with three elements.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
*Operators*
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`"foo" + "bar"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
String concatenation
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`1 + 2`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Integer addition
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`"foo" == "f" + "oo"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Equality test (evaluates to `true`)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`"foo" != "bar"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Inequality test (evaluates to `true`)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`!true`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Boolean negation
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x = 1; y = 2; }.x`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Attribute selection](@docroot@/language/types.md#attribute-set) (evaluates to `1`)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x = 1; y = 2; }.z or 3`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Attribute selection](@docroot@/language/types.md#attribute-set) with default (evaluates to `3`)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x = 1; y = 2; } // { z = 3; }`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Merge two sets (attributes in the right-hand set taking precedence)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
*Control structures*
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`if 1 + 1 == 2 then "yes!" else "no!"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Conditional expression](@docroot@/language/syntax.md#conditionals).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`assert 1 + 1 == 2; "yes!"`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
[Assertion](@docroot@/language/syntax.md#assertions) check (evaluates to `"yes!"`).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`let x = "foo"; y = "bar"; in x + y`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Variable definition. See [`let`-expressions](@docroot@/language/syntax.md#let-expressions).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`with builtins; head [ 1 2 3 ]`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Add all attributes from the given set to the scope (evaluates to `1`).
|
||||
|
||||
See [`with`-expressions](@docroot@/language/syntax.md#with-expressions) for details and shadowing caveats.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`inherit pkgs src;`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Adds the variables to the current scope (attribute set or `let` binding).
|
||||
Desugars to `pkgs = pkgs; src = src;`.
|
||||
See [Inheriting attributes](@docroot@/language/syntax.md#inheriting-attributes).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`inherit (pkgs) lib stdenv;`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Adds the attributes, from the attribute set in parentheses, to the current scope (attribute set or `let` binding).
|
||||
Desugars to `lib = pkgs.lib; stdenv = pkgs.stdenv;`.
|
||||
See [Inheriting attributes](@docroot@/language/syntax.md#inheriting-attributes).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
*[Functions](@docroot@/language/syntax.md#functions) (lambdas)*
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`x: x + 1`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) that expects an integer and returns it increased by 1.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`x: y: x + y`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Curried [function](@docroot@/language/syntax.md#functions), equivalent to `x: (y: x + y)`. Can be used like a function that takes two arguments and returns their sum.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`(x: x + 1) 100`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) call (evaluates to 101)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`let inc = x: x + 1; in inc (inc (inc 100))`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) bound to a variable and subsequently called by name (evaluates to 103)
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x, y }: x + y`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) that expects a set with required attributes `x` and `y` and concatenates them
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x, y ? "bar" }: x + y`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y`
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x, y, ... }: x + y`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) that expects a set with required attributes `x` and `y` and ignores any other attributes
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`{ x, y } @ args: x + y`
|
||||
|
||||
`args @ { x, y }: x + y`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A [function](@docroot@/language/syntax.md#functions) that expects a set with required attributes `x` and `y`, and binds the whole set to `args`
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
*Built-in functions*
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`import ./foo.nix`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Load and return Nix expression in given file.
|
||||
See [import](@docroot@/language/builtins.md#builtins-import).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`map (x: x + x) [ 1 2 3 ]`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`).
|
||||
See [`map`](@docroot@/language/builtins.md#builtins-map).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
20
doc/manual/source/language/meson.build
Normal file
20
doc/manual/source/language/meson.build
Normal file
|
@ -0,0 +1,20 @@
|
|||
builtins_md = custom_target(
|
||||
command : [
|
||||
python.full_path(),
|
||||
'@INPUT0@',
|
||||
'@OUTPUT@',
|
||||
'--'
|
||||
] + nix_eval_for_docs + [
|
||||
'--expr',
|
||||
'(builtins.readFile @INPUT3@) + import @INPUT1@ (builtins.fromJSON (builtins.readFile ./@INPUT2@)) + (builtins.readFile @INPUT4@)',
|
||||
],
|
||||
input : [
|
||||
'../../remove_before_wrapper.py',
|
||||
'../../generate-builtins.nix',
|
||||
language_json,
|
||||
'builtins-prefix.md',
|
||||
'builtins-suffix.md'
|
||||
],
|
||||
output : 'builtins.md',
|
||||
env : nix_env_for_docs,
|
||||
)
|
235
doc/manual/source/language/operators.md
Normal file
235
doc/manual/source/language/operators.md
Normal file
|
@ -0,0 +1,235 @@
|
|||
# Operators
|
||||
|
||||
| Name | Syntax | Associativity | Precedence |
|
||||
|----------------------------------------|--------------------------------------------|---------------|------------|
|
||||
| [Attribute selection] | *attrset* `.` *attrpath* \[ `or` *expr* \] | none | 1 |
|
||||
| [Function application] | *func* *expr* | left | 2 |
|
||||
| [Arithmetic negation][arithmetic] | `-` *number* | none | 3 |
|
||||
| [Has attribute] | *attrset* `?` *attrpath* | none | 4 |
|
||||
| List concatenation | *list* `++` *list* | right | 5 |
|
||||
| [Multiplication][arithmetic] | *number* `*` *number* | left | 6 |
|
||||
| [Division][arithmetic] | *number* `/` *number* | left | 6 |
|
||||
| [Subtraction][arithmetic] | *number* `-` *number* | left | 7 |
|
||||
| [Addition][arithmetic] | *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][Comparison] | *expr* `<` *expr* | none | 10 |
|
||||
| [Less than or equal to][Comparison] | *expr* `<=` *expr* | none | 10 |
|
||||
| [Greater than][Comparison] | *expr* `>` *expr* | none | 10 |
|
||||
| [Greater than or equal to][Comparison] | *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* <code>\|\|</code> *bool* | left | 13 |
|
||||
| [Logical implication] | *bool* `->` *bool* | right | 14 |
|
||||
| [Pipe operator] (experimental) | *expr* `\|>` *func* | left | 15 |
|
||||
| [Pipe operator] (experimental) | *func* `<\|` *expr* | right | 15 |
|
||||
|
||||
[string]: ./types.md#type-string
|
||||
[path]: ./types.md#type-path
|
||||
[number]: ./types.md#type-float
|
||||
[list]: ./types.md#type-list
|
||||
[attribute set]: ./types.md#type-attrs
|
||||
|
||||
<!-- TODO(@rhendric, #10970): ^ rationalize number -> int/float -->
|
||||
|
||||
## 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.
|
||||
|
||||
[Attribute selection]: #attribute-selection
|
||||
|
||||
## Function application
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *func* *expr*
|
||||
|
||||
Apply the callable value *func* to the argument *expr*. Note the absence of any visible operator symbol.
|
||||
A callable value is either:
|
||||
- a [user-defined function][function]
|
||||
- a [built-in][builtins] function
|
||||
- an attribute set with a [`__functor` attribute](./syntax.md#attr-__functor)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> [List][list] items are also separated by whitespace, which means that function calls in list items must be enclosed by parentheses.
|
||||
|
||||
## Has attribute
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *attrset* `?` *attrpath*
|
||||
|
||||
Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*.
|
||||
The result is a [Boolean] value.
|
||||
|
||||
See also: [`builtins.hasAttr`](@docroot@/language/builtins.md#builtins-hasAttr)
|
||||
|
||||
[Boolean]: ./types.md#type-bool
|
||||
|
||||
[Has attribute]: #has-attribute
|
||||
|
||||
After evaluating *attrset* and *attrpath*, the computational complexity is O(log(*n*)) for *n* attributes in the *attrset*
|
||||
|
||||
## Arithmetic
|
||||
|
||||
Numbers will retain their type unless mixed with other numeric types:
|
||||
Pure integer operations will always return integers, whereas any operation involving at least one floating point number returns a floating point number.
|
||||
|
||||
Evaluation of the following numeric operations throws an evaluation error:
|
||||
- Division by zero
|
||||
- Integer overflow, that is, any operation yielding a result outside of the representable range of [Nix language integers](./syntax.md#number-literal)
|
||||
|
||||
See also [Comparison] and [Equality].
|
||||
|
||||
The `+` operator is overloaded to also work on strings and paths.
|
||||
|
||||
[arithmetic]: #arithmetic
|
||||
|
||||
## String concatenation
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *string* `+` *string*
|
||||
|
||||
Concatenate two [strings][string] and merge their string contexts.
|
||||
|
||||
[String concatenation]: #string-concatenation
|
||||
|
||||
## Path concatenation
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *path* `+` *path*
|
||||
|
||||
Concatenate two [paths][path].
|
||||
The result is a path.
|
||||
|
||||
[Path concatenation]: #path-concatenation
|
||||
|
||||
## 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].
|
||||
|
||||
[Path and string concatenation]: #path-and-string-concatenation
|
||||
|
||||
## 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].
|
||||
|
||||
[store path]: @docroot@/store/store-path.md
|
||||
[store]: @docroot@/glossary.md#gloss-store
|
||||
|
||||
[String and path concatenation]: #string-and-path-concatenation
|
||||
|
||||
## Update
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *attrset1* // *attrset2*
|
||||
|
||||
Update [attribute set] *attrset1* with names and values from *attrset2*.
|
||||
|
||||
The returned attribute set will have all of the attributes in *attrset1* and *attrset2*.
|
||||
If an attribute name is present in both, the attribute value from the latter is taken.
|
||||
|
||||
[Update]: #update
|
||||
|
||||
## Comparison
|
||||
|
||||
Comparison is
|
||||
|
||||
- [arithmetic] for [numbers][number]
|
||||
- lexicographic for [strings][string] and [paths][path]
|
||||
- item-wise lexicographic for [lists][list]:
|
||||
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* `)` |
|
||||
|
||||
[Comparison]: #comparison
|
||||
|
||||
## Equality
|
||||
|
||||
- [Attribute sets][attribute set] and [lists][list] are compared recursively, and therefore are fully evaluated.
|
||||
- Comparison of [functions][function] always returns `false`.
|
||||
- Numbers are type-compatible, see [arithmetic] operators.
|
||||
- Floating point numbers only differ up to a limited precision.
|
||||
|
||||
[function]: ./syntax.md#functions
|
||||
|
||||
[Equality]: #equality
|
||||
|
||||
## Logical implication
|
||||
|
||||
Equivalent to `!`*b1* `||` *b2*.
|
||||
|
||||
[Logical implication]: #logical-implication
|
||||
|
||||
## Pipe operators
|
||||
|
||||
- *a* `|>` *b* is equivalent to *b* *a*
|
||||
- *a* `<|` *b* is equivalent to *a* *b*
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```
|
||||
> nix-repl> 1 |> builtins.add 2 |> builtins.mul 3
|
||||
> 9
|
||||
>
|
||||
> nix-repl> builtins.add 1 <| builtins.mul 2 <| 3
|
||||
> 7
|
||||
> ```
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> This syntax is part of an
|
||||
> [experimental feature](@docroot@/development/experimental-features.md)
|
||||
> and may change in future releases.
|
||||
>
|
||||
> To use this syntax, make sure the
|
||||
> [`pipe-operators` experimental feature](@docroot@/development/experimental-features.md#xp-feature-pipe-operators)
|
||||
> is enabled.
|
||||
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = pipe-operators
|
||||
> ```
|
||||
|
||||
[Pipe operator]: #pipe-operators
|
||||
[builtins]: ./builtins.md
|
||||
[Function application]: #function-application
|
28
doc/manual/source/language/scope.md
Normal file
28
doc/manual/source/language/scope.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Scoping rules
|
||||
|
||||
A *scope* in the Nix language is a dictionary keyed by [name](./identifiers.md#names), mapping each name to an expression and a *definition type*.
|
||||
The definition type is either *explicit* or *implicit*.
|
||||
Each entry in this dictionary is a *definition*.
|
||||
|
||||
Explicit definitions are created by the following expressions:
|
||||
- [let-expressions](syntax.md#let-expressions)
|
||||
- [recursive attribute set literals](syntax.md#recursive-sets) (`rec`)
|
||||
- [function literals](syntax.md#functions)
|
||||
|
||||
Implicit definitions are only created by [with-expressions](./syntax.md#with-expressions).
|
||||
|
||||
Every expression is *enclosed* by a scope.
|
||||
The outermost expression is enclosed by the [built-in, global scope](./builtins.md), which contains only explicit definitions.
|
||||
The expressions listed above *extend* their enclosing scope by adding new definitions, or replacing existing ones with the same name.
|
||||
An explicit definition can replace a definition of any type; an implicit definition can only replace another implicit definition.
|
||||
|
||||
Each of the above expressions defines which of its subexpressions are enclosed by the extended scope.
|
||||
In all other cases, the same scope that encloses an expression is the enclosing scope for its subexpressions.
|
||||
|
||||
The Nix language is [statically scoped](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope);
|
||||
the value of a variable is determined only by the variable's enclosing scope, and not by the dynamic context in which the variable is evaluated.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Expressions entered into the [Nix REPL](@docroot@/command-ref/new-cli/nix3-repl.md) are enclosed by a scope that can be extended by command line arguments or previous REPL commands.
|
||||
> These ways of extending scope are not, strictly speaking, part of the Nix language.
|
134
doc/manual/source/language/string-context.md
Normal file
134
doc/manual/source/language/string-context.md
Normal file
|
@ -0,0 +1,134 @@
|
|||
# String context
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> This is an advanced topic.
|
||||
> The Nix language is designed to be used without the programmer consciously dealing with string contexts or even knowing what they are.
|
||||
|
||||
A string in the Nix language is not just a sequence of characters like strings in other languages.
|
||||
It is actually a pair of a sequence of characters and a *string context*.
|
||||
The string context is an (unordered) set of *string context elements*.
|
||||
|
||||
The purpose of string contexts is to collect non-string values attached to strings via
|
||||
[string concatenation](./operators.md#string-concatenation),
|
||||
[string interpolation](./string-interpolation.md),
|
||||
and similar operations.
|
||||
The idea is that a user can combine together values to create a build instructions for derivations without manually keeping track of where they come from.
|
||||
Then the Nix language implicitly does that bookkeeping to efficiently obtain the closure of derivation inputs.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> String contexts are *not* explicitly manipulated in idiomatic Nix language code.
|
||||
|
||||
String context elements come in different forms:
|
||||
|
||||
- [deriving path]{#string-context-element-derived-path}
|
||||
|
||||
A string context element of this type is a [deriving path](@docroot@/glossary.md#gloss-deriving-path).
|
||||
They can be either of type [constant](#string-context-constant) or [output](#string-context-output), which correspond to the types of deriving paths.
|
||||
|
||||
- [Constant string context elements]{#string-context-constant}
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> [`builtins.storePath`] creates a string with a single constant string context element:
|
||||
>
|
||||
> ```nix
|
||||
> builtins.getContext (builtins.storePath "/nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10")
|
||||
> ```
|
||||
> evaluates to
|
||||
> ```nix
|
||||
> {
|
||||
> "/nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10" = {
|
||||
> path = true;
|
||||
> };
|
||||
> }
|
||||
> ```
|
||||
|
||||
[deriving path]: @docroot@/glossary.md#gloss-deriving-path
|
||||
[store path]: @docroot@/glossary.md#gloss-store-path
|
||||
[`builtins.storePath`]: ./builtins.md#builtins-storePath
|
||||
|
||||
- [Output string context elements]{#string-context-output}
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> The behavior of string contexts are best demonstrated with a built-in function that is still experimental: [`builtins.outputOf`].
|
||||
> This example will *not* work with stable Nix!
|
||||
>
|
||||
> ```nix
|
||||
> builtins.getContext
|
||||
> (builtins.outputOf
|
||||
> (builtins.storePath "/nix/store/fvchh9cvcr7kdla6n860hshchsba305w-hello-2.12.drv")
|
||||
> "out")
|
||||
> ```
|
||||
> evaluates to
|
||||
> ```nix
|
||||
> {
|
||||
> "/nix/store/fvchh9cvcr7kdla6n860hshchsba305w-hello-2.12.drv" = {
|
||||
> outputs = [ "out" ];
|
||||
> };
|
||||
> }
|
||||
> ```
|
||||
|
||||
[`builtins.outputOf`]: ./builtins.md#builtins-outputOf
|
||||
|
||||
- [*derivation deep*]{#string-context-element-derivation-deep}
|
||||
|
||||
*derivation deep* is an advanced feature intended to be used with the
|
||||
[`exportReferencesGraph` derivation attribute](./advanced-attributes.html#adv-attr-exportReferencesGraph).
|
||||
A *derivation deep* string context element is a derivation path, and refers to both its outputs and the entire build closure of that derivation:
|
||||
all its outputs, all the other derivations the given derivation depends on, and all the outputs of those.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> The best way to illustrate *derivation deep* string contexts is with [`builtins.addDrvOutputDependencies`].
|
||||
> Take a regular constant string context element pointing to a derivation, and transform it into a "Derivation deep" string context element.
|
||||
>
|
||||
> ```nix
|
||||
> builtins.getContext
|
||||
> (builtins.addDrvOutputDependencies
|
||||
> (builtins.storePath "/nix/store/fvchh9cvcr7kdla6n860hshchsba305w-hello-2.12.drv"))
|
||||
> ```
|
||||
> evaluates to
|
||||
> ```nix
|
||||
> {
|
||||
> "/nix/store/fvchh9cvcr7kdla6n860hshchsba305w-hello-2.12.drv" = {
|
||||
> allOutputs = true;
|
||||
> };
|
||||
> }
|
||||
> ```
|
||||
|
||||
[`builtins.addDrvOutputDependencies`]: ./builtins.md#builtins-addDrvOutputDependencies
|
||||
[`builtins.unsafeDiscardOutputDependency`]: ./builtins.md#builtins-unsafeDiscardOutputDependency
|
||||
|
||||
## Inspecting string contexts
|
||||
|
||||
Most basically, [`builtins.hasContext`] will tell whether a string has a non-empty context.
|
||||
|
||||
When more granular information is needed, [`builtins.getContext`] can be used.
|
||||
It creates an [attribute set] representing the string context, which can be inspected as usual.
|
||||
|
||||
[`builtins.hasContext`]: ./builtins.md#builtins-hasContext
|
||||
[`builtins.getContext`]: ./builtins.md#builtins-getContext
|
||||
[attribute set]: ./types.md#attribute-set
|
||||
|
||||
## Clearing string contexts
|
||||
|
||||
[`buitins.unsafeDiscardStringContext`](./builtins.md#builtins-unsafeDiscardStringContext) will make a copy of a string, but with an empty string context.
|
||||
The returned string can be used in more ways, e.g. by operators that require the string context to be empty.
|
||||
The requirement to explicitly discard the string context in such use cases helps ensure that string context elements are not lost by mistake.
|
||||
The "unsafe" marker is only there to remind that Nix normally guarantees that dependencies are tracked, whereas the returned string has lost them.
|
||||
|
||||
## Constructing string contexts
|
||||
|
||||
[`builtins.appendContext`] will create a copy of a string, but with additional string context elements.
|
||||
The context is specified explicitly by an [attribute set] in the format that [`builtins.hasContext`] produces.
|
||||
A string with arbitrary contexts can be made like this:
|
||||
|
||||
1. Create a string with the desired string context elements.
|
||||
(The contents of the string do not matter.)
|
||||
2. Dump its context with [`builtins.getContext`].
|
||||
3. Combine it with a base string and repeated [`builtins.appendContext`] calls.
|
||||
|
||||
[`builtins.appendContext`]: ./builtins.md#builtins-appendContext
|
245
doc/manual/source/language/string-interpolation.md
Normal file
245
doc/manual/source/language/string-interpolation.md
Normal file
|
@ -0,0 +1,245 @@
|
|||
# String interpolation
|
||||
|
||||
String interpolation is a language feature where a [string], [path], or [attribute name][attribute set] 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](#interpolated-expression).
|
||||
|
||||
[string]: ./types.md#type-string
|
||||
[path]: ./types.md#type-path
|
||||
[attribute set]: ./types.md#attribute-set
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *interpolation_element* → `${` *expression* `}`
|
||||
|
||||
## Examples
|
||||
|
||||
### String
|
||||
|
||||
Rather than writing
|
||||
|
||||
```nix
|
||||
"--with-freetype2-library=" + freetype + "/lib"
|
||||
```
|
||||
|
||||
(where `freetype` is a [derivation]), you can instead write
|
||||
|
||||
[derivation]: @docroot@/glossary.md#gloss-derivation
|
||||
|
||||
```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)):
|
||||
|
||||
```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 interpolated expressions that themselves contain strings (e.g., `"-thread"`), some of which in turn contain interpolated expressions (e.g., `${mesa}`).
|
||||
|
||||
To write a literal `${` in an regular string, escape it with a backslash (`\`).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> "echo \${PATH}"
|
||||
> ```
|
||||
>
|
||||
> "echo ${PATH}"
|
||||
|
||||
To write a literal `${` in an indented string, escape it with two single quotes (`''`).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> ''
|
||||
> echo ''${PATH}
|
||||
> ''
|
||||
> ```
|
||||
>
|
||||
> "echo ${PATH}\n"
|
||||
|
||||
`$${` can be written literally in any string.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> In Make, `$` in file names or recipes is represented as `$$`, see [GNU `make`: Basics of Variable Reference](https://www.gnu.org/software/make/manual/html_node/Reference.html#Basics-of-Variable-References).
|
||||
> This can be expressed directly in the Nix language strings:
|
||||
>
|
||||
> ```nix
|
||||
> ''
|
||||
> MAKEVAR = Hello
|
||||
> all:
|
||||
> @export BASHVAR=world; echo $(MAKEVAR) $${BASHVAR}
|
||||
> ''
|
||||
> ```
|
||||
>
|
||||
> "MAKEVAR = Hello\nall:\n\t@export BASHVAR=world; echo $(MAKEVAR) $\${BASHVAR}\n"
|
||||
|
||||
See the [documentation on strings][string] for details.
|
||||
|
||||
### Path
|
||||
|
||||
Rather than writing
|
||||
|
||||
```nix
|
||||
./. + "/" + foo + "-" + bar + ".nix"
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```nix
|
||||
./. + "/${foo}-${bar}.nix"
|
||||
```
|
||||
|
||||
you can instead write
|
||||
|
||||
```nix
|
||||
./${foo}-${bar}.nix
|
||||
```
|
||||
|
||||
### Attribute name
|
||||
|
||||
<!--
|
||||
FIXME: these examples are redundant with the main page on attribute sets.
|
||||
figure out what to do about that
|
||||
-->
|
||||
|
||||
Attribute names can be interpolated strings.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> let name = "foo"; in
|
||||
> { ${name} = 123; }
|
||||
> ```
|
||||
>
|
||||
> { foo = 123; }
|
||||
|
||||
Attributes can be selected with interpolated strings.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> 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 an `outPath` attribute
|
||||
|
||||
- `__toString` must be a function that takes the attribute set itself and returns a string
|
||||
- `outPath` must be a string
|
||||
|
||||
This includes [derivations](./derivations.md) or [flake inputs](@docroot@/command-ref/new-cli/nix3-flake.md#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](@docroot@/store/store-object.md).
|
||||
|
||||
[store path]: @docroot@/store/store-path.md
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```console
|
||||
> $ mkdir foo
|
||||
> ```
|
||||
>
|
||||
> Reference the empty directory in an interpolated expression:
|
||||
>
|
||||
> ```nix
|
||||
> "${./foo}"
|
||||
> ```
|
||||
>
|
||||
> "/nix/store/2hhl2nz5v0khbn06ys82nrk99aa1xxdw-foo"
|
||||
|
||||
A derivation interpolates to the [store path] of its first [output](./derivations.md#attr-outputs).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> 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**
|
||||
>
|
||||
> ```nix
|
||||
> 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**
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> a = { outPath = "foo"; };
|
||||
> in
|
||||
> "${a}"
|
||||
> ```
|
||||
>
|
||||
> "foo"
|
||||
|
||||
If both `__toString` and `outPath` are present in an attribute set, `__toString` takes precedence.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> a = { __toString = _: "yes"; outPath = throw "no"; };
|
||||
> in
|
||||
> "${a}"
|
||||
> ```
|
||||
>
|
||||
> "yes"
|
||||
|
||||
If neither is present, an error is thrown.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> a = {};
|
||||
> in
|
||||
> "${a}"
|
||||
> ```
|
||||
>
|
||||
> error: cannot coerce a set to a string: { }
|
||||
>
|
||||
> at «string»:4:2:
|
||||
>
|
||||
> 3| in
|
||||
> 4| "${a}"
|
||||
> | ^
|
190
doc/manual/source/language/string-literals.md
Normal file
190
doc/manual/source/language/string-literals.md
Normal file
|
@ -0,0 +1,190 @@
|
|||
# String literals
|
||||
|
||||
A *string literal* represents a [string](types.md#type-string) value.
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *expression* → *string*
|
||||
>
|
||||
> *string* → `"` ( *string_char*\* [*interpolation_element*][string interpolation] )* *string_char*\* `"`
|
||||
>
|
||||
> *string* → `''` ( *indented_string_char*\* [*interpolation_element*][string interpolation] )* *indented_string_char*\* `''`
|
||||
>
|
||||
> *string* → *uri*
|
||||
>
|
||||
> *string_char* ~ `[^"$\\]|\$(?!\{)|\\.`
|
||||
>
|
||||
> *indented_string_char* ~ `[^$']|\$\$|\$(?!\{)|''[$']|''\\.|'(?!')`
|
||||
>
|
||||
> *uri* ~ `[A-Za-z][+\-.0-9A-Za-z]*:[!$%&'*+,\-./0-9:=?@A-Z_a-z~]+`
|
||||
|
||||
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 results of other expressions can be included into a string by enclosing them in `${ }`, a feature known as [string interpolation].
|
||||
|
||||
[string interpolation]: ./string-interpolation.md
|
||||
|
||||
The following must be escaped to represent them within a string, by prefixing with a backslash (`\`):
|
||||
|
||||
- Double quote (`"`)
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> "\""
|
||||
> ```
|
||||
>
|
||||
> "\""
|
||||
|
||||
- Backslash (`\`)
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> "\\"
|
||||
> ```
|
||||
>
|
||||
> "\\"
|
||||
|
||||
- Dollar sign followed by an opening curly bracket (`${`) – "dollar-curly"
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> "\${"
|
||||
> ```
|
||||
>
|
||||
> "\${"
|
||||
|
||||
The newline, carriage return, and tab characters can be written as `\n`, `\r` and `\t`, respectively.
|
||||
|
||||
A "double-dollar-curly" (`$${`) can be written literally.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> "$${"
|
||||
> ```
|
||||
>
|
||||
> "$\${"
|
||||
|
||||
String values are output on the terminal with Nix-specific escaping.
|
||||
Strings written to files will contain the characters encoded by the escaping.
|
||||
|
||||
The second way to write string literals is as an *indented string*, which is enclosed between pairs of *double single-quotes* (`''`), like so:
|
||||
|
||||
```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
|
||||
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
|
||||
|
||||
```nix
|
||||
"This is the first line.\nThis is the second line.\n This is the third line.\n"
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Whitespace and newline following the opening `''` is ignored if there is no non-whitespace text on the initial line.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Prefixed tab characters are not stripped.
|
||||
>
|
||||
> > **Example**
|
||||
> >
|
||||
> > The following indented string is prefixed with tabs:
|
||||
> >
|
||||
> > <pre><code class="nohighlight">''
|
||||
> > all:
|
||||
> > @echo hello
|
||||
> > ''
|
||||
> > </code></pre>
|
||||
> >
|
||||
> > "\tall:\n\t\t@echo hello\n"
|
||||
|
||||
Indented strings support [string interpolation].
|
||||
|
||||
The following must be escaped to represent them in an indented string:
|
||||
|
||||
- `$` is escaped by prefixing it with two single quotes (`''`)
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> ''
|
||||
> ''$
|
||||
> ''
|
||||
> ```
|
||||
>
|
||||
> "$\n"
|
||||
|
||||
- `''` is escaped by prefixing it with one single quote (`'`)
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> ''
|
||||
> '''
|
||||
> ''
|
||||
> ```
|
||||
>
|
||||
> "''\n"
|
||||
|
||||
These special characters are escaped as follows:
|
||||
- Linefeed (`\n`): `''\n`
|
||||
- Carriage return (`\r`): `''\r`
|
||||
- Tab (`\t`): `''\t`
|
||||
|
||||
`''\` escapes any other character.
|
||||
|
||||
A "double-dollar-curly" (`$${`) can be written literally.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> ''
|
||||
> $${
|
||||
> ''
|
||||
> ```
|
||||
>
|
||||
> "$\${\n"
|
||||
|
||||
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:
|
||||
|
||||
```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
|
||||
is*, without quotes. For instance, the string
|
||||
`"http://example.org/foo.tar.bz2"` can also be written as
|
||||
`http://example.org/foo.tar.bz2`.
|
705
doc/manual/source/language/syntax.md
Normal file
705
doc/manual/source/language/syntax.md
Normal file
|
@ -0,0 +1,705 @@
|
|||
# Language Constructs
|
||||
|
||||
This section covers syntax and semantics of the Nix language.
|
||||
|
||||
## Basic Literals
|
||||
|
||||
### String {#string-literal}
|
||||
|
||||
See [String literals](string-literals.md).
|
||||
|
||||
### Number {#number-literal}
|
||||
|
||||
<!-- TODO(@rhendric, #10970): split this into int and float -->
|
||||
|
||||
Numbers, which can be *integers* (like `123`) or *floating point*
|
||||
(like `123.43` or `.27e13`).
|
||||
|
||||
Integers in the Nix language are 64-bit [two's complement] signed integers, with a range of -9223372036854775808 to 9223372036854775807, inclusive.
|
||||
|
||||
[two's complement]: https://en.wikipedia.org/wiki/Two%27s_complement
|
||||
|
||||
Note that negative numeric literals are actually parsed as unary negation of positive numeric literals.
|
||||
This means that the minimum integer `-9223372036854775808` cannot be written as-is as a literal, since the positive number `9223372036854775808` is one past the maximum range.
|
||||
|
||||
See [arithmetic] and [comparison] operators for semantics.
|
||||
|
||||
[arithmetic]: ./operators.md#arithmetic
|
||||
[comparison]: ./operators.md#comparison
|
||||
|
||||
### Path {#path-literal}
|
||||
|
||||
*Paths* can be expressed by path literals such as `./builder.sh`.
|
||||
|
||||
A path literal 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 attribute `sh` from the variable `builder`.
|
||||
|
||||
Path literals are resolved relative to their [base directory](@docroot@/glossary.md#gloss-base-directory).
|
||||
Path literals may also refer to absolute paths by starting with a slash.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Absolute paths make expressions less portable.
|
||||
> In the case where a function translates a path literal into an absolute path string for a configuration file, it is recommended to write a string literal instead.
|
||||
> This avoids some confusion about whether files at that location will be used during evaluation.
|
||||
> It also avoids unintentional situations where some function might try to copy everything at the location into the store.
|
||||
|
||||
If the first component of a path is a `~`, it is interpreted such that the rest of the path were relative to the user's home directory.
|
||||
For example, `~/foo` would be equivalent to `/home/edolstra/foo` for a user whose home directory is `/home/edolstra`.
|
||||
Path literals that start with `~` are not allowed in [pure](@docroot@/command-ref/conf-file.md#conf-pure-eval) evaluation.
|
||||
|
||||
Path literals can also include [string interpolation], besides being [interpolated into other expressions].
|
||||
|
||||
[interpolated into 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 number division operation.
|
||||
`./a.${foo}/b.${bar}` is a path.
|
||||
|
||||
[Lookup path](./constructs/lookup-path.md) literals such as `<nixpkgs>` also resolve to path values.
|
||||
|
||||
## List {#list-literal}
|
||||
|
||||
Lists are formed by enclosing a whitespace-separated list of values
|
||||
between square brackets. For example,
|
||||
|
||||
```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.,
|
||||
|
||||
```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.
|
||||
|
||||
Note that lists are only lazy in values, and they are strict in length.
|
||||
|
||||
Elements in a list can be accessed using [`builtins.elemAt`](./builtins.md#builtins-elemAt).
|
||||
|
||||
## Attribute Set {#attrs-literal}
|
||||
|
||||
An attribute set is a collection of name-value-pairs called *attributes*.
|
||||
|
||||
Attribute sets are written enclosed in curly brackets (`{ }`).
|
||||
Attribute names and attribute values are separated by an equal sign (`=`).
|
||||
Each value can be an arbitrary expression, terminated by a semicolon (`;`)
|
||||
|
||||
An attribute name is a string without context, and is denoted by a [name] (an [identifier](./identifiers.md#identifiers) or [string literal](string-literals.md)).
|
||||
|
||||
[name]: ./identifiers.md#names
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *attrset* → `{` { *name* `=` *expr* `;` } `}`
|
||||
|
||||
Attributes can appear in any order.
|
||||
An attribute name may only occur once in each attribute set.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> This defines an attribute set with attributes named:
|
||||
> - `x` with the value `123`, an integer
|
||||
> - `text` with the value `"Hello"`, a string
|
||||
> - `y` where the value is the result of applying the function `f` to the attribute set `{ bla = 456; }`
|
||||
>
|
||||
> ```nix
|
||||
> {
|
||||
> x = 123;
|
||||
> text = "Hello";
|
||||
> y = f { bla = 456; };
|
||||
> }
|
||||
> ```
|
||||
|
||||
Attributes in nested attribute sets can be written using *attribute paths*.
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *attrset* → `{` { *attrpath* `=` *expr* `;` } `}`
|
||||
|
||||
An attribute path is a dot-separated list of [names][name].
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *attrpath* = *name* { `.` *name* }
|
||||
|
||||
<!-- -->
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> { a.b.c = 1; a.b.d = 2; }
|
||||
> ```
|
||||
>
|
||||
> {
|
||||
> a = {
|
||||
> b = {
|
||||
> c = 1;
|
||||
> d = 2;
|
||||
> };
|
||||
> };
|
||||
> }
|
||||
|
||||
Attribute names can also be set implicitly by using the [`inherit` keyword](#inheriting-attributes).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> { inherit (builtins) true; }
|
||||
> ```
|
||||
>
|
||||
> { true = true; }
|
||||
|
||||
Attributes can be accessed with the [`.` operator](./operators.md#attribute-selection).
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
{ 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:
|
||||
|
||||
```nix
|
||||
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
||||
```
|
||||
|
||||
```nix
|
||||
{ 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:
|
||||
|
||||
```nix
|
||||
{ "$!@#?" = 123; }."$!@#?"
|
||||
```
|
||||
|
||||
```nix
|
||||
let bar = "bar"; in
|
||||
{ "foo ${bar}" = 123; }."foo ${bar}"
|
||||
```
|
||||
|
||||
Both will evaluate to `123`.
|
||||
|
||||
Attribute names support [string interpolation]:
|
||||
|
||||
```nix
|
||||
let bar = "foo"; in
|
||||
{ foo = 123; }.${bar}
|
||||
```
|
||||
|
||||
```nix
|
||||
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:
|
||||
|
||||
```nix
|
||||
{ ${if foo then "bar" else null} = true; }
|
||||
```
|
||||
|
||||
This will evaluate to `{}` if `foo` evaluates to `false`.
|
||||
|
||||
A set that has a [`__functor`]{#attr-__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.,
|
||||
|
||||
```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
|
||||
of object-oriented programming, for example.
|
||||
|
||||
## Recursive sets
|
||||
|
||||
Recursive sets are like normal [attribute sets](./types.md#attribute-set), but the attributes can refer to each other.
|
||||
|
||||
> *rec-attrset* = `rec {` [ *name* `=` *expr* `;` `]`... `}`
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
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
|
||||
|
||||
```nix
|
||||
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:
|
||||
|
||||
```nix
|
||||
let
|
||||
x = "foo";
|
||||
y = "bar";
|
||||
in x + y
|
||||
```
|
||||
|
||||
This evaluates to `"foobar"`.
|
||||
|
||||
## Inheriting attributes
|
||||
|
||||
When defining an [attribute set](./types.md#attribute-set) or in a [let-expression](#let-expressions) 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:
|
||||
|
||||
```nix
|
||||
let x = 123; in
|
||||
{
|
||||
inherit x;
|
||||
y = 456;
|
||||
}
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```nix
|
||||
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 the `let` construct.
|
||||
|
||||
It is also possible to inherit attributes from another attribute set.
|
||||
|
||||
Example:
|
||||
|
||||
In this fragment from `all-packages.nix`,
|
||||
|
||||
```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
|
||||
|
||||
```nix
|
||||
...
|
||||
inherit x y z;
|
||||
inherit (src-set) a b c;
|
||||
...
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```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.
|
||||
|
||||
In a `let` expression, `inherit` can be used to selectively bring specific attributes of a set into scope. For example
|
||||
|
||||
|
||||
```nix
|
||||
let
|
||||
x = { a = 1; b = 2; };
|
||||
inherit (builtins) attrNames;
|
||||
in
|
||||
{
|
||||
names = attrNames x;
|
||||
}
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```nix
|
||||
let
|
||||
x = { a = 1; b = 2; };
|
||||
in
|
||||
{
|
||||
names = builtins.attrNames x;
|
||||
}
|
||||
```
|
||||
|
||||
both evaluate to `{ names = [ "a" "b" ]; }`.
|
||||
|
||||
## Functions
|
||||
|
||||
Functions have the following form:
|
||||
|
||||
```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
|
||||
three kinds of patterns:
|
||||
|
||||
- If a pattern is a single identifier, then the function matches any
|
||||
argument. Example:
|
||||
|
||||
```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.,
|
||||
|
||||
```nix
|
||||
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
|
||||
|
||||
```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 (`...`):
|
||||
|
||||
```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,
|
||||
|
||||
```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`.
|
||||
|
||||
- An `@`-pattern provides a means of referring to the whole value
|
||||
being matched:
|
||||
|
||||
```nix
|
||||
args@{ x, y, z, ... }: z + y + x + args.a
|
||||
```
|
||||
|
||||
but can also be written as:
|
||||
|
||||
```nix
|
||||
{ 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 as `a`, using `args.a`, which was
|
||||
given as an additional attribute to the function.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> `args@` binds the name `args` 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
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> f = args@{ a ? 23, ... }: [ a args ];
|
||||
> in
|
||||
> f {}
|
||||
> ```
|
||||
>
|
||||
> is equivalent to
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> f = args @ { ... }: [ (args.a or 23) args ];
|
||||
> in
|
||||
> f {}
|
||||
> ```
|
||||
>
|
||||
> and both expressions will evaluate to:
|
||||
>
|
||||
> ```nix
|
||||
> [ 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.,
|
||||
|
||||
```nix
|
||||
let concat = { x, y }: x + y;
|
||||
in concat { x = "foo"; y = "bar"; }
|
||||
```
|
||||
|
||||
## Conditionals
|
||||
|
||||
Conditionals look like this:
|
||||
|
||||
```nix
|
||||
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:
|
||||
|
||||
```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
|
||||
evaluation is aborted and a backtrace is printed.
|
||||
|
||||
Here is a Nix expression for the Subversion package that shows how
|
||||
assertions can be used:.
|
||||
|
||||
```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:
|
||||
|
||||
1. 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 to `true` but
|
||||
the `db4` argument set to `null`, then the evaluation fails.
|
||||
|
||||
Note that `->` is the [logical
|
||||
implication](https://en.wikipedia.org/wiki/Truth_table#Logical_implication)
|
||||
Boolean operation.
|
||||
|
||||
2. 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.
|
||||
|
||||
3. 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.)
|
||||
|
||||
4. 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*,
|
||||
|
||||
```nix
|
||||
with e1; e2
|
||||
```
|
||||
|
||||
introduces the set *e1* into the lexical scope of the expression *e2*.
|
||||
For instance,
|
||||
|
||||
```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.,
|
||||
|
||||
```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.
|
||||
|
||||
The bindings introduced by `with` do not shadow bindings introduced by
|
||||
other means, e.g.
|
||||
|
||||
```nix
|
||||
let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...
|
||||
```
|
||||
|
||||
establishes the same scope as
|
||||
|
||||
```nix
|
||||
let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...
|
||||
```
|
||||
|
||||
Variables coming from outer `with` expressions *are* shadowed:
|
||||
|
||||
```nix
|
||||
with { a = "outer"; };
|
||||
with { a = "inner"; };
|
||||
a
|
||||
```
|
||||
|
||||
Does evaluate to `"inner"`.
|
||||
|
||||
## Comments
|
||||
|
||||
- Inline comments start with `#` and run until the end of the line.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> # A number
|
||||
> 2 # Equals 1 + 1
|
||||
> ```
|
||||
>
|
||||
> ```console
|
||||
> 2
|
||||
> ```
|
||||
|
||||
- Block comments start with `/*` and run until the next occurrence of `*/`.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> /*
|
||||
> Block comments
|
||||
> can span multiple lines.
|
||||
> */ "hello"
|
||||
> ```
|
||||
>
|
||||
> ```console
|
||||
> "hello"
|
||||
> ```
|
||||
|
||||
This means that block comments cannot be nested.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> /* /* nope */ */ 1
|
||||
> ```
|
||||
>
|
||||
> ```console
|
||||
> error: syntax error, unexpected '*'
|
||||
>
|
||||
> at «string»:1:15:
|
||||
>
|
||||
> 1| /* /* nope */ *
|
||||
> | ^
|
||||
> ```
|
||||
|
||||
Consider escaping nested comments and unescaping them in post-processing.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> ```nix
|
||||
> /* /* nested *\/ */ 1
|
||||
> ```
|
||||
>
|
||||
> ```console
|
||||
> 1
|
||||
> ```
|
120
doc/manual/source/language/types.md
Normal file
120
doc/manual/source/language/types.md
Normal file
|
@ -0,0 +1,120 @@
|
|||
# Data Types
|
||||
|
||||
Every value in the Nix language has one of the following types:
|
||||
|
||||
* [Integer](#type-int)
|
||||
* [Float](#type-float)
|
||||
* [Boolean](#type-bool)
|
||||
* [String](#type-string)
|
||||
* [Path](#type-path)
|
||||
* [Null](#type-null)
|
||||
* [Attribute set](#type-attrs)
|
||||
* [List](#type-list)
|
||||
* [Function](#type-function)
|
||||
* [External](#type-external)
|
||||
|
||||
## Primitives
|
||||
|
||||
### Integer {#type-int}
|
||||
|
||||
An _integer_ in the Nix language is a signed 64-bit integer.
|
||||
|
||||
Non-negative integers can be expressed as [integer literals](syntax.md#number-literal).
|
||||
Negative integers are created with the [arithmetic negation operator](./operators.md#arithmetic).
|
||||
The function [`builtins.isInt`](builtins.md#builtins-isInt) can be used to determine if a value is an integer.
|
||||
|
||||
### Float {#type-float}
|
||||
|
||||
A _float_ in the Nix language is a 64-bit [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) floating-point number.
|
||||
|
||||
Most non-negative floats can be expressed as [float literals](syntax.md#number-literal).
|
||||
Negative floats are created with the [arithmetic negation operator](./operators.md#arithmetic).
|
||||
The function [`builtins.isFloat`](builtins.md#builtins-isFloat) can be used to determine if a value is a float.
|
||||
|
||||
### Boolean {#type-bool}
|
||||
|
||||
A _boolean_ in the Nix language is one of _true_ or _false_.
|
||||
|
||||
<!-- TODO: mention the top-level environment -->
|
||||
|
||||
These values are available as attributes of [`builtins`](builtins.md#builtins-builtins) as [`builtins.true`](builtins.md#builtins-true) and [`builtins.false`](builtins.md#builtins-false).
|
||||
The function [`builtins.isBool`](builtins.md#builtins-isBool) can be used to determine if a value is a boolean.
|
||||
|
||||
### String {#type-string}
|
||||
|
||||
A _string_ in the Nix language is an immutable, finite-length sequence of bytes, along with a [string context](string-context.md).
|
||||
Nix does not assume or support working natively with character encodings.
|
||||
|
||||
String values without string context can be expressed as [string literals](string-literals.md).
|
||||
The function [`builtins.isString`](builtins.md#builtins-isString) can be used to determine if a value is a string.
|
||||
|
||||
### Path {#type-path}
|
||||
|
||||
A _path_ in the Nix language is an immutable, finite-length sequence of bytes starting with `/`, representing a POSIX-style, canonical file system path.
|
||||
Path values are distinct from string values, even if they contain the same sequence of bytes.
|
||||
Operations that produce paths will simplify the result as the standard C function [`realpath`] would, except that there is no symbolic link resolution.
|
||||
|
||||
[`realpath`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html
|
||||
|
||||
Paths are suitable for referring to local files, and are often preferable over strings.
|
||||
- Path values do not contain trailing or duplicate slashes, `.`, or `..`.
|
||||
- Relative path literals are automatically resolved relative to their [base directory].
|
||||
- Tooling can recognize path literals and provide additional features, such as autocompletion, refactoring automation and jump-to-file.
|
||||
|
||||
[base directory]: @docroot@/glossary.md#gloss-base-directory
|
||||
|
||||
A file is not required to exist at a given path in order for that path value to be valid, but a path that is converted to a string with [string interpolation] or [string-and-path concatenation] must resolve to a readable file or directory which will be copied into the Nix store.
|
||||
For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` from the same directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.
|
||||
Operations such as [`import`] can also expect a path to resolve to a readable file or directory.
|
||||
|
||||
[string interpolation]: string-interpolation.md#interpolated-expression
|
||||
[string-and-path concatenation]: operators.md#string-and-path-concatenation
|
||||
[`import`]: builtins.md#builtins-import
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> 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.
|
||||
> Use `:r` to reset the repl as needed.
|
||||
|
||||
[store path]: @docroot@/store/store-path.md
|
||||
|
||||
Path values can be expressed as [path literals](syntax.md#path-literal).
|
||||
The function [`builtins.isPath`](builtins.md#builtins-isPath) can be used to determine if a value is a path.
|
||||
|
||||
### Null {#type-null}
|
||||
|
||||
There is a single value of type _null_ in the Nix language.
|
||||
|
||||
<!-- TODO: mention the top-level environment -->
|
||||
|
||||
This value is available as an attribute on the [`builtins`](builtins.md#builtins-builtins) attribute set as [`builtins.null`](builtins.md#builtins-null).
|
||||
|
||||
## Compound values
|
||||
|
||||
### Attribute set {#type-attrs}
|
||||
|
||||
<!-- TODO(@rhendric, #10970): fill this out -->
|
||||
|
||||
An attribute set can be constructed with an [attribute set literal](syntax.md#attrs-literal).
|
||||
The function [`builtins.isAttrs`](builtins.md#builtins-isAttrs) can be used to determine if a value is an attribute set.
|
||||
|
||||
### List {#type-list}
|
||||
|
||||
<!-- TODO(@rhendric, #10970): fill this out -->
|
||||
|
||||
A list can be constructed with a [list literal](syntax.md#list-literal).
|
||||
The function [`builtins.isList`](builtins.md#builtins-isList) can be used to determine if a value is a list.
|
||||
|
||||
## Function {#type-function}
|
||||
|
||||
<!-- TODO(@rhendric, #10970): fill this out -->
|
||||
|
||||
A function can be constructed with a [function expression](syntax.md#functions).
|
||||
The function [`builtins.isFunction`](builtins.md#builtins-isFunction) can be used to determine if a value is a function.
|
||||
|
||||
## External {#type-external}
|
||||
|
||||
An _external_ value is an opaque value created by a Nix [plugin](../command-ref/conf-file.md#conf-plugin-files).
|
||||
Such a value can be substituted in Nix expressions but only created and used by plugin code.
|
1
doc/manual/source/language/values.md
Normal file
1
doc/manual/source/language/values.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Data Types
|
10
doc/manual/source/language/variables.md
Normal file
10
doc/manual/source/language/variables.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Variables
|
||||
|
||||
A *variable* is an [identifier](identifiers.md) used as an expression.
|
||||
|
||||
> **Syntax**
|
||||
>
|
||||
> *expression* → *identifier*
|
||||
|
||||
A variable must have the same name as a definition in the [scope](./scope.md) that encloses it.
|
||||
The value of a variable is the value of the corresponding expression in the enclosing scope.
|
Loading…
Add table
Add a link
Reference in a new issue