push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

450
doc/README.md Normal file
View File

@@ -0,0 +1,450 @@
# Contributing to the Nixpkgs reference manual
This directory houses the source files for the Nixpkgs reference manual.
> [!IMPORTANT]
> We are actively restructuring our documentation to follow the [Diátaxis framework](https://diataxis.fr/)
>
> Going forward, this directory should **only** contain [reference documentation](https://nix.dev/contributing/documentation/diataxis#reference).
> For tutorials, guides and explanations, contribute to <https://nix.dev/> instead.
>
> We are actively working to generate **all** reference documentation from the [doc-comments](https://github.com/NixOS/rfcs/blob/master/rfcs/0145-doc-strings.md) present in code.
> This also provides the benefit of using `:doc` in the `nix repl` to view reference documentation locally on the fly.
For documentation only relevant for contributors, use Markdown files next to the source and regular code comments.
> [!TIP]
> Feedback for improving support for parsing and rendering doc-comments is highly appreciated.
> [Open an issue](https://github.com/NixOS/nixpkgs/issues/new?labels=6.topic%3A+documentation&title=Doc%3A+) to request bugfixes or new features.
Rendered documentation:
- [Unstable (from master)](https://nixos.org/manual/nixpkgs/unstable/)
- [Stable (from latest release)](https://nixos.org/manual/nixpkgs/stable/)
The rendering tool is [nixos-render-docs](../pkgs/by-name/ni/nixos-render-docs), sometimes abbreviated `nrd`.
## Contributing to this documentation
You can quickly check your edits with `nix-build`:
```ShellSession
$ cd /path/to/nixpkgs
$ nix-build doc
```
If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.html`.
### Development environment
In order to reduce repetition, consider using tools from the provided development environment:
Load it from the Nixpkgs documentation directory with
```ShellSession
$ cd /path/to/nixpkgs/doc
$ nix-shell
```
To load the development utilities automatically when entering that directory, [set up `nix-direnv`](https://nix.dev/guides/recipes/direnv).
Make sure that your local files aren't added to Git history by adding the following lines to `.git/info/exclude` at the root of the Nixpkgs repository:
```
/**/.envrc
/**/.direnv
```
#### `devmode`
Use [`devmode`](../pkgs/by-name/de/devmode/README.md) for a live preview when editing the manual.
### Testing redirects
Once you have a successful build, you can open the relevant HTML (path mentioned above) in a browser along with the anchor, and observe the redirection.
Note that if you already loaded the page and *then* input the anchor, you will need to perform a reload.
This is because browsers do not re-run client JS code when only the anchor has changed.
## Syntax
As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
Additional syntax extensions are available, all of which can be used in NixOS option documentation.
The following extensions are currently used:
#### Tables
Tables, using the [GitHub-flavored Markdown syntax](https://github.github.com/gfm/#tables-extension-).
#### Anchors
Explicitly defined **anchors** on headings, to allow linking to sections.
These should be always used, to ensure the anchors can be linked even when the heading text changes, and to prevent conflicts between [automatically assigned identifiers](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/auto_identifiers.md).
It uses the widely compatible [header attributes](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/attributes.md) syntax:
```markdown
## Syntax {#sec-contributing-markup}
```
> [!Note]
> NixOS option documentation does not support headings in general.
#### Inline Anchors
Allow linking to an arbitrary place in the text (e.g. individual list items, sentences…).
They are defined using a hybrid of the link syntax with the attributes syntax known from headings, called [bracketed spans](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/bracketed_spans.md):
```markdown
- []{#ssec-gnome-hooks-glib} `glib` setup hook will populate `GSETTINGS_SCHEMAS_PATH` and then `wrapGApps*` hook will prepend it to `XDG_DATA_DIRS`.
```
#### Automatic links
If you **omit a link text** for a link pointing to a section, the text will be substituted automatically.
For example `[](#chap-contributing)`.
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#targets-and-cross-referencing).
#### HTML
Inlining HTML is not allowed.
Parts of the documentation gets rendered to various non-HTML formats, such as man pages in the case of NixOS manual.
#### Roles
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``.
The references will turn into links when a mapping exists in [`doc/manpage-urls.json`](./manpage-urls.json).
Please keep the `manpage-urls.json` file alphabetically sorted.
A few markups for other kinds of literals are also available:
- `` {command}`rm -rfi` ``
- `` {env}`XDG_DATA_DIRS` ``
- `` {file}`/etc/passwd` ``
- `` {option}`networking.useDHCP` ``
- `` {var}`/etc/passwd` ``
These literal kinds are used mostly in NixOS option documentation.
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point).
Though, the feature originates from [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage) with slightly different syntax.
They are handled by `myst_role` defined per renderer. <!-- reverse references in code -->
#### Admonitions
Set off from the text to bring attention to something.
It uses pandocs [fenced `div`s syntax](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/fenced_divs.md):
```markdown
::: {.warning}
This is a warning
:::
```
The following are supported:
- `caution`
- `important`
- `note`
- `tip`
- `warning`
- `example`
Example admonitions require a title to work.
If you don't provide one, the manual won't be built.
```markdown
::: {.example #ex-showing-an-example}
# Title for this example
Text for the example.
:::
```
#### [Definition lists](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/definition_lists.md)
For defining a group of terms:
```markdown
pear
: green or yellow bulbous fruit
watermelon
: green fruit with red flesh
```
## Commit conventions
- Make sure you read about the [commit conventions](../CONTRIBUTING.md#commit-conventions) common to Nixpkgs as a whole.
- If creating a commit purely for documentation changes, format the commit message in the following way:
```
doc: (documentation summary)
(Motivation for change, relevant links, additional information.)
```
Examples:
* doc: update the kernel config documentation to use `nix-shell`
* doc: add information about `nix-update-script`
Closes #216321.
- If the commit contains more than just documentation changes, follow the commit message format relevant for the rest of the changes.
## Documentation conventions
In an effort to keep the Nixpkgs manual in a consistent style, please follow the conventions below, unless they prevent you from properly documenting something.
In that case, please open an issue about the particular documentation convention and tag it with a "needs: documentation" label.
When needed, each convention explains why it exists, so you can make a decision whether to follow it or not based on your particular case.
Note that these conventions are about the **structure** of the manual (and its source files), not about the content that goes in it.
You, as the writer of documentation, are still in charge of its content.
### One sentence per line
Put each sentence in its own line.
This makes reviews and suggestions much easier, since GitHub's review system is based on lines.
It also helps identifying long sentences at a glance.
### Writing Function Documentation
Function documentation is *reference documentation*, for which
[diataxis Reference documentation](https://diataxis.fr/reference/) (8 minutes) is **mandatory reading**.
On top of the diataxis framework, which provides a balanced perspective on what reference documentation should contain, we apply a specific style rule to function documentation:
the first sentence is in present tense, active voice, and the subject is omitted, referring implicitly to the name of the function.
For example:
```nix
/**
Subtracts value `b` from value `a`.
Returns the difference as a number.
*/
subtractValues # ...elided code
```
Renders as:
```md
## `subtractValues`
Subtracts value `b` from value `a`.
Returns the difference as a number.
```
### Callouts and examples
Use the [admonition syntax](#admonitions) for callouts and examples.
### Provide self-contained examples
Provide at least one example per function, and make examples self-contained.
This is easier to understand for beginners.
It also helps with testing that it actually works especially once we introduce automation.
Example code should be such that it can be passed to `pkgs.callPackage`.
Instead of something like:
```nix
pkgs.dockerTools.buildLayeredImage {
name = "hello";
contents = [ pkgs.hello ];
}
```
Write something like:
```nix
{ dockerTools, hello }:
dockerTools.buildLayeredImage {
name = "hello";
contents = [ hello ];
}
```
### REPLs
When showing inputs/outputs of any [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop), such as a shell or the Nix REPL, use a format as you'd see in the REPL, while trying to visually separate inputs from outputs.
This means that for a shell, you should use a format like the following:
```shell
$ nix-build -A hello '<nixpkgs>' \
--option require-sigs false \
--option trusted-substituters file:///tmp/hello-cache \
--option substituters file:///tmp/hello-cache
/nix/store/zhl06z4lrfrkw5rp0hnjjfrgsclzvxpm-hello-2.12.1
```
Note how the input is preceded by `$` on the first line and indented on subsequent lines, and how the output is provided as you'd see on the shell.
For the Nix REPL, you should use a format like the following:
```shell
nix-repl> builtins.attrNames { a = 1; b = 2; }
[ "a" "b" ]
```
Note how the input is preceded by `nix-repl>` and the output is provided as you'd see on the Nix REPL.
### Headings for inputs, outputs and examples
When documenting functions or anything that has inputs/outputs and example usage, use nested headings to clearly separate inputs, outputs, and examples.
Keep examples as the last nested heading, and link to the examples wherever applicable in the documentation.
The purpose of this convention is to provide a familiar structure for navigating the manual, so any reader can expect to find content related to inputs in an "inputs" heading, examples in an "examples" heading, and so on.
An example:
```
## buildImage
Some explanation about the function here.
Describe a particular scenario, and point to [](#ex-dockerTools-buildImage), which is an example demonstrating it.
### Inputs
Documentation for the inputs of `buildImage`.
Perhaps even point to [](#ex-dockerTools-buildImage) again when talking about something specifically linked to it.
### Passthru outputs
Documentation for any passthru outputs of `buildImage`.
### Examples
Note that this is the last nested heading in the `buildImage` section.
:::{.example #ex-dockerTools-buildImage}
# Using `buildImage`
Example of how to use `buildImage` goes here.
:::
```
### Function arguments
Use [definition lists](#definition-lists) to document function arguments, and the attributes of such arguments as well as their [types](https://nixos.org/manual/nix/stable/language/values).
For example:
```markdown
# pkgs.coolFunction {#pkgs.coolFunction}
`pkgs.coolFunction` *`name`* *`config`*
Description of what `callPackage` does.
## Inputs {#pkgs-coolFunction-inputs}
If something's special about `coolFunction`'s general argument handling, you can say so here.
Otherwise, just describe the single argument or start the arguments' definition list without introduction.
*`name`* (String)
: The name of the resulting image.
*`config`* (Attribute set)
: Introduce the parameter. Maybe you have a test to make sure `{ }` is a sensible default; then you can say: these attributes are optional; `{ }` is a valid argument.
`outputHash` (String; _optional_)
: A brief explanation including when and when not to pass this attribute.
: _Default:_ the output path's hash.
```
Checklist:
- Start with a synopsis, to show the order of positional arguments.
- Metavariables are in emphasized code spans: ``` *`arg1`* ```.
Metavariables are placeholders where users may write arbitrary expressions.
This includes positional arguments.
- Attribute names are regular code spans: ``` `attr1` ```.
These identifiers can _not_ be picked freely by users, so they are _not_ metavariables.
- _optional_ attributes have a _`Default:`_ if it's easily described as a value.
- _optional_ attributes have a _`Default behavior:`_ if it's not easily described using a value.
- Nix types aren't in code spans, because they are not code
- Nix types are capitalized, to distinguish them from the camelCase Module System types, which _are_ code and behave like functions.
#### Examples
To define a referenceable figure use the following fencing:
```markdown
:::{.example #an-attribute-set-example}
# An attribute set example
You can add text before
```nix
{ a = 1; b = 2;}
```
and after code fencing
:::
```
Defining examples through the `example` fencing class adds them to a "List of Examples" section after the Table of Contents.
Though this is not shown in the rendered documentation on nixos.org.
#### Figures
To define a referenceable figure use the following fencing:
```markdown
::: {.figure #nixos-logo}
# NixOS Logo
![NixOS logo](./nixos_logo.png)
:::
```
Defining figures through the `figure` fencing class adds them to a `List of Figures` after the `Table of Contents`.
Though this is not shown in the rendered documentation on nixos.org.
#### Footnotes
To add a footnote explanation, use the following syntax:
```markdown
Sometimes it's better to add context [^context] in a footnote.
[^context]: This explanation will be rendered at the end of the chapter.
```
#### Inline comments
Inline comments are supported with following syntax:
```markdown
<!-- This is an inline comment -->
```
The comments will not be rendered in the rendered HTML.
#### Link reference definitions
Links can reference a label, for example, to make the link target reusable:
```markdown
::: {.note}
Reference links can also be used to [shorten URLs][url-id] and keep the markdown readable.
:::
[url-id]: https://github.com/NixOS/nixpkgs/blob/19d4f7dc485f74109bd66ef74231285ff797a823/doc/README.md
```
This syntax is taken from [CommonMark](https://spec.commonmark.org/0.30/#link-reference-definitions).
#### Typographic replacements
Typographic replacements are enabled.
Check the [list of possible replacement patterns](https://github.com/executablebooks/markdown-it-py/blob/3613e8016ecafe21709471ee0032a90a4157c2d1/markdown_it/rules_core/replacements.py#L1-L15).
## Getting help
If you need documentation-specific help or reviews, ping [@NixOS/documentation-team](https://github.com/orgs/nixos/teams/documentation-team) on your pull request.

5
doc/anchor-use.js Normal file
View File

@@ -0,0 +1,5 @@
document.addEventListener('DOMContentLoaded', () => {
anchors.add(
'h1[id]:not(div.note h1, div.warning h1, div.tip h1, div.caution h1, div.important h1), h2[id]:not(div.note h2, div.warning h2, div.tip h2, div.caution h2, div.important h2), h3[id]:not(div.note h3, div.warning h3, div.tip h3, div.caution h3, div.important h3), h4[id]:not(div.note h4, div.warning h4, div.tip h4, div.caution h4, div.important h4), h5[id]:not(div.note h5, div.warning h5, div.tip h5, div.caution h5, div.important h5), h6[id]:not(div.note h6, div.warning h6, div.tip h6, div.caution h6, div.important h6)',
)
})

9
doc/anchor.min.js vendored Normal file

File diff suppressed because one or more lines are too long

30
doc/build-helpers.md Normal file
View File

@@ -0,0 +1,30 @@
# Build helpers {#part-builders}
A build helper is a function that produces derivations.
:::{.warning}
This is not to be confused with the [`builder` argument of the Nix `derivation` primitive](https://nixos.org/manual/nix/unstable/language/derivations.html), which refers to the executable that produces the build result, or [remote builder](https://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html), which refers to a remote machine that could run such an executable.
:::
Such a function is usually designed to abstract over a typical workflow for a given programming language or framework.
This allows declaring a build recipe by setting a limited number of options relevant to the particular use case instead of using the `derivation` function directly.
[`stdenv.mkDerivation`](#part-stdenv) is the most widely used build helper and serves as a basis for many others.
In addition, it offers various options to customize parts of the builds.
There is no uniform interface for build helpers.
[Trivial build helpers](#chap-trivial-builders) and [fetchers](#chap-pkgs-fetchers) have various input types for convenience.
[Language- or framework-specific build helpers](#chap-language-support) usually follow the style of `stdenv.mkDerivation`, which accepts an attribute set or a fixed-point function taking an attribute set.
```{=include=} chapters
build-helpers/fixed-point-arguments.chapter.md
build-helpers/fetchers.chapter.md
build-helpers/trivial-build-helpers.chapter.md
build-helpers/testers.chapter.md
build-helpers/dev-shell-tools.chapter.md
build-helpers/special.md
build-helpers/images.md
hooks/index.md
languages-frameworks/index.md
packages/index.md
```

View File

@@ -0,0 +1,84 @@
# Development Shell helpers {#chap-devShellTools}
The `nix-shell` command has popularized the concept of transient shell environments for development or testing purposes.
<!--
We should try to document the product, not its development process in the Nixpkgs reference manual,
but *something* needs to be said to provide context for this library.
This is the most future proof sentence I could come up with while Nix itself does yet make use of this.
Relevant is the current status of the devShell attribute "project": https://github.com/NixOS/nix/issues/7501
-->
However, `nix-shell` is not the only way to create such environments, and even `nix-shell` itself can indirectly benefit from this library.
This library provides a set of functions that help create such environments.
## `devShellTools.valueToString` {#sec-devShellTools-valueToString}
Converts Nix values to strings in the way the [`derivation` built-in function](https://nix.dev/manual/nix/2.23/language/derivations) does.
:::{.example}
## `valueToString` usage examples
```nix
devShellTools.valueToString (builtins.toFile "foo" "bar")
# => "/nix/store/...-foo"
```
```nix
devShellTools.valueToString false
# => ""
```
:::
## `devShellTools.unstructuredDerivationInputEnv` {#sec-devShellTools-unstructuredDerivationInputEnv}
Convert a set of derivation attributes (as would be passed to [`derivation`]) to a set of environment variables that can be used in a shell script.
This function does not support `__structuredAttrs`, but does support `passAsFile`.
:::{.example}
## `unstructuredDerivationInputEnv` usage example
```nix
devShellTools.unstructuredDerivationInputEnv {
drvAttrs = {
name = "foo";
buildInputs = [
hello
figlet
];
builder = bash;
args = [
"-c"
"${./builder.sh}"
];
};
}
# => {
# name = "foo";
# buildInputs = "/nix/store/...-hello /nix/store/...-figlet";
# builder = "/nix/store/...-bash";
#}
```
Note that `args` is not included, because Nix does not added it to the builder process environment.
:::
## `devShellTools.derivationOutputEnv` {#sec-devShellTools-derivationOutputEnv}
Takes the relevant parts of a derivation and returns a set of environment variables, that would be present in the derivation.
:::{.example}
## `derivationOutputEnv` usage example
```nix
let
pkg = hello;
in
devShellTools.derivationOutputEnv {
outputList = pkg.outputs;
outputMap = pkg;
}
```
:::

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
# Fixed-point arguments of build helpers {#chap-build-helpers-finalAttrs}
As mentioned in the beginning of this part, `stdenv.mkDerivation` could alternatively accept a fixed-point function. The input of this function, typically named `finalAttrs`, is expected to be the final state of the attribute set. A build helper like this is said to accept **fixed-point arguments**.
Build helpers don't always support fixed-point arguments yet, as support in [`stdenv.mkDerivation`](#mkderivation-recursive-attributes) was first included in Nixpkgs 22.05.
## Defining a build helper with `lib.extendMkDerivation` {#sec-build-helper-extendMkDerivation}
Developers can use the Nixpkgs library function [`lib.customisation.extendMkDerivation`](#function-library-lib.customisation.extendMkDerivation) to define a build helper supporting fixed-point arguments from an existing one with such support, with an attribute overlay similar to the one taken by [`<pkg>.overrideAttrs`](#sec-pkg-overrideAttrs).
Besides overriding, `lib.extendMkDerivation` also supports `excludeDrvArgNames` to optionally exclude some arguments in the input fixed-point arguments from passing down the base build helper (specified as `constructDrv`).
:::{.example #ex-build-helpers-extendMkDerivation}
# Example definition of `mkLocalDerivation` extended from `stdenv.mkDerivation` with `lib.extendMkDerivation`
We want to define a build helper named `mkLocalDerivation` that builds locally without using substitutes by default.
Instead of taking a plain attribute set,
```nix
{
preferLocalBuild ? true,
allowSubstitute ? false,
specialArg ? (_: false),
...
}@args:
stdenv.mkDerivation (
removeAttrs [
# Don't pass specialArg into mkDerivation.
"specialArg"
] args
// {
# Arguments to pass
inherit preferLocalBuild allowSubstitute;
# Some expressions involving specialArg
greeting = if specialArg "hi" then "hi" else "hello";
}
)
```
we could define with `lib.extendMkDerivation` an attribute overlay to make the result build helper also accept the attribute set's fixed point passing to the underlying `stdenv.mkDerivation`, named `finalAttrs` here:
```nix
lib.extendMkDerivation {
constructDrv = stdenv.mkDerivation;
excludeDrvArgNames = [
# Don't pass specialArg into mkDerivation.
"specialArg"
];
extendDrvArgs =
finalAttrs:
{
preferLocalBuild ? true,
allowSubstitute ? false,
specialArg ? (_: false),
...
}@args:
{
# Arguments to pass
inherit preferLocalBuild allowSubstitute;
# Some expressions involving specialArg
greeting = if specialArg "hi" then "hi" else "hello";
};
}
```
:::
If one needs to apply extra changes to the result derivation, pass the derivation transformation function to `lib.extendMkDerivation` as `lib.customisation.extendMkDerivation { transformDrv = drv: ...; }`.

View File

@@ -0,0 +1,12 @@
# Images {#chap-images}
This chapter describes tools for creating various types of images.
```{=include=} sections
images/appimagetools.section.md
images/dockertools.section.md
images/ocitools.section.md
images/portableservice.section.md
images/makediskimage.section.md
images/binarycache.section.md
```

View File

@@ -0,0 +1,176 @@
# pkgs.appimageTools {#sec-pkgs-appimageTools}
`pkgs.appimageTools` is a set of functions for extracting and wrapping [AppImage](https://appimage.org/) files.
They are meant to be used if traditional packaging from source is infeasible, or if it would take too long.
To quickly run an AppImage file, `pkgs.appimage-run` can be used as well.
::: {.warning}
The `appimageTools` API is unstable and may be subject to backwards-incompatible changes in the future.
:::
## Wrapping {#ssec-pkgs-appimageTools-wrapping}
Use `wrapType2` to wrap any AppImage.
This will create a FHS environment with many packages [expected to exist](https://github.com/AppImage/pkg2appimage/blob/master/excludelist) for the AppImage to work.
`wrapType2` expects an argument with the `src` attribute, and either a `name` attribute or `pname` and `version` attributes.
It will eventually call into [`buildFHSEnv`](#sec-fhs-environments), and any extra attributes in the argument to `wrapType2` will be passed through to it.
This means that you can pass the `extraInstallCommands` attribute, for example, and it will have the same effect as described in [`buildFHSEnv`](#sec-fhs-environments).
::: {.note}
In the past, `appimageTools` provided both `wrapType1` and `wrapType2`, to be used depending on the type of AppImage that was being wrapped.
However, [those were unified early 2020](https://github.com/NixOS/nixpkgs/pull/81833), meaning that both `wrapType1` and `wrapType2` have the same behaviour now.
:::
:::{.example #ex-wrapping-appimage-from-github}
# Wrapping an AppImage from GitHub
```nix
{ appimageTools, fetchurl }:
let
pname = "nuclear";
version = "0.6.30";
src = fetchurl {
url = "https://github.com/nukeop/nuclear/releases/download/v${version}/nuclear-v${version}.AppImage";
hash = "sha256-he1uGC1M/nFcKpMM9JKY4oeexJcnzV0ZRxhTjtJz6xw=";
};
in
appimageTools.wrapType2 { inherit pname version src; }
```
:::
The argument passed to `wrapType2` can also contain an `extraPkgs` attribute, which allows you to include additional packages inside the FHS environment your AppImage is going to run in.
`extraPkgs` must be a function that returns a list of packages.
There are a few ways to learn which dependencies an application needs:
- Looking through the extracted AppImage files, reading its scripts and running `patchelf` and `ldd` on its executables.
This can also be done in `appimage-run`, by setting `APPIMAGE_DEBUG_EXEC=bash`.
- Running `strace -vfefile` on the wrapped executable, looking for libraries that can't be found.
:::{.example #ex-wrapping-appimage-with-extrapkgs}
# Wrapping an AppImage with extra packages
```nix
{ appimageTools, fetchurl }:
let
pname = "irccloud";
version = "0.16.0";
src = fetchurl {
url = "https://github.com/irccloud/irccloud-desktop/releases/download/v${version}/IRCCloud-${version}-linux-x86_64.AppImage";
hash = "sha256-/hMPvYdnVB1XjKgU2v47HnVvW4+uC3rhRjbucqin4iI=";
};
in
appimageTools.wrapType2 {
inherit pname version src;
extraPkgs = pkgs: [ pkgs.at-spi2-core ];
}
```
:::
## Extracting {#ssec-pkgs-appimageTools-extracting}
Use `extract` if you need to extract the contents of an AppImage.
This is usually used in Nixpkgs to install extra files in addition to [wrapping](#ssec-pkgs-appimageTools-wrapping) the AppImage.
`extract` expects an argument with the `src` attribute, and either a `name` attribute or `pname` and `version` attributes.
::: {.note}
In the past, `appimageTools` provided both `extractType1` and `extractType2`, to be used depending on the type of AppImage that was being extracted.
However, [those were unified early 2020](https://github.com/NixOS/nixpkgs/pull/81572), meaning that both `extractType1` and `extractType2` have the same behaviour as `extract` now.
:::
:::{.example #ex-extracting-appimage}
# Extracting an AppImage to install extra files
This example was adapted from a real package in Nixpkgs to show how `extract` is usually used in combination with `wrapType2`.
Note how `appimageContents` is used in `extraInstallCommands` to install additional files that were extracted from the AppImage.
```nix
{ appimageTools, fetchurl }:
let
pname = "irccloud";
version = "0.16.0";
src = fetchurl {
url = "https://github.com/irccloud/irccloud-desktop/releases/download/v${version}/IRCCloud-${version}-linux-x86_64.AppImage";
hash = "sha256-/hMPvYdnVB1XjKgU2v47HnVvW4+uC3rhRjbucqin4iI=";
};
appimageContents = appimageTools.extract { inherit pname version src; };
in
appimageTools.wrapType2 {
inherit pname version src;
extraPkgs = pkgs: [ pkgs.at-spi2-core ];
extraInstallCommands = ''
mv $out/bin/irccloud-${version} $out/bin/irccloud
install -m 444 -D ${appimageContents}/irccloud.desktop $out/share/applications/irccloud.desktop
install -m 444 -D ${appimageContents}/usr/share/icons/hicolor/512x512/apps/irccloud.png \
$out/share/icons/hicolor/512x512/apps/irccloud.png
substituteInPlace $out/share/applications/irccloud.desktop \
--replace-fail 'Exec=AppRun' 'Exec=irccloud'
'';
}
```
:::
The argument passed to `extract` can also contain a `postExtract` attribute, which allows you to execute additional commands after the files are extracted from the AppImage.
`postExtract` must be a string with commands to run.
:::{.warning}
When specifying `postExtract`, you should use `appimageTools.wrapAppImage` instead of `appimageTools.wrapType2`.
Otherwise `wrapType2` will extract the AppImage contents without respecting the `postExtract` instructions.
:::
:::{.example #ex-extracting-appimage-with-postextract}
# Extracting an AppImage to install extra files, using `postExtract`
This is a rewrite of [](#ex-extracting-appimage) to use `postExtract` and `wrapAppImage`.
```nix
{ appimageTools, fetchurl }:
let
pname = "irccloud";
version = "0.16.0";
src = fetchurl {
url = "https://github.com/irccloud/irccloud-desktop/releases/download/v${version}/IRCCloud-${version}-linux-x86_64.AppImage";
hash = "sha256-/hMPvYdnVB1XjKgU2v47HnVvW4+uC3rhRjbucqin4iI=";
};
appimageContents = appimageTools.extract {
inherit pname version src;
postExtract = ''
substituteInPlace $out/irccloud.desktop --replace-fail 'Exec=AppRun' 'Exec=irccloud'
'';
};
in
appimageTools.wrapAppImage {
inherit pname version;
src = appimageContents;
extraPkgs = pkgs: [ pkgs.at-spi2-core ];
extraInstallCommands = ''
mv $out/bin/irccloud-${version} $out/bin/irccloud
install -m 444 -D ${appimageContents}/irccloud.desktop $out/share/applications/irccloud.desktop
install -m 444 -D ${appimageContents}/usr/share/icons/hicolor/512x512/apps/irccloud.png \
$out/share/icons/hicolor/512x512/apps/irccloud.png
'';
# specify src archive for nix-update
passthru.src = src;
}
```
:::

View File

@@ -0,0 +1,63 @@
# pkgs.mkBinaryCache {#sec-pkgs-binary-cache}
`pkgs.mkBinaryCache` is a function for creating Nix flat-file binary caches.
Such a cache exists as a directory on disk, and can be used as a Nix substituter by passing `--substituter file:///path/to/cache` to Nix commands.
Nix packages are most commonly shared between machines using [HTTP, SSH, or S3](https://nixos.org/manual/nix/stable/package-management/sharing-packages.html), but a flat-file binary cache can still be useful in some situations.
For example, you can copy it directly to another machine, or make it available on a network file system.
It can also be a convenient way to make some Nix packages available inside a container via bind-mounting.
`mkBinaryCache` expects an argument with the `rootPaths` attribute.
`rootPaths` must be a list of derivations.
The transitive closure of these derivations' outputs will be copied into the cache.
## Optional arguments {#sec-pkgs-binary-cache-arguments}
`compression` (`"none"` or `"xz"` or `"zstd"`; _optional_)
: The compression algorithm to use.
_Default value:_ `zstd`.
::: {.note}
This function is meant for advanced use cases.
The more idiomatic way to work with flat-file binary caches is via the [nix-copy-closure](https://nixos.org/manual/nix/stable/command-ref/nix-copy-closure.html) command.
You may also want to consider [dockerTools](#sec-pkgs-dockerTools) for your containerization needs.
:::
[]{#sec-pkgs-binary-cache-example}
:::{.example #ex-mkbinarycache-copying-package-closure}
# Copying a package and its closure to another machine with `mkBinaryCache`
The following derivation will construct a flat-file binary cache containing the closure of `hello`.
```nix
{ mkBinaryCache, hello }: mkBinaryCache { rootPaths = [ hello ]; }
```
Build the cache on a machine.
Note that the command still builds the exact nix package above, but adds some boilerplate to build it directly from an expression.
```shellSession
$ nix-build -E 'let pkgs = import <nixpkgs> {}; in pkgs.callPackage ({ mkBinaryCache, hello }: mkBinaryCache { rootPaths = [hello]; }) {}'
/nix/store/azf7xay5xxdnia4h9fyjiv59wsjdxl0g-binary-cache
```
Copy the resulting directory to another machine, which we'll call `host2`:
```shellSession
$ scp result host2:/tmp/hello-cache
```
At this point, the cache can be used as a substituter when building derivations on `host2`:
```shellSession
$ nix-build -A hello '<nixpkgs>' \
--option require-sigs false \
--option trusted-substituters file:///tmp/hello-cache \
--option substituters file:///tmp/hello-cache
/nix/store/zhl06z4lrfrkw5rp0hnjjfrgsclzvxpm-hello-2.12.1
```
:::

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
# `<nixpkgs/nixos/lib/make-disk-image.nix>` {#sec-make-disk-image}
`<nixpkgs/nixos/lib/make-disk-image.nix>` is a function to create _disk images_ in multiple formats: raw, QCOW2 (QEMU), QCOW2-Compressed (compressed version), VDI (VirtualBox), VPC (VirtualPC).
This function can create images in two ways:
- using `cptofs` without any virtual machine to create a Nix store disk image,
- using a virtual machine to create a full NixOS installation.
When testing early-boot or lifecycle parts of NixOS such as a bootloader or multiple generations, it is necessary to opt for a full NixOS system installation.
Whereas for many web servers, applications, it is possible to work with a Nix store only disk image and is faster to build.
NixOS tests also use this function when preparing the VM. The `cptofs` method is used when `virtualisation.useBootLoader` is false (the default). Otherwise the second method is used.
## Features {#sec-make-disk-image-features}
For reference, read the function signature source code for documentation on arguments: <https://github.com/NixOS/nixpkgs/blob/master/nixos/lib/make-disk-image.nix>.
Features are separated in various sections depending on if you opt for a Nix-store only image or a full NixOS image.
### Common {#sec-make-disk-image-features-common}
- arbitrary NixOS configuration
- automatic or bound disk size: `diskSize` parameter, `additionalSpace` can be set when `diskSize` is `auto` to add a constant of disk space
- multiple partition table layouts: EFI, legacy, legacy + GPT, hybrid, none through `partitionTableType` parameter
- OVMF or EFI firmwares and variables templates can be customized
- root filesystem `fsType` can be customized to whatever `mkfs.${fsType}` exists during operations
- root filesystem label can be customized, defaults to `nix-store` if it's a Nix store image, otherwise `nixpkgs/nixos`
- arbitrary code can be executed after disk image was produced with `postVM`
- the current nixpkgs can be realized as a channel in the disk image, which will change the hash of the image when the sources are updated
- additional store paths can be provided through `additionalPaths`
### Full NixOS image {#sec-make-disk-image-features-full-image}
- arbitrary contents with permissions can be placed in the target filesystem using `contents`
- a `/etc/nixpkgs/nixos/configuration.nix` can be provided through `configFile`
- bootloaders are supported
- EFI variables can be mutated during image production and the result is exposed in `$out`
- boot partition size when partition table is `efi` or `hybrid`
### On bit-to-bit reproducibility {#sec-make-disk-image-features-reproducibility}
Images are **NOT** deterministic, please do not hesitate to try to fix this, source of determinisms are (not exhaustive) :
- bootloader installation has timestamps
- SQLite Nix store database contains registration times
- `/etc/shadow` is in a non-deterministic order
A `deterministic` flag is available for best efforts determinism.
## Usage {#sec-make-disk-image-usage}
To produce a Nix-store only image:
```nix
let
pkgs = import <nixpkgs> { };
lib = pkgs.lib;
make-disk-image = import <nixpkgs/nixos/lib/make-disk-image.nix>;
in
make-disk-image {
inherit pkgs lib;
config = { };
additionalPaths = [ ];
format = "qcow2";
onlyNixStore = true;
partitionTableType = "none";
installBootLoader = false;
touchEFIVars = false;
diskSize = "auto";
additionalSpace = "0M"; # Defaults to 512M.
copyChannel = false;
}
```
Some arguments can be left out, they are shown explicitly for the sake of the example.
Building this derivation will provide a QCOW2 disk image containing only the Nix store and its registration information.
To produce a NixOS installation image disk with UEFI and bootloader installed:
```nix
let
pkgs = import <nixpkgs> { };
lib = pkgs.lib;
make-disk-image = import <nixpkgs/nixos/lib/make-disk-image.nix>;
evalConfig = import <nixpkgs/nixos/lib/eval-config.nix>;
in
make-disk-image {
inherit pkgs lib;
inherit
(evalConfig {
modules = [
{
fileSystems."/" = {
device = "/dev/vda";
fsType = "ext4";
autoFormat = true;
};
boot.grub.device = "/dev/vda";
}
];
})
config
;
format = "qcow2";
onlyNixStore = false;
partitionTableType = "legacy+gpt";
installBootLoader = true;
touchEFIVars = true;
diskSize = "auto";
additionalSpace = "0M"; # Defaults to 512M.
copyChannel = false;
memSize = 2048; # Qemu VM memory size in MiB (1024*1024 bytes). Defaults to 1024M.
}
```

View File

@@ -0,0 +1,106 @@
# pkgs.ociTools {#sec-pkgs-ociTools}
`pkgs.ociTools` is a set of functions for creating runtime container bundles according to the [OCI runtime specification v1.0.0](https://github.com/opencontainers/runtime-spec/blob/v1.0.0/spec.md).
It makes no assumptions about the container runner you choose to use to run the created container.
The set of functions in `pkgs.ociTools` currently does not handle the [OCI image specification](https://github.com/opencontainers/image-spec).
At a high-level an OCI implementation would download an OCI Image then unpack that image into an OCI Runtime filesystem bundle.
At this point the OCI Runtime Bundle would be run by an OCI Runtime.
`pkgs.ociTools` provides utilities to create OCI Runtime bundles.
## buildContainer {#ssec-pkgs-ociTools-buildContainer}
This function creates an OCI runtime container (consisting of a `config.json` and a root filesystem directory) that runs a single command inside of it.
The nix store of the container will contain all referenced dependencies of the given command.
This function has an assumption that the container will run on POSIX platforms, and sets configurations (such as the user running the process or certain mounts) according to this assumption.
Because of this, a container built with `buildContainer` will not work on Windows or other non-POSIX platforms without modifications to the container configuration.
These modifications aren't supported by `buildContainer`.
For `linux` platforms, `buildContainer` also configures the following namespaces (see {manpage}`unshare(1)`) to isolate the OCI container from the global namespace:
PID, network, mount, IPC, and UTS.
Note that no user namespace is created, which means that you won't be able to run the container unless you are the `root` user.
### Inputs {#ssec-pkgs-ociTools-buildContainer-inputs}
`buildContainer` expects an argument with the following attributes:
`args` (List of String)
: Specifies a set of arguments to run inside the container.
Any packages referenced by `args` will be made available inside the container.
`mounts` (Attribute Set; _optional_)
: Would specify additional mounts that the runtime must make available to the container.
:::{.warning}
As explained in [issue #290879](https://github.com/NixOS/nixpkgs/issues/290879), this attribute is currently ignored.
:::
:::{.note}
`buildContainer` includes a minimal set of necessary filesystems to be mounted into the container, and this set can't be changed with the `mounts` attribute.
:::
_Default value:_ `{}`.
`readonly` (Boolean; _optional_)
: If `true`, sets the container's root filesystem as read-only.
_Default value:_ `false`.
`os` **DEPRECATED**
: Specifies the operating system on which the container filesystem is based on.
If specified, its value should follow the [OCI Image Configuration Specification](https://github.com/opencontainers/image-spec/blob/main/config.md#properties).
According to the linked specification, all possible values for `$GOOS` in [the Go docs](https://go.dev/doc/install/source#environment) should be valid, but will commonly be one of `darwin` or `linux`.
_Default value:_ `"linux"`.
`arch` **DEPRECATED**
: Used to specify the architecture for which the binaries in the container filesystem have been compiled.
If specified, its value should follow the [OCI Image Configuration Specification](https://github.com/opencontainers/image-spec/blob/main/config.md#properties).
According to the linked specification, all possible values for `$GOARCH` in [the Go docs](https://go.dev/doc/install/source#environment) should be valid, but will commonly be one of `386`, `amd64`, `arm`, or `arm64`.
_Default value:_ `x86_64`.
### Examples {#ssec-pkgs-ociTools-buildContainer-examples}
::: {.example #ex-ociTools-buildContainer-bash}
# Creating an OCI runtime container that runs `bash`
This example uses `ociTools.buildContainer` to create a simple container that runs `bash`.
```nix
{
ociTools,
lib,
bash,
}:
ociTools.buildContainer {
args = [ (lib.getExe bash) ];
readonly = false;
}
```
As an example of how to run the container generated by this package, we'll use `runc` to start the container.
Any other tool that supports OCI containers could be used instead.
```shell
$ nix-build
(some output removed for clarity)
/nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join
$ cd /nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join
$ nix-shell -p runc
[nix-shell:/nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join]$ sudo runc run ocitools-example
help
GNU bash, version 5.2.26(1)-release (x86_64-pc-linux-gnu)
(some output removed for clarity)
```
:::

View File

@@ -0,0 +1,188 @@
# pkgs.portableService {#sec-pkgs-portableService}
`pkgs.portableService` is a function to create [Portable Services](https://systemd.io/PORTABLE_SERVICES/) in a read-only, immutable, `squashfs` raw disk image.
This lets you use Nix to build images which can be run on many recent Linux distributions.
::: {.note}
Portable services are supported starting with systemd 239 (released on 2018-06-22).
:::
The generated image will contain the file system structure as required by the Portable Services specification, along with the packages given to `portableService` and all of their dependencies.
When generated, the image will exist in the Nix store with the `.raw` file extension, as required by the specification.
See [](#ex-portableService-hello) to understand how to use the output of `portableService`.
## Inputs {#ssec-pkgs-portableService-inputs}
`portableService` expects one argument with the following attributes:
`pname` (String)
: The name of the portable service.
The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification.
`version` (String)
: The version of the portable service.
The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification.
`units` (List of Attribute Set)
: A list of derivations for systemd unit files.
Each derivation must produce a single file, and must have a name that starts with the value of `pname` and ends with the suffix of the unit type (e.g. ".service", ".socket", ".timer", and so on).
See [](#ex-portableService-hello) to better understand this naming constraint.
`description` (String or Null; _optional_)
: If specified, the value is added as `PORTABLE_PRETTY_NAME` to the `/etc/os-release` file in the generated image.
This could be used to provide more information to anyone inspecting the image.
_Default value:_ `null`.
`homepage` (String or Null; _optional_)
: If specified, the value is added as `HOME_URL` to the `/etc/os-release` file in the generated image.
This could be used to provide more information to anyone inspecting the image.
_Default value:_ `null`.
`symlinks` (List of Attribute Set; _optional_)
: A list of attribute sets in the format `{object, symlink}`.
For each item in the list, `portableService` will create a symlink in the path specified by `symlink` (relative to the root of the image) that points to `object`.
All packages that `object` depends on and their dependencies are automatically copied into the image.
This can be used to create symlinks for applications that assume some files to exist globally (`/etc/ssl` or `/bin/bash`, for example).
See [](#ex-portableService-symlinks) to understand how to do that.
_Default value:_ `[]`.
`contents` (List of Attribute Set; _optional_)
: A list of additional derivations to be included as-is in the image.
These derivations will be included directly in a `/nix/store` directory inside the image.
_Default value:_ `[]`.
`squashfsTools` (Attribute Set; _optional_)
: Allows you to override the package that provides {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
_Default value:_ `pkgs.squashfsTools`.
`squash-compression` (String; _optional_)
: Passed as the compression option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
_Default value:_ `"xz -Xdict-size 100%"`.
`squash-block-size` (String; _optional_)
: Passed as the block size option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
_Default value:_ `"1M"`.
## Examples {#ssec-pkgs-portableService-examples}
[]{#ex-pkgs-portableService}
:::{.example #ex-portableService-hello}
# Building a Portable Service image
The following example builds a Portable Service image with the `hello` package, along with a service unit that runs it.
```nix
{
lib,
writeText,
portableService,
hello,
}:
let
hello-service = writeText "hello.service" ''
[Unit]
Description=Hello world service
[Service]
Type=oneshot
ExecStart=${lib.getExe hello}
'';
in
portableService {
pname = "hello";
inherit (hello) version;
units = [ hello-service ];
}
```
After building the package, the generated image can be loaded into a system through {manpage}`portablectl(1)`:
```shell
$ nix-build
(some output removed for clarity)
/nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1
$ portablectl attach /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw
Created directory /etc/systemd/system.attached.
Created directory /etc/systemd/system.attached/hello.service.d.
Written /etc/systemd/system.attached/hello.service.d/20-portable.conf.
Created symlink /etc/systemd/system.attached/hello.service.d/10-profile.conf → /usr/lib/systemd/portable/profile/default/service.conf.
Copied /etc/systemd/system.attached/hello.service.
Created symlink /etc/portables/hello_2.12.1.raw → /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw.
$ systemctl start hello
$ journalctl -u hello
Feb 28 22:39:16 hostname systemd[1]: Starting Hello world service...
Feb 28 22:39:16 hostname hello[102887]: Hello, world!
Feb 28 22:39:16 hostname systemd[1]: hello.service: Deactivated successfully.
Feb 28 22:39:16 hostname systemd[1]: Finished Hello world service.
$ portablectl detach hello_2.12.1
Removed /etc/systemd/system.attached/hello.service.
Removed /etc/systemd/system.attached/hello.service.d/10-profile.conf.
Removed /etc/systemd/system.attached/hello.service.d/20-portable.conf.
Removed /etc/systemd/system.attached/hello.service.d.
Removed /etc/portables/hello_2.12.1.raw.
Removed /etc/systemd/system.attached.
```
:::
:::{.example #ex-portableService-symlinks}
# Specifying symlinks when building a Portable Service image
Some services may expect files or directories to be available globally.
An example is a service which expects all trusted SSL certificates to exist in a specific location by default.
To make things available globally, you must specify the `symlinks` attribute when using `portableService`.
The following package builds on the package from [](#ex-portableService-hello) to make `/etc/ssl` available globally (this is only for illustrative purposes, because `hello` doesn't use `/etc/ssl`).
```nix
{
lib,
writeText,
portableService,
hello,
cacert,
}:
let
hello-service = writeText "hello.service" ''
[Unit]
Description=Hello world service
[Service]
Type=oneshot
ExecStart=${lib.getExe hello}
'';
in
portableService {
pname = "hello";
inherit (hello) version;
units = [ hello-service ];
symlinks = [
{
object = "${cacert}/etc/ssl";
symlink = "/etc/ssl";
}
];
}
```
:::

View File

@@ -0,0 +1,12 @@
# Special build helpers {#chap-special}
This chapter describes several special build helpers.
```{=include=} sections
special/fakenss.section.md
special/fhs-environments.section.md
special/makesetuphook.section.md
special/mkshell.section.md
special/vm-tools.section.md
special/checkpoint-build.section.md
```

View File

@@ -0,0 +1,41 @@
# pkgs.checkpointBuildTools {#sec-checkpoint-build}
`pkgs.checkpointBuildTools` provides a way to build derivations incrementally. It consists of two functions to make checkpoint builds using Nix possible.
For hermeticity, Nix derivations do not allow any state to be carried over between builds, making a transparent incremental build within a derivation impossible.
However, we can tell Nix explicitly what the previous build state was, by representing that previous state as a derivation output. This allows the passed build state to be used for an incremental build.
To change a normal derivation to a checkpoint based build, these steps must be taken:
```nix
{
checkpointArtifacts = (pkgs.checkpointBuildTools.prepareCheckpointBuild pkgs.virtualbox);
}
```
```nix
{
changedVBox = pkgs.virtualbox.overrideAttrs (old: {
src = path/to/vbox/sources;
});
}
```
- use `mkCheckpointBuild changedVBox checkpointArtifacts`
- enjoy shorter build times
## Example {#sec-checkpoint-build-example}
```nix
{
pkgs ? import <nixpkgs> { },
}:
let
inherit (pkgs.checkpointBuildTools) prepareCheckpointBuild mkCheckpointBuild;
helloCheckpoint = prepareCheckpointBuild pkgs.hello;
changedHello = pkgs.hello.overrideAttrs (_: {
doCheck = false;
postPatch = ''
sed -i 's/Hello, world!/Hello, Nix!/g' src/hello.c
'';
});
in
mkCheckpointBuild changedHello helloCheckpoint
```

View File

@@ -0,0 +1,84 @@
# fakeNss {#sec-fakeNss}
Provides `/etc/passwd` and `/etc/group` files that contain `root` and `nobody`, allowing user/group lookups to work in binaries that insist on doing those.
This might be a better choice than a custom script running `useradd` and related utilities if you only need those files to exist with some entries.
`fakeNss` also provides `/etc/nsswitch.conf`, configuring NSS host resolution to first check `/etc/hosts` before checking DNS, since the default in the absence of a config file (`dns [!UNAVAIL=return] files`) is quite unexpected.
It also creates an empty directory at `/var/empty` because it uses that as the home directory for the `root` and `nobody` users.
The `/var/empty` directory can also be used as a `chroot` target to prevent file access in processes that do not need to access files, if your container runs such processes.
The user entries created by `fakeNss` use the `/bin/sh` shell, which is not provided by `fakeNss` because in most cases it won't be used.
If you need that to be available, see [`dockerTools.binSh`](#sssec-pkgs-dockerTools-helpers-binSh) or provide your own.
## Inputs {#sec-fakeNss-inputs}
`fakeNss` is made available in Nixpkgs as a package rather than a function, but it has two attributes that can be overridden and might be useful in particular cases.
For more details on how overriding works, see [](#ex-fakeNss-overriding) and [](#sec-pkg-override).
`extraPasswdLines` (List of Strings; _optional_)
: A list of lines that will be added to `/etc/passwd`.
Useful if extra users need to exist in the output of `fakeNss`.
If `extraPasswdLines` is specified, it will **not** override the `root` and `nobody` entries created by `fakeNss`.
Those entries will always exist.
Lines specified here must follow the format in {manpage}`passwd(5)`.
_Default value:_ `[]`.
`extraGroupLines` (List of Strings; _optional_)
: A list of lines that will be added to `/etc/group`.
Useful if extra groups need to exist in the output of `fakeNss`.
If `extraGroupLines` is specified, it will **not** override the `root` and `nobody` entries created by `fakeNss`.
Those entries will always exist.
Lines specified here must follow the format in {manpage}`group(5)`.
_Default value:_ `[]`.
## Examples {#sec-fakeNss-examples}
:::{.example #ex-fakeNss-dockerTools-buildImage}
# Using `fakeNss` with `dockerTools.buildImage`
This example shows how to use `fakeNss` as-is.
It is useful with functions in `dockerTools` to allow building Docker images that have the `/etc/passwd` and `/etc/group` files.
This example includes the `hello` binary in the image so it can do something besides just have the extra files.
```nix
{
dockerTools,
fakeNss,
hello,
}:
dockerTools.buildImage {
name = "image-with-passwd";
tag = "latest";
copyToRoot = [
fakeNss
hello
];
config = {
Cmd = [ "/bin/hello" ];
};
}
```
:::
:::{.example #ex-fakeNss-overriding}
# Using `fakeNss` with an override to add extra lines
The following code uses `override` to add extra lines to `/etc/passwd` and `/etc/group` to create another user and group entry.
```nix
{ fakeNss }:
fakeNss.override {
extraPasswdLines = [ "newuser:x:9001:9001:new user:/var/empty:/bin/sh" ];
extraGroupLines = [ "newuser:x:9001:" ];
}
```
:::

View File

@@ -0,0 +1,69 @@
# buildFHSEnv {#sec-fhs-environments}
`buildFHSEnv` provides a way to build and run an FHS-compatible, lightweight sandbox. It creates an isolated root filesystem with the host's `/nix/store`, so its footprint in terms of disk space is quite small. This allows you to run software which is hard or unfeasible to patch for NixOS; 3rd-party source trees with FHS assumptions, games distributed as tarballs, software with integrity checking and/or external self-updated binaries for instance.
It uses Linux' namespaces feature to create temporary lightweight environments which are destroyed after all child processes exit, without requiring elevated privileges. It works similar to containerisation technology such as Docker or FlatPak but provides no security-relevant separation from the host system.
Accepted arguments are:
- `name`
The name of the environment.
- `pname`
The pname of the environment.
- `version`
The version of the environment.
- `executableName`
The name of the wrapper executable. Defaults to `pname` if set, or `name` otherwise.
- `targetPkgs`
Packages to be installed for the main host's architecture (i.e. x86_64 on x86_64 installations). Along with libraries binaries are also installed.
- `multiPkgs`
Packages to be installed for all architectures supported by a host (i.e. i686 and x86_64 on x86_64 installations). Only libraries are installed by default.
- `multiArch`
Whether to install 32bit multiPkgs into the FHSEnv in 64bit environments
- `extraBuildCommands`
Additional commands to be executed for finalizing the directory structure.
- `extraBuildCommandsMulti`
Like `extraBuildCommands`, but executed only on multilib architectures.
- `extraOutputsToInstall`
Additional derivation outputs to be linked for both target and multi-architecture packages.
- `extraInstallCommands`
Additional commands to be executed for finalizing the derivation with runner script.
- `runScript`
A shell command to be executed inside the sandbox. It defaults to `bash`. Command line arguments passed to the resulting wrapper are appended to this command by default.
This command must be escaped; i.e. `"foo app" --do-stuff --with "some file"`. See `lib.escapeShellArgs`.
- `profile`
Optional script for `/etc/profile` within the sandbox.
You can create a simple environment using a `shell.nix` like this:
```nix
{
pkgs ? import <nixpkgs> { },
}:
(pkgs.buildFHSEnv {
name = "simple-x11-env";
targetPkgs =
pkgs:
(with pkgs; [
udev
alsa-lib
])
++ (with pkgs.xorg; [
libX11
libXcursor
libXrandr
]);
multiPkgs =
pkgs:
(with pkgs; [
udev
alsa-lib
]);
runScript = "bash";
}).env
```
Running `nix-shell` on it would drop you into a shell inside an FHS env where those libraries and binaries are available in FHS-compliant paths. Applications that expect an FHS structure (i.e. proprietary binaries) can run inside this environment without modification.
You can build a wrapper by running your binary in `runScript`, e.g. `./bin/start.sh`. Relative paths work as expected.
Additionally, the FHS builder links all relocated gsettings-schemas (the glib setup-hook moves them to `share/gsettings-schemas/${name}/glib-2.0/schemas`) to their standard FHS location. This means you don't need to wrap binaries with `wrapGApps*` hook.

View File

@@ -0,0 +1,55 @@
# pkgs.makeSetupHook {#sec-pkgs.makeSetupHook}
`pkgs.makeSetupHook` is a build helper that produces hooks that go in to `nativeBuildInputs`
## Usage {#sec-pkgs.makeSetupHook-usage}
```nix
pkgs.makeSetupHook {
name = "something-hook";
propagatedBuildInputs = [ pkgs.commandsomething ];
depsTargetTargetPropagated = [ pkgs.libsomething ];
} ./script.sh
```
### setup hook that depends on the hello package and runs hello and @shell@ is substituted with path to bash {#sec-pkgs.makeSetupHook-usage-example}
```nix
pkgs.makeSetupHook
{
name = "run-hello-hook";
# Put dependencies here if they have hooks or necessary dependencies propagated
# otherwise prefer direct paths to executables.
propagatedBuildInputs = [
pkgs.hello
pkgs.cowsay
];
substitutions = {
shell = "${pkgs.bash}/bin/bash";
cowsay = "${pkgs.cowsay}/bin/cowsay";
};
}
(
writeScript "run-hello-hook.sh" ''
#!@shell@
# the direct path to the executable has to be here because
# this will be run when the file is sourced
# at which point '$PATH' has not yet been populated with inputs
@cowsay@ cow
_printHelloHook() {
hello
}
preConfigureHooks+=(_printHelloHook)
''
)
```
## Attributes {#sec-pkgs.makeSetupHook-attributes}
* `name` Set the name of the hook.
* `propagatedBuildInputs` Runtime dependencies (such as binaries) of the hook.
* `depsTargetTargetPropagated` Non-binary dependencies.
* `meta`
* `passthru`
* `substitutions` Variables for `substituteAll`

View File

@@ -0,0 +1,46 @@
# pkgs.mkShell {#sec-pkgs-mkShell}
`pkgs.mkShell` is a specialized `stdenv.mkDerivation` that removes some
repetition when using it with `nix-shell` (or `nix develop`).
## Usage {#sec-pkgs-mkShell-usage}
Here is a common usage example:
```nix
{
pkgs ? import <nixpkgs> { },
}:
pkgs.mkShell {
packages = [ pkgs.gnumake ];
inputsFrom = [
pkgs.hello
pkgs.gnutar
];
shellHook = ''
export DEBUG=1
'';
}
```
## Attributes {#sec-pkgs-mkShell-attributes}
* `name` (default: `nix-shell`). Set the name of the derivation.
* `packages` (default: `[]`). Add executable packages to the `nix-shell` environment.
* `inputsFrom` (default: `[]`). Add build dependencies of the listed derivations to the `nix-shell` environment.
* `shellHook` (default: `""`). Bash statements that are executed by `nix-shell`.
... all the attributes of `stdenv.mkDerivation`.
## Variants {#sec-pkgs-mkShell-variants}
`pkgs.mkShellNoCC` is a variant that uses `stdenvNoCC` instead of `stdenv` as base environment. This is useful if no C compiler is needed in the shell environment.
## Building the shell {#sec-pkgs-mkShell-building}
This derivation output will contain a text file that contains a reference to
all the build inputs. This is useful in CI where we want to make sure that
every derivation, and its dependencies, build properly. Or when creating a GC
root so that the build dependencies don't get garbage-collected.

View File

@@ -0,0 +1,161 @@
# vmTools {#sec-vm-tools}
A set of VM related utilities, that help in building some packages in more advanced scenarios.
## `vmTools.createEmptyImage` {#vm-tools-createEmptyImage}
A bash script fragment that produces a disk image at `destination`.
### Attributes {#vm-tools-createEmptyImage-attributes}
* `size`. The disk size, in MiB.
* `fullName`. Name that will be written to `${destination}/nix-support/full-name`.
* `destination` (optional, default `$out`). Where to write the image files.
## `vmTools.runInLinuxVM` {#vm-tools-runInLinuxVM}
Run a derivation in a Linux virtual machine (using Qemu/KVM).
By default, there is no disk image; the root filesystem is a `tmpfs`, and the Nix store is shared with the host (via the [9P protocol](https://wiki.qemu.org/Documentation/9p#9p_Protocol)).
Thus, any pure Nix derivation should run unmodified.
If the build fails and Nix is run with the `-K/--keep-failed` option, a script `run-vm` will be left behind in the temporary build directory that allows you to boot into the VM and debug it interactively.
### Attributes {#vm-tools-runInLinuxVM-attributes}
* `preVM` (optional). Shell command to be evaluated *before* the VM is started (i.e., on the host).
* `memSize` (optional, default `512`). The memory size of the VM in MiB (1024×1024 bytes).
* `diskImage` (optional). A file system image to be attached to `/dev/sda`.
Note that currently we expect the image to contain a filesystem, not a full disk image with a partition table etc.
### Examples {#vm-tools-runInLinuxVM-examples}
Build the derivation hello inside a VM:
```nix
{ pkgs }: with pkgs; with vmTools; runInLinuxVM hello
```
Build inside a VM with extra memory:
```nix
{ pkgs }:
with pkgs;
with vmTools;
runInLinuxVM (
hello.overrideAttrs (_: {
memSize = 1024;
})
)
```
Use VM with a disk image (implicitly sets `diskImage`, see [`vmTools.createEmptyImage`](#vm-tools-createEmptyImage)):
```nix
{ pkgs }:
with pkgs;
with vmTools;
runInLinuxVM (
hello.overrideAttrs (_: {
preVM = createEmptyImage {
size = 1024;
fullName = "vm-image";
};
})
)
```
## `vmTools.extractFs` {#vm-tools-extractFs}
Takes a file, such as an ISO, and extracts its contents into the store.
### Attributes {#vm-tools-extractFs-attributes}
* `file`. Path to the file to be extracted.
Note that currently we expect the image to contain a filesystem, not a full disk image with a partition table etc.
* `fs` (optional). Filesystem of the contents of the file.
### Examples {#vm-tools-extractFs-examples}
Extract the contents of an ISO file:
```nix
{ pkgs }: with pkgs; with vmTools; extractFs { file = ./image.iso; }
```
## `vmTools.extractMTDfs` {#vm-tools-extractMTDfs}
Like [](#vm-tools-extractFs), but it makes use of a [Memory Technology Device (MTD)](https://en.wikipedia.org/wiki/Memory_Technology_Device).
## `vmTools.runInLinuxImage` {#vm-tools-runInLinuxImage}
Like [](#vm-tools-runInLinuxVM), but instead of using `stdenv` from the Nix store, run the build using the tools provided by `/bin`, `/usr/bin`, etc. from the specified filesystem image, which typically is a filesystem containing a [FHS](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)-based Linux distribution.
## `vmTools.makeImageTestScript` {#vm-tools-makeImageTestScript}
Generate a script that can be used to run an interactive session in the given image.
### Examples {#vm-tools-makeImageTestScript-examples}
Create a script for running a Fedora 27 VM:
```nix
{ pkgs }: with pkgs; with vmTools; makeImageTestScript diskImages.fedora27x86_64
```
Create a script for running an Ubuntu 20.04 VM:
```nix
{ pkgs }: with pkgs; with vmTools; makeImageTestScript diskImages.ubuntu2004x86_64
```
## `vmTools.diskImageFuns` {#vm-tools-diskImageFuns}
A set of functions that build a predefined set of minimal Linux distributions images.
### Images {#vm-tools-diskImageFuns-images}
* Fedora
* `fedora26x86_64`
* `fedora27x86_64`
* CentOS
* `centos6i386`
* `centos6x86_64`
* `centos7x86_64`
* Ubuntu
* `ubuntu1404i386`
* `ubuntu1404x86_64`
* `ubuntu1604i386`
* `ubuntu1604x86_64`
* `ubuntu1804i386`
* `ubuntu1804x86_64`
* `ubuntu2004i386`
* `ubuntu2004x86_64`
* `ubuntu2204i386`
* `ubuntu2204x86_64`
* Debian
* `debian10i386`
* `debian10x86_64`
* `debian11i386`
* `debian11x86_64`
* `debian12i386`
* `debian12x86_64`
### Attributes {#vm-tools-diskImageFuns-attributes}
* `size` (optional, defaults to `4096`). The size of the image, in MiB.
* `extraPackages` (optional). A list names of additional packages from the distribution that should be included in the image.
### Examples {#vm-tools-diskImageFuns-examples}
8GiB image containing Firefox in addition to the default packages:
```nix
{ pkgs }:
with pkgs;
with vmTools;
diskImageFuns.ubuntu2004x86_64 {
extraPackages = [ "firefox" ];
size = 8192;
}
```
## `vmTools.diskImageExtraFuns` {#vm-tools-diskImageExtraFuns}
Shorthand for `vmTools.diskImageFuns.<attr> { extraPackages = ... }`.
## `vmTools.diskImages` {#vm-tools-diskImages}
Shorthand for `vmTools.diskImageFuns.<attr> { }`.

View File

@@ -0,0 +1,720 @@
# Testers {#chap-testers}
This chapter describes several testing builders which are available in the `testers` namespace.
## `hasPkgConfigModules` {#tester-hasPkgConfigModules}
<!-- Old anchor name so links still work -->
[]{#tester-hasPkgConfigModule}
Checks whether a package exposes a given list of `pkg-config` modules.
If the `moduleNames` argument is omitted, `hasPkgConfigModules` will use `meta.pkgConfigModules`.
:::{.example #ex-haspkgconfigmodules-defaultvalues}
# Check that `pkg-config` modules are exposed using default values
```nix
{
passthru.tests.pkg-config = testers.hasPkgConfigModules { package = finalAttrs.finalPackage; };
meta.pkgConfigModules = [ "libfoo" ];
}
```
:::
:::{.example #ex-haspkgconfigmodules-explicitmodules}
# Check that `pkg-config` modules are exposed using explicit module names
```nix
{
passthru.tests.pkg-config = testers.hasPkgConfigModules {
package = finalAttrs.finalPackage;
moduleNames = [ "libfoo" ];
};
}
```
:::
## `hasCmakeConfigModules` {#tester-hasCmakeConfigModules}
Checks whether a package exposes a given list of `*config.cmake` modules.
Note the moduleNames used in cmake find_package are case sensitive.
:::{.example #ex-hascmakeconfigmodules}
# Check that `*config.cmake` modules are exposed using explicit module names
```nix
{
passthru.tests.cmake-config = testers.hasCmakeConfigModules {
package = finalAttrs.finalPackage;
moduleNames = [ "Foo" ];
};
}
```
:::
## `lycheeLinkCheck` {#tester-lycheeLinkCheck}
Check a packaged static site's links with the [`lychee` package](https://search.nixos.org/packages?show=lychee&type=packages&query=lychee).
You may use Nix to reproducibly build static websites, such as for software documentation.
Some packages will install documentation in their `out` or `doc` outputs, or maybe you have dedicated package where you've made your static site reproducible by running a generator, such as [Hugo](https://gohugo.io/) or [mdBook](https://rust-lang.github.io/mdBook/), in a derivation.
If you have a static site that can be built with Nix, you can use `lycheeLinkCheck` to check that the hyperlinks in your site are correct, and do so as part of your Nix workflow and CI.
:::{.example #ex-lycheelinkcheck}
# Check hyperlinks in the `nix` documentation
```nix
testers.lycheeLinkCheck { site = nix.doc + "/share/doc/nix/manual"; }
```
:::
### Return value {#tester-lycheeLinkCheck-return}
This tester produces a package that does not produce useful outputs, but only succeeds if the hyperlinks in your site are correct. The build log will list the broken links.
It has two modes:
- Build the returned derivation; its build process will check that internal hyperlinks are correct. This runs in the sandbox, so it will not check external hyperlinks, but it is quick and reliable.
- Invoke the `.online` attribute with [`nix run`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-run) ([experimental](https://nixos.org/manual/nix/stable/contributing/experimental-features#xp-feature-nix-command)). This runs outside the sandbox, and checks that both internal and external hyperlinks are correct.
Example:
```shell
nix run nixpkgs#lychee.tests.ok.online
```
### Inputs {#tester-lycheeLinkCheck-inputs}
`site` (path or derivation) {#tester-lycheeLinkCheck-param-site}
: The path to the files to check.
`remap` (attribute set, optional) {#tester-lycheeLinkCheck-param-remap}
: An attribute set where the attribute names are regular expressions.
The values should be strings, derivations, or path values.
In the returned check's default configuration, external URLs are only checked when you run the `.online` attribute.
By adding remappings, you can check offline that URLs to external resources are correct, by providing a stand-in from the file system.
Before checking the existence of a URL, the regular expressions are matched and replaced by their corresponding values.
Example:
```nix
{
"https://nix\\.dev/manual/nix/[a-z0-9.-]*" = "${nix.doc}/share/doc/nix/manual";
"https://nixos\\.org/manual/nix/(un)?stable" =
"${emptyDirectory}/placeholder-to-disallow-old-nix-docs-urls";
}
```
Store paths in the attribute values are automatically prefixed with `file://`, because lychee requires this for paths in the file system.
If this is a problem, or if you need to control the order in which replacements are performed, use `extraConfig.remap` instead.
`extraConfig` (attribute set) {#tester-lycheeLinkCheck-param-extraConfig}
: Extra configuration to pass to `lychee` in its [configuration file](https://github.com/lycheeverse/lychee/blob/master/lychee.example.toml).
It is automatically [translated](https://nixos.org/manual/nixos/stable/index.html#sec-settings-nix-representable) to TOML.
Example: `{ "include_verbatim" = true; }`
`lychee` (derivation, optional) {#tester-lycheeLinkCheck-param-lychee}
: The `lychee` package to use.
## `shellcheck` {#tester-shellcheck}
Run files through `shellcheck`, a static analysis tool for shell scripts, failing if there are any issues.
:::{.example #ex-shellcheck}
# Run `testers.shellcheck`
A single script
```nix
testers.shellcheck {
name = "script";
src = ./script.sh;
}
```
Multiple files
```nix
let
inherit (lib) fileset;
in
testers.shellcheck {
name = "nixbsd-activate";
src = fileset.toSource {
root = ./.;
fileset = fileset.unions [
./lib.sh
./nixbsd-activate
];
};
}
```
:::
### Inputs {#tester-shellcheck-inputs}
`name` (string, optional)
: The name of the test.
`name` will be required at a future point because it massively improves traceability of test failures, but is kept optional for now to avoid breaking existing usages.
Defaults to `run-shellcheck`.
The name of the derivation produced by the tester is `shellcheck-${name}` when `name` is supplied.
`src` (path-like)
: The path to the shell script(s) to check.
This can be a single file or a directory containing shell files.
All files in `src` will be checked, so you may want to provide `fileset`-based source instead of a whole directory.
### Return value {#tester-shellcheck-return}
A derivation that runs `shellcheck` on the given script(s), producing an empty output if no issues are found.
The build will fail if `shellcheck` finds any issues.
## `shfmt` {#tester-shfmt}
Run files through `shfmt`, a shell script formatter, failing if any files are reformatted.
:::{.example #ex-shfmt}
# Run `testers.shfmt`
A single script
```nix
testers.shfmt {
name = "script";
src = ./script.sh;
}
```
Multiple files
```nix
let
inherit (lib) fileset;
in
testers.shfmt {
name = "nixbsd";
src = fileset.toSource {
root = ./.;
fileset = fileset.unions [
./lib.sh
./nixbsd-activate
];
};
}
```
:::
### Inputs {#tester-shfmt-inputs}
`name` (string)
: The name of the test.
`name` is required because it massively improves traceability of test failures.
The name of the derivation produced by the tester is `shfmt-${name}`.
`src` (path-like)
: The path to the shell script(s) to check.
This can be a single file or a directory containing shell files.
All files in `src` will be checked, so you may want to provide `fileset`-based source instead of a whole directory.
`indent` (integer, optional)
: The number of spaces to use for indentation.
Defaults to `2`.
A value of `0` indents with tabs.
### Return value {#tester-shfmt-return}
A derivation that runs `shfmt` on the given script(s), producing an empty output upon success.
The build will fail if `shfmt` reformats anything.
## `testVersion` {#tester-testVersion}
Checks that the output from running a command contains the specified version string in it as a whole word.
NOTE: This is a check you add to `passthru.tests` which is mainly run by OfBorg, but not in Hydra. If you want a version check failure to block the build altogether, then [`versionCheckHook`](#versioncheckhook) is the tool you're looking for (and recommended for quick builds). The motivation for adding either of these checks would be:
- Catch dynamic linking errors and such and missing environment variables that should be added by wrapping.
- Probable protection against accidentally building the wrong version, for example when using an "old" hash in a fixed-output derivation.
By default, the command to be run will be inferred from the given `package` attribute:
it will check `meta.mainProgram` first, and fall back to `pname` or `name`.
The default argument to the command is `--version`, and the version to be checked will be inferred from the given `package` attribute as well.
:::{.example #ex-testversion-hello}
# Check a program version using all the default values
This example will run the command `hello --version`, and then check that the version of the `hello` package is in the output of the command.
```nix
{ passthru.tests.version = testers.testVersion { package = hello; }; }
```
:::
:::{.example #ex-testversion-different-commandversion}
# Check the program version using a specified command and expected version string
This example will run the command `leetcode -V`, and then check that `leetcode 0.4.2` is in the output of the command as a whole word (separated by whitespaces).
This means that an output like "leetcode 0.4.21" would fail the tests, and an output like "You're running leetcode 0.4.2" would pass the tests.
A common usage of the `version` attribute is to specify `version = "v${version}"`.
```nix
{
version = "0.4.2";
passthru.tests.version = testers.testVersion {
package = leetcode-cli;
command = "leetcode -V";
version = "leetcode ${version}";
};
}
```
:::
## `testBuildFailure` {#tester-testBuildFailure}
Make sure that a build does not succeed. This is useful for testing testers.
This returns a derivation with an override on the builder, with the following effects:
- Fail the build when the original builder succeeds
- Move `$out` to `$out/result`, if it exists (assuming `out` is the default output)
- Save the build log to `$out/testBuildFailure.log` (same)
While `testBuildFailure` is designed to keep changes to the original builder's environment to a minimum, some small changes are inevitable:
- The file `$TMPDIR/testBuildFailure.log` is present. It should not be deleted.
- `stdout` and `stderr` are a pipe instead of a tty. This could be improved.
- One or two extra processes are present in the sandbox during the original builder's execution.
- The derivation and output hashes are different, but not unusual.
- The derivation includes a dependency on `buildPackages.bash` and `expect-failure.sh`, which is built to include a transitive dependency on `buildPackages.coreutils` and possibly more.
These are not added to `PATH` or any other environment variable, so they should be hard to observe.
:::{.example #ex-testBuildFailure-showingenvironmentchanges}
# Check that a build fails, and verify the changes made during build
```nix
runCommand "example"
{
failed = testers.testBuildFailure (
runCommand "fail" { } ''
echo ok-ish >$out
echo failing though
exit 3
''
);
}
''
grep -F 'ok-ish' $failed/result
grep -F 'failing though' $failed/testBuildFailure.log
[[ 3 = $(cat $failed/testBuildFailure.exit) ]]
touch $out
''
```
:::
## `testBuildFailure'` {#tester-testBuildFailurePrime}
This tester wraps the functionality provided by [`testers.testBuildFailure`](#tester-testBuildFailure) to make writing checks easier by simplifying checking the exit code of the builder and asserting the existence of entries in the builder's log.
Additionally, users may specify a script containing additional checks, accessing the result of applying `testers.testBuildFailure` through the variable `failed`.
NOTE: This tester will produce an empty output and exit with success if none of the checks fail; there is no need to `touch "$out"` in `script`.
:::{.example #ex-testBuildFailurePrime-doc-example}
# Check that a build fails, and verify the changes made during build
Re-using the example from [`testers.testBuildFailure`](#ex-testBuildFailure-showingenvironmentchanges), we can see how common checks are made easier and remove the need for `runCommand`:
```nix
testers.testBuildFailure' {
drv = runCommand "doc-example" { } ''
echo ok-ish >"$out"
echo failing though
exit 3
'';
expectedBuilderExitCode = 3;
expectedBuilderLogEntries = [ "failing though" ];
script = ''
grep --silent -F 'ok-ish' "$failed/result"
'';
}
```
:::
### Inputs {#tester-testBuildFailurePrime-inputs}
`drv` (derivation)
: The failing derivation to wrap with `testBuildFailure`.
`name` (string, optional)
: The name of the test.
When not provided, this value defaults to `testBuildFailure-${(testers.testBuildFailure drv).name}`.
`expectedBuilderExitCode` (integer, optional)
: The expected exit code of the builder of `drv`.
When not provided, this value defaults to `1`.
`expectedBuilderLogEntries` (array of string-like values, optional)
: A list of string-like values which must be found in the builder's log by exact match.
When not provided, this value defaults to `[ ]`.
NOTE: Patterns and regular expressions are not supported.
`script` (string, optional)
: A string containing additional checks to run.
When not provided, this value defaults to `""`.
The result of `testers.testBuildFailure drv` is available through the variable `failed`.
As an example, the builder's log is at `"$failed/testBuildFailure.log"`.
### Return value {#tester-testBuildFailurePrime-return}
The tester produces an empty output and only succeeds when the checks using `expectedBuilderExitCode`, `expectedBuilderLogEntries`, and `script` succeed.
## `testEqualContents` {#tester-testEqualContents}
Check that two paths have the same contents.
`assertion` (string)
: A message that is printed before the comparison, after `Checking:`.
`expected` (path or value coercible to store path)
: The path to the expected [file system object] content
`actual` (value coercible to store path) <!-- path value is possible, but wrong in practice, but let's not bother readers with our predictions -->
: The path to the actual file system object content to check
`postFailureMessage` (string)
: A message that is printed last if the file system object contents at the two paths don't match exactly.
:::{.example #ex-testEqualContents-toyexample}
# Check that two paths have the same contents
```nix
testers.testEqualContents {
assertion = "sed -e performs replacement";
expected = writeText "expected" ''
foo baz baz
'';
actual =
runCommand "actual"
{
# not really necessary for a package that's in stdenv
nativeBuildInputs = [ gnused ];
base = writeText "base" ''
foo bar baz
'';
}
''
sed -e 's/bar/baz/g' $base >$out
'';
# if applicable
postFailureMessage = ''
The bar-baz replacer produced an unexpected result.
If the new behavior is acceptable and validated against the bar-baz specification, run ./adopt-new-bar-baz-result.sh to adjust this test and require the new behavior.
'';
}
```
:::
## `testEqualArrayOrMap` {#tester-testEqualArrayOrMap}
Check that bash arrays (including associative arrays, referred to as "maps") are populated correctly.
This can be used to ensure setup hooks are registered in a certain order, or to write unit tests for shell functions which transform arrays.
:::{.example #ex-testEqualArrayOrMap-test-function-add-cowbell}
# Test a function which appends a value to an array
```nix
testers.testEqualArrayOrMap {
name = "test-function-add-cowbell";
valuesArray = [
"cowbell"
"cowbell"
];
expectedArray = [
"cowbell"
"cowbell"
"cowbell"
];
script = ''
addCowbell() {
local -rn arrayNameRef="$1"
arrayNameRef+=( "cowbell" )
}
nixLog "appending all values in valuesArray to actualArray"
for value in "''${valuesArray[@]}"; do
actualArray+=( "$value" )
done
nixLog "applying addCowbell"
addCowbell actualArray
'';
}
```
:::
### Inputs {#tester-testEqualArrayOrMap-inputs}
NOTE: Internally, this tester uses `__structuredAttrs` to handle marshalling between Nix expressions and shell variables.
This imposes the restriction that arrays and "maps" have values which are string-like.
NOTE: At least one of `expectedArray` and `expectedMap` must be provided.
`name` (string)
: The name of the test.
`script` (string)
: The singular task of `script` is to populate `actualArray` or `actualMap` (it may populate both).
To do this, `script` may access the following shell variables:
- `valuesArray` (available when `valuesArray` is provided to the tester)
- `valuesMap` (available when `valuesMap` is provided to the tester)
- `actualArray` (available when `expectedArray` is provided to the tester)
- `actualMap` (available when `expectedMap` is provided to the tester)
While both `expectedArray` and `expectedMap` are in scope during the execution of `script`, they *must not* be accessed or modified from within `script`.
`valuesArray` (array of string-like values, optional)
: An array of string-like values.
This array may be used within `script`.
`valuesMap` (attribute set of string-like values, optional)
: An attribute set of string-like values.
This attribute set may be used within `script`.
`expectedArray` (array of string-like values, optional)
: An array of string-like values.
This array *must not* be accessed or modified from within `script`.
When provided, `script` is expected to populate `actualArray`.
`expectedMap` (attribute set of string-like values, optional)
: An attribute set of string-like values.
This attribute set *must not* be accessed or modified from within `script`.
When provided, `script` is expected to populate `actualMap`.
### Return value {#tester-testEqualArrayOrMap-return}
The tester produces an empty output and only succeeds when `expectedArray` and `expectedMap` match `actualArray` and `actualMap`, respectively, when non-null.
The build log will contain differences encountered.
## `testEqualDerivation` {#tester-testEqualDerivation}
Checks that two packages produce the exact same build instructions.
This can be used to make sure that a certain difference of configuration, such as the presence of an overlay does not cause a cache miss.
When the derivations are equal, the return value is an empty file.
Otherwise, the build log explains the difference via `nix-diff`.
:::{.example #ex-testEqualDerivation-hello}
# Check that two packages produce the same derivation
```nix
testers.testEqualDerivation "The hello package must stay the same when enabling checks." hello (
hello.overrideAttrs (o: {
doCheck = true;
})
)
```
:::
## `invalidateFetcherByDrvHash` {#tester-invalidateFetcherByDrvHash}
Use the derivation hash to invalidate the output via name, for testing.
Type: `(a@{ name, ... } -> Derivation) -> a -> Derivation`
Normally, fixed output derivations can and should be cached by their output hash only, but for testing we want to re-fetch everytime the fetcher changes.
Changes to the fetcher become apparent in the drvPath, which is a hash of how to fetch, rather than a fixed store path.
By inserting this hash into the name, we can make sure to re-run the fetcher every time the fetcher changes.
This relies on the assumption that Nix isn't clever enough to reuse its database of local store contents to optimize fetching.
You might notice that the "salted" name derives from the normal invocation, not the final derivation.
`invalidateFetcherByDrvHash` has to invoke the fetcher function twice:
once to get a derivation hash, and again to produce the final fixed output derivation.
:::{.example #ex-invalidateFetcherByDrvHash-nix}
# Prevent nix from reusing the output of a fetcher
```nix
{
tests.fetchgit = testers.invalidateFetcherByDrvHash fetchgit {
name = "nix-source";
url = "https://github.com/NixOS/nix";
rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
hash = "sha256-7DszvbCNTjpzGRmpIVAWXk20P0/XTrWZ79KSOGLrUWY=";
};
}
```
:::
## `runCommand` {#tester-runCommand}
`runCommand :: { name, script, stdenv ? stdenvNoCC, hash ? "...", ... } -> Derivation`
This is a wrapper around `pkgs.runCommandWith`, which
- produces a fixed-output derivation, enabling the command(s) to access the network ;
- salts the derivation's name based on its inputs, ensuring the command is re-run whenever the inputs change.
It accepts the following attributes:
- the derivation's `name` ;
- the `script` to be executed ;
- `stdenv`, the environment to use, defaulting to `stdenvNoCC` ;
- the derivation's output `hash`, defaulting to the empty file's.
The derivation's `outputHashMode` is set by default to recursive, so the `script` can output a directory as well.
All other attributes are passed through to [`mkDerivation`](#sec-using-stdenv),
including `nativeBuildInputs` to specify dependencies available to the `script`.
:::{.example #ex-tester-runCommand-nix}
# Run a command with network access
```nix
testers.runCommand {
name = "access-the-internet";
script = ''
curl -o /dev/null https://example.com
touch $out
'';
nativeBuildInputs = with pkgs; [
cacert
curl
];
}
```
:::
## `runNixOSTest` {#tester-runNixOSTest}
A helper function that behaves exactly like the NixOS `runTest`, except it also assigns this Nixpkgs package set as the `pkgs` of the test and makes the `nixpkgs.*` options read-only.
If your test is part of the Nixpkgs repository, or if you need a more general entrypoint, see ["Calling a test" in the NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-calling-nixos-tests).
:::{.example #ex-runNixOSTest-hello}
# Run a NixOS test using `runNixOSTest`
```nix
pkgs.testers.runNixOSTest (
{ lib, ... }:
{
name = "hello";
nodes.machine =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.hello ];
};
testScript = ''
machine.succeed("hello")
'';
}
)
```
:::
## `nixosTest` {#tester-nixosTest}
Run a NixOS VM network test using this evaluation of Nixpkgs.
NOTE: This function is primarily for external use. NixOS itself uses `make-test-python.nix` directly. Packages defined in Nixpkgs [reuse NixOS tests via `nixosTests`, plural](#ssec-nixos-tests-linking).
It is mostly equivalent to the function `import ./make-test-python.nix` from the [NixOS manual](https://nixos.org/nixos/manual/index.html#sec-nixos-tests), except that the current application of Nixpkgs (`pkgs`) will be used, instead of letting NixOS invoke Nixpkgs anew.
If a test machine needs to set NixOS options under `nixpkgs`, it must set only the `nixpkgs.pkgs` option.
### Parameter {#tester-nixosTest-parameter}
A [NixOS VM test network](https://nixos.org/nixos/manual/index.html#sec-nixos-tests), or path to it. Example:
```nix
{
name = "my-test";
nodes = {
machine1 =
{
lib,
pkgs,
nodes,
...
}:
{
environment.systemPackages = [ pkgs.hello ];
services.foo.enable = true;
};
# machine2 = ...;
};
testScript = ''
start_all()
machine1.wait_for_unit("foo.service")
machine1.succeed("hello | foo-send")
'';
}
```
### Result {#tester-nixosTest-result}
A derivation that runs the VM test.
Notable attributes:
* `nodes`: the evaluated NixOS configurations. Useful for debugging and exploring the configuration.
* `driverInteractive`: a script that launches an interactive Python session in the context of the `testScript`.
[file system object]: https://nix.dev/manual/nix/latest/store/file-system-object

View File

@@ -0,0 +1,830 @@
# Trivial build helpers {#chap-trivial-builders}
Nixpkgs provides a variety of wrapper functions that help build commonly useful derivations.
Like [`stdenv.mkDerivation`](#sec-using-stdenv), each of these build helpers creates a derivation, but the arguments passed are different (usually simpler) from those required by `stdenv.mkDerivation`.
## `runCommandWith` {#trivial-builder-runCommandWith}
The function `runCommandWith` returns a derivation built using the specified command(s), in a specified environment.
It is the underlying base function of all [`runCommand*` variants].
The general behavior is controlled via a single attribute set passed
as the first argument, and allows specifying `stdenv` freely.
The following [`runCommand*` variants] exist: `runCommand`, `runCommandCC`, and `runCommandLocal`.
[`runCommand*` variants]: #trivial-builder-runCommand
### Type {#trivial-builder-runCommandWith-Type}
```
runCommandWith :: {
name :: name;
stdenv? :: Derivation;
runLocal? :: Bool;
derivationArgs? :: { ... };
} -> String -> Derivation
```
### Inputs {#trivial-builder-runCommandWith-Inputs}
`name` (String)
: The derivation's name, which Nix will append to the store path; see [`mkDerivation`](#sec-using-stdenv).
`runLocal` (Boolean)
: If set to `true` this forces the derivation to be built locally, not using [substitutes] nor remote builds.
This is intended for very cheap commands (<1s execution time) which can be sped up by avoiding the network round-trip(s).
Its effect is to set [`preferLocalBuild = true`][preferLocalBuild] and [`allowSubstitutes = false`][allowSubstitutes].
::: {.note}
This prevents the use of [substituters][substituter], so only set `runLocal` (or use `runCommandLocal`) when certain the user will
always have a builder for the `system` of the derivation. This should be true for most trivial use cases
(e.g., just copying some files to a different location or adding symlinks) because there the `system`
is usually the same as `builtins.currentSystem`.
:::
`stdenv` (Derivation)
: The [standard environment](#chap-stdenv) to use, defaulting to `pkgs.stdenv`
`derivationArgs` (Attribute set)
: Additional arguments for [`mkDerivation`](#sec-using-stdenv).
`buildCommand` (String)
: Shell commands to run in the derivation builder.
::: {.note}
You have to create a file or directory `$out` for Nix to be able to run the builder successfully.
:::
[allowSubstitutes]: https://nix.dev/manual/nix/latest/language/advanced-attributes.html#adv-attr-allowSubstitutes
[preferLocalBuild]: https://nix.dev/manual/nix/latest/language/advanced-attributes.html#adv-attr-preferLocalBuild
[substituter]: https://nix.dev/manual/nix/latest/glossary#gloss-substituter
[substitutes]: https://nix.dev/manual/nix/latest/glossary#gloss-substitute
::: {.example #ex-runcommandwith}
# Invocation of `runCommandWith`
```nix
runCommandWith
{
name = "example";
derivationArgs.nativeBuildInputs = [ cowsay ];
}
''
cowsay > $out <<EOMOO
'runCommandWith' is a bit cumbersome,
so we have more ergonomic wrappers.
EOMOO
''
```
:::
## `runCommand` and `runCommandCC` {#trivial-builder-runCommand}
The function `runCommand` returns a derivation built using the specified command(s), in the `stdenvNoCC` environment.
`runCommandCC` is similar but uses the default compiler environment. To minimize dependencies, `runCommandCC`
should only be used when the build command needs a C compiler.
`runCommandLocal` is also similar to `runCommand`, but forces the derivation to be built locally.
See the note on [`runCommandWith`] about `runLocal`.
[`runCommandWith`]: #trivial-builder-runCommandWith
### Type {#trivial-builder-runCommand-Type}
```
runCommand :: String -> AttrSet -> String -> Derivation
runCommandCC :: String -> AttrSet -> String -> Derivation
runCommandLocal :: String -> AttrSet -> String -> Derivation
```
### Input {#trivial-builder-runCommand-Input}
While the type signature(s) differ from [`runCommandWith`], individual arguments with the same name will have the same type and meaning:
`name` (String)
: The derivation's name
`derivationArgs` (Attribute set)
: Additional parameters passed to [`mkDerivation`]
`buildCommand` (String)
: The command(s) run to build the derivation.
::: {.example #ex-runcommand-simple}
# Invocation of `runCommand`
```nix
runCommand "my-example" { } ''
echo My example command is running
mkdir $out
echo I can write data to the Nix store > $out/message
echo I can also run basic commands like:
echo ls
ls
echo whoami
whoami
echo date
date
''
```
:::
::: {.note}
`runCommand name derivationArgs buildCommand` is equivalent to
```nix
runCommandWith {
inherit name derivationArgs;
stdenv = stdenvNoCC;
} buildCommand
```
Likewise, `runCommandCC name derivationArgs buildCommand` is equivalent to
```nix
runCommandWith { inherit name derivationArgs; } buildCommand
```
:::
## Writing text files {#trivial-builder-text-writing}
Nixpkgs provides the following functions for producing derivations which write text files or executable scripts into the Nix store.
They are useful for creating files from Nix expression, and are all implemented as convenience wrappers around `writeTextFile`.
Each of these functions will cause a derivation to be produced.
When you coerce the result of each of these functions to a string with [string interpolation](https://nixos.org/manual/nix/stable/language/string-interpolation) or [`toString`](https://nixos.org/manual/nix/stable/language/builtins#builtins-toString), it will evaluate to the [store path](https://nixos.org/manual/nix/stable/store/store-path) of this derivation.
:::: {.note}
Some of these functions will put the resulting files within a directory inside the [derivation output](https://nixos.org/manual/nix/stable/language/derivations#attr-outputs).
If you need to refer to the resulting files somewhere else in a Nix expression, append their path to the derivation's store path.
For example, if the file destination is a directory:
```nix
{
my-file = writeTextFile {
name = "my-file";
text = ''
Contents of File
'';
destination = "/share/my-file";
};
}
```
Remember to append "/share/my-file" to the resulting store path when using it elsewhere:
```nix
writeShellScript "evaluate-my-file.sh" ''
cat ${my-file}/share/my-file
''
```
::::
### `makeDesktopItem` {#trivial-builder-makeDesktopItem}
Write an [XDG desktop file](https://specifications.freedesktop.org/desktop-entry-spec/1.4/) to the Nix store.
This function is usually used to add desktop items to a package through the `copyDesktopItems` hook.
`makeDesktopItem` adheres to version 1.4 of the specification.
#### Inputs {#trivial-builder-makeDesktopItem-inputs}
`makeDesktopItem` takes an attribute set that accepts most values from the [XDG specification](https://specifications.freedesktop.org/desktop-entry-spec/1.4/ar01s06.html).
All recognised keys from the specification are supported with the exception of the "Hidden" field. The keys are converted into camelCase format, but correspond 1:1 to their equivalent in the specification: `genericName`, `noDisplay`, `comment`, `icon`, `onlyShowIn`, `notShowIn`, `dbusActivatable`, `tryExec`, `exec`, `path`, `terminal`, `mimeTypes`, `categories`, `implements`, `keywords`, `startupNotify`, `startupWMClass`, `url`, `prefersNonDefaultGPU`.
The "Version" field is hardcoded to the version `makeDesktopItem` currently adheres to.
The following fields are either required, are of a different type than in the specification, carry specific default values, or are additional fields supported by `makeDesktopItem`:
`name` (String)
: The name of the desktop file in the Nix store.
`type` (String; _optional_)
: Default value: `"Application"`
`desktopName` (String)
: Corresponds to the "Name" field of the specification.
`actions` (List of Attribute set; _optional_)
: A list of attribute sets {name, exec?, icon?}
`extraConfig` (Attribute set; _optional_)
: Additional key/value pairs to be added verbatim to the desktop file. Attributes need to be prefixed with 'X-'.
#### Examples {#trivial-builder-makeDesktopItem-examples}
::: {.example #ex-makeDesktopItem}
# Usage 1 of `makeDesktopItem`
Write a desktop file `/nix/store/<store path>/my-program.desktop` to the Nix store.
```nix
{ makeDesktopItem }:
makeDesktopItem {
name = "my-program";
desktopName = "My Program";
genericName = "Video Player";
noDisplay = false;
comment = "Cool video player";
icon = "/path/to/icon";
onlyShowIn = [ "KDE" ];
dbusActivatable = true;
tryExec = "my-program";
exec = "my-program --someflag";
path = "/some/working/path";
terminal = false;
actions.example = {
name = "New Window";
exec = "my-program --new-window";
icon = "/some/icon";
};
mimeTypes = [ "video/mp4" ];
categories = [ "Utility" ];
implements = [ "org.my-program" ];
keywords = [
"Video"
"Player"
];
startupNotify = false;
startupWMClass = "MyProgram";
prefersNonDefaultGPU = false;
extraConfig.X-SomeExtension = "somevalue";
}
```
:::
::: {.example #ex2-makeDesktopItem}
# Usage 2 of `makeDesktopItem`
Override the `hello` package to add a desktop item.
```nix
{
copyDesktopItems,
hello,
makeDesktopItem,
}:
hello.overrideAttrs {
nativeBuildInputs = [ copyDesktopItems ];
desktopItems = [
(makeDesktopItem {
name = "hello";
desktopName = "Hello";
exec = "hello";
})
];
}
```
:::
### `writeTextFile` {#trivial-builder-writeTextFile}
Write a text file to the Nix store.
`writeTextFile` takes an attribute set with the following possible attributes:
`name` (String)
: Corresponds to the name used in the Nix store path identifier.
`text` (String)
: The contents of the file.
`executable` (Bool, _optional_)
: Make this file have the executable bit set.
Default: `false`
`destination` (String, _optional_)
: A subpath under the derivation's output path into which to put the file.
Subdirectories are created automatically when the derivation is realised.
By default, the store path itself will be a file containing the text contents.
Default: `""`
`checkPhase` (String, _optional_)
: Commands to run after generating the file.
Default: `""`
`meta` (Attribute set, _optional_)
: Additional metadata for the derivation.
Default: `{}`
`allowSubstitutes` (Bool, _optional_)
: Whether to allow substituting from a binary cache.
Passed through to [`allowSubstitutes`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-allowSubstitutes) of the underlying call to `derivation`.
It defaults to `false`, as running the derivation's simple `builder` executable locally is assumed to be faster than network operations.
Set it to true if the `checkPhase` step is expensive.
Default: `false`
`preferLocalBuild` (Bool, _optional_)
: Whether to prefer building locally, even if faster [remote build machines](https://nixos.org/manual/nix/stable/command-ref/conf-file#conf-substituters) are available.
Passed through to [`preferLocalBuild`](https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-preferLocalBuild) of the underlying call to `derivation`.
It defaults to `true` for the same reason `allowSubstitutes` defaults to `false`.
Default: `true`
`derivationArgs` (Attribute set, _optional_)
: Extra arguments to pass to the underlying call to `stdenv.mkDerivation`.
Default: `{}`
The resulting store path will include some variation of the name, and it will be a file unless `destination` is used, in which case it will be a directory.
::: {.example #ex-writeTextFile}
# Usage 1 of `writeTextFile`
Write `my-file` to `/nix/store/<store path>/some/subpath/my-cool-script`, making it executable.
Also run a check on the resulting file in a `checkPhase`, and supply values for the less-used options.
```nix
writeTextFile {
name = "my-cool-script";
text = ''
#!/bin/sh
echo "This is my cool script!"
'';
executable = true;
destination = "/some/subpath/my-cool-script";
checkPhase = ''
${pkgs.shellcheck}/bin/shellcheck $out/some/subpath/my-cool-script
'';
meta = {
license = pkgs.lib.licenses.cc0;
};
allowSubstitutes = true;
preferLocalBuild = false;
}
```
:::
::: {.example #ex2-writeTextFile}
# Usage 2 of `writeTextFile`
Write the string `Contents of File` to `/nix/store/<store path>`.
See also the [](#trivial-builder-writeText) helper function.
```nix
writeTextFile {
name = "my-file";
text = ''
Contents of File
'';
}
```
:::
::: {.example #ex3-writeTextFile}
# Usage 3 of `writeTextFile`
Write an executable script `my-script` to `/nix/store/<store path>/bin/my-script`.
See also the [](#trivial-builder-writeScriptBin) helper function.
```nix
writeTextFile {
name = "my-script";
text = ''
echo "hi"
'';
executable = true;
destination = "/bin/my-script";
}
```
:::
### `writeText` {#trivial-builder-writeText}
Write a text file to the Nix store
`writeText` takes the following arguments:
a string.
`name` (String)
: The name used in the Nix store path.
`text` (String)
: The contents of the file.
The store path will include the name, and it will be a file.
::: {.example #ex-writeText}
# Usage of `writeText`
Write the string `Contents of File` to `/nix/store/<store path>`:
```nix
writeText "my-file" ''
Contents of File
''
```
:::
This is equivalent to:
```nix
writeTextFile {
name = "my-file";
text = ''
Contents of File
'';
}
```
### `writeTextDir` {#trivial-builder-writeTextDir}
Write a text file within a subdirectory of the Nix store.
`writeTextDir` takes the following arguments:
`path` (String)
: The destination within the Nix store path under which to create the file.
`text` (String)
: The contents of the file.
The store path will be a directory.
::: {.example #ex-writeTextDir}
# Usage of `writeTextDir`
Write the string `Contents of File` to `/nix/store/<store path>/share/my-file`:
```nix
writeTextDir "share/my-file" ''
Contents of File
''
```
:::
This is equivalent to:
```nix
writeTextFile {
name = "my-file";
text = ''
Contents of File
'';
destination = "/share/my-file";
}
```
### `writeScript` {#trivial-builder-writeScript}
Write an executable script file to the Nix store.
`writeScript` takes the following arguments:
`name` (String)
: The name used in the Nix store path.
`text` (String)
: The contents of the file.
The created file is marked as executable.
The store path will include the name, and it will be a file.
::: {.example #ex-writeScript}
# Usage of `writeScript`
Write the string `Contents of File` to `/nix/store/<store path>` and make the file executable.
```nix
writeScript "my-file" ''
Contents of File
''
```
This is equivalent to:
```nix
writeTextFile {
name = "my-file";
text = ''
Contents of File
'';
executable = true;
}
```
:::
### `writeScriptBin` {#trivial-builder-writeScriptBin}
Write a script within a `bin` subdirectory of a directory in the Nix store.
This is for consistency with the convention of software packages placing executables under `bin`.
`writeScriptBin` takes the following arguments:
`name` (String)
: The name used in the Nix store path and within the file created under the store path.
`text` (String)
: The contents of the file.
The created file is marked as executable.
The file's contents will be put into `/nix/store/<store path>/bin/<name>`.
The store path will include the name, and it will be a directory.
::: {.example #ex-writeScriptBin}
# Usage of `writeScriptBin`
```nix
writeScriptBin "my-script" ''
echo "hi"
''
```
:::
This is equivalent to:
```nix
writeTextFile {
name = "my-script";
text = ''
echo "hi"
'';
executable = true;
destination = "/bin/my-script";
}
```
### `writeShellScript` {#trivial-builder-writeShellScript}
Write a Bash script to the store.
`writeShellScript` takes the following arguments:
`name` (String)
: The name used in the Nix store path.
`text` (String)
: The contents of the file.
The created file is marked as executable.
The store path will include the name, and it will be a file.
This function is almost exactly like [](#trivial-builder-writeScript), except that it prepends to the file a [shebang](https://en.wikipedia.org/wiki/Shebang_%28Unix%29) line that points to the version of Bash used in Nixpkgs.
<!-- this cannot be changed in practice, so there is no point pretending it's somehow generic -->
::: {.example #ex-writeShellScript}
# Usage of `writeShellScript`
```nix
writeShellScript "my-script" ''
echo "hi"
''
```
:::
This is equivalent to:
```nix
writeTextFile {
name = "my-script";
text = ''
#! ${pkgs.runtimeShell}
echo "hi"
'';
executable = true;
}
```
### `writeShellScriptBin` {#trivial-builder-writeShellScriptBin}
Write a Bash script to a "bin" subdirectory of a directory in the Nix store.
`writeShellScriptBin` takes the following arguments:
`name` (String)
: The name used in the Nix store path and within the file generated under the store path.
`text` (String)
: The contents of the file.
The file's contents will be put into `/nix/store/<store path>/bin/<name>`.
The store path will include the name, and it will be a directory.
This function is a combination of [](#trivial-builder-writeShellScript) and [](#trivial-builder-writeScriptBin).
::: {.example #ex-writeShellScriptBin}
# Usage of `writeShellScriptBin`
```nix
writeShellScriptBin "my-script" ''
echo "hi"
''
```
:::
This is equivalent to:
```nix
writeTextFile {
name = "my-script";
text = ''
#! ${pkgs.runtimeShell}
echo "hi"
'';
executable = true;
destination = "/bin/my-script";
}
```
## `concatTextFile`, `concatText`, `concatScript` {#trivial-builder-concatText}
These functions concatenate `files` to the Nix store in a single file. This is useful for configuration files structured in lines of text. `concatTextFile` takes an attribute set and expects two arguments, `name` and `files`. `name` corresponds to the name used in the Nix store path. `files` will be the files to be concatenated. You can also set `executable` to true to make this file have the executable bit set.
`concatText` and`concatScript` are simple wrappers over `concatTextFile`.
Here are a few examples:
```nix
# Writes my-file to /nix/store/<store path>
concatTextFile
{
name = "my-file";
files = [
drv1
"${drv2}/path/to/file"
];
}
# See also the `concatText` helper function below.
# Writes executable my-file to /nix/store/<store path>/bin/my-file
concatTextFile
{
name = "my-file";
files = [
drv1
"${drv2}/path/to/file"
];
executable = true;
destination = "/bin/my-file";
}
# Writes contents of files to /nix/store/<store path>
concatText
"my-file"
[
file1
file2
]
# Writes contents of files to /nix/store/<store path>
concatScript
"my-file"
[
file1
file2
]
```
## `writeShellApplication` {#trivial-builder-writeShellApplication}
`writeShellApplication` is similar to `writeShellScriptBin` and `writeScriptBin` but supports runtime dependencies with `runtimeInputs`.
Writes an executable shell script to `/nix/store/<store path>/bin/<name>` and checks its syntax with [`shellcheck`](https://github.com/koalaman/shellcheck) and the `bash`'s `-n` option.
Some basic Bash options are set by default (`errexit`, `nounset`, and `pipefail`), but can be overridden with `bashOptions`.
Extra arguments may be passed to `stdenv.mkDerivation` by setting `derivationArgs`; note that variables set in this manner will be set when the shell script is _built,_ not when it's run.
Runtime environment variables can be set with the `runtimeEnv` argument.
For example, the following shell application can refer to `curl` directly, rather than needing to write `${curl}/bin/curl`:
```nix
writeShellApplication {
name = "show-nixos-org";
runtimeInputs = [
curl
w3m
];
text = ''
curl -s 'https://nixos.org' | w3m -dump -T text/html
'';
}
```
## `symlinkJoin` {#trivial-builder-symlinkJoin}
This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, `name`, and `paths`. `name` (or alternatively `pname` and `version`) is the name used in the Nix store path for the created derivation. `paths` is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within.
Here is an example:
```nix
# adds symlinks of hello and stack to current build and prints "links added"
symlinkJoin {
name = "myexample";
paths = [
pkgs.hello
pkgs.stack
];
postBuild = "echo links added";
}
```
This creates a derivation with a directory structure like the following:
```
/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample
|-- bin
| |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello
| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack
`-- share
|-- bash-completion
| `-- completions
| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack
|-- fish
| `-- vendor_completions.d
| `-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish
...
```
## `writeClosure` {#trivial-builder-writeClosure}
Given a list of [store paths](https://nixos.org/manual/nix/stable/glossary#gloss-store-path) (or string-like expressions coercible to store paths), write their collective [closure](https://nixos.org/manual/nix/stable/glossary#gloss-closure) to a text file.
The result is equivalent to the output of `nix-store -q --requisites`.
For example,
```nix
writeClosure [ (writeScriptBin "hi" "${hello}/bin/hello") ]
```
produces an output path `/nix/store/<hash>-runtime-deps` containing
```
/nix/store/<hash>-hello-2.10
/nix/store/<hash>-hi
/nix/store/<hash>-libidn2-2.3.0
/nix/store/<hash>-libunistring-0.9.10
/nix/store/<hash>-glibc-2.32-40
```
You can see that this includes `hi`, the original input path,
`hello`, which is a direct reference, but also
the other paths that are indirectly required to run `hello`.
## `writeDirectReferencesToFile` {#trivial-builder-writeDirectReferencesToFile}
Writes the set of references to the output file, that is, their immediate dependencies.
This produces the equivalent of `nix-store -q --references`.
For example,
```nix
writeDirectReferencesToFile (writeScriptBin "hi" "${hello}/bin/hello")
```
produces an output path `/nix/store/<hash>-runtime-references` containing
```
/nix/store/<hash>-hello-2.10
```
but none of `hello`'s dependencies because those are not referenced directly
by `hi`'s output.

10
doc/contributing.md Normal file
View File

@@ -0,0 +1,10 @@
# Contributing to Nixpkgs {#part-contributing}
```{=include=} chapters
contributing/quick-start.chapter.md
contributing/coding-conventions.chapter.md
contributing/submitting-changes.chapter.md
contributing/vulnerability-roundup.chapter.md
contributing/reviewing-contributions.chapter.md
contributing/contributing-to-documentation.chapter.md
```

View File

@@ -0,0 +1,63 @@
# Coding conventions {#chap-conventions}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Syntax {#sec-syntax}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Package naming {#sec-package-naming}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## File naming and organisation {#sec-organisation}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Versioning {#sec-versioning}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Fetching Sources {#sec-sources}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Obtaining source hash {#sec-source-hashes}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Obtaining hashes securely {#sec-source-hashes-security}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Patches {#sec-patches}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Package tests {#sec-package-tests}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Writing inline package tests {#ssec-inline-package-tests-writing}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Writing larger package tests {#ssec-package-tests-writing}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Running package tests {#ssec-package-tests-running}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Examples of package tests {#ssec-package-tests-examples}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Linking NixOS module tests to a package {#ssec-nixos-tests-linking}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Import From Derivation {#ssec-import-from-derivation}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).

View File

@@ -0,0 +1,11 @@
# Contributing to Nixpkgs documentation {#chap-contributing}
This section has been moved to [doc/README.md](https://github.com/NixOS/nixpkgs/blob/master/doc/README.md).
## devmode {#sec-contributing-devmode}
This section has been moved to [doc/README.md](https://github.com/NixOS/nixpkgs/blob/master/doc/README.md).
## Syntax {#sec-contributing-markup}
This section has been moved to [doc/README.md](https://github.com/NixOS/nixpkgs/blob/master/doc/README.md).

View File

@@ -0,0 +1,3 @@
# Quick Start to Adding a Package {#chap-quick-start}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).

View File

@@ -0,0 +1,35 @@
# Reviewing contributions {#chap-reviewing-contributions}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Package updates {#reviewing-contributions-package-updates}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## New packages {#reviewing-contributions-new-packages}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Module updates {#reviewing-contributions-module-updates}
This section has been moved to [nixos/README.md](https://github.com/NixOS/nixpkgs/blob/master/nixos/README.md).
## New modules {#reviewing-contributions-new-modules}
This section has been moved to [nixos/README.md](https://github.com/NixOS/nixpkgs/blob/master/nixos/README.md#new-modules).
## Individual maintainer list {#reviewing-contributions-individual-maintainer-list}
This section has been moved to [maintainers/README.md](https://github.com/NixOS/nixpkgs/blob/master/maintainers/README.md).
## Maintainer teams {#reviewing-contributions-maintainer-teams}
This section has been moved to [maintainers/README.md](https://github.com/NixOS/nixpkgs/blob/master/maintainers/README.md).
## Other submissions {#reviewing-contributions-other-submissions}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Merging pull requests {#reviewing-contributions--merging-pull-requests}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).

View File

@@ -0,0 +1,88 @@
# Submitting changes {#chap-submitting-changes}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Submitting changes {#submitting-changes-submitting-changes}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Submitting security fixes {#submitting-changes-submitting-security-fixes}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Deprecating/removing packages {#submitting-changes-deprecating-packages}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
### Steps to remove a package from Nixpkgs {#steps-to-remove-a-package-from-nixpkgs}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Pull Request Template {#submitting-changes-pull-request-template}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Tested using sandboxing {#submitting-changes-tested-with-sandbox}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Built on platform(s) {#submitting-changes-platform-diversity}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests) {#submitting-changes-nixos-tests}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Tested compilation of all pkgs that depend on this change using `nixpkgs-review` {#submitting-changes-tested-compilation}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Tested execution of all binary files (usually in `./result/bin/`) {#submitting-changes-tested-execution}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Meets Nixpkgs contribution standards {#submitting-changes-contribution-standards}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Hotfixing pull requests {#submitting-changes-hotfixing-pull-requests}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
## Commit policy {#submitting-changes-commit-policy}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
### Branches {#submitting-changes-branches}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Master branch {#submitting-changes-master-branch}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Staging branch {#submitting-changes-staging-branch}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Staging-next branch {#submitting-changes-staging-next-branch}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Stable release branches {#submitting-changes-stable-release-branches}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Automatically backporting a Pull Request {#submitting-changes-stable-release-branches-automatic-backports}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Manually backporting changes {#submitting-changes-stable-release-branches-manual-backports}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
#### Acceptable backport criteria {#acceptable-backport-criteria}
This section has been moved to [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).

View File

@@ -0,0 +1,11 @@
# Vulnerability Roundup {#chap-vulnerability-roundup}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Issues {#vulnerability-roundup-issues}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).
## Triaging and Fixing {#vulnerability-roundup-triaging-and-fixing}
This section has been moved to [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md).

6
doc/default.nix Normal file
View File

@@ -0,0 +1,6 @@
{
pkgs ? (import ../ci { }).pkgs,
nixpkgs ? { },
}:
pkgs.callPackage ./doc-support/package.nix { inherit nixpkgs; }

10
doc/development.md Normal file
View File

@@ -0,0 +1,10 @@
# Development of Nixpkgs {#part-development}
This section shows you how Nixpkgs is developed and how you can interact with the contributors and the latest updates.
If you are interested in contributing yourself, see [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
<!-- In the future this section should also include: How to test pull requests, how to know if pull requests are available in channels, etc. -->
```{=include=} chapters
development/opening-issues.chapter.md
```

View File

@@ -0,0 +1,7 @@
# Opening issues {#sec-opening-issues}
* Make sure you have a [GitHub account](https://github.com/signup/free)
* Make sure there is no open issue on the topic
* [Submit a new issue](https://github.com/NixOS/nixpkgs/issues/new/choose) by choosing the kind of topic and fill out the template
<!-- In the future this section could also include more detailed information on the issue templates -->

54
doc/doc-support/epub.nix Normal file
View File

@@ -0,0 +1,54 @@
# To build this derivation, run `nix-build -A nixpkgs-manual.epub`
{
lib,
runCommand,
docbook_xsl_ns,
libxslt,
zip,
}:
runCommand "manual.epub"
{
nativeBuildInputs = [
libxslt
zip
];
epub = ''
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="5.0"
xml:id="nixpkgs-manual">
<info>
<title>Nixpkgs Manual</title>
<subtitle>Version ${lib.version}</subtitle>
</info>
<chapter>
<title>Temporarily unavailable</title>
<para>
The Nixpkgs manual is currently not available in EPUB format,
please use the <link xlink:href="https://nixos.org/nixpkgs/manual">HTML manual</link>
instead.
</para>
<para>
If you've used the EPUB manual in the past and it has been useful to you, please
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/237234">let us know</link>.
</para>
</chapter>
</book>
'';
passAsFile = [ "epub" ];
}
''
mkdir scratch
xsltproc \
--param chapter.autolabel 0 \
--nonet \
--output scratch/ \
${docbook_xsl_ns}/xml/xsl/docbook/epub/docbook.xsl \
$epubPath
echo "application/epub+zip" > mimetype
zip -0Xq -b "$TMPDIR" "$out" mimetype
cd scratch && zip -Xr9D -b "$TMPDIR" "$out" *
''

View File

@@ -0,0 +1,151 @@
# Generates the documentation for library functions via nixdoc.
# To build this derivation, run `nix-build -A nixpkgs-manual.lib-docs`
{
lib,
stdenvNoCC,
nixdoc,
nix,
nixpkgs ? { },
libsets ? [
{
name = "asserts";
description = "assertion functions";
}
{
name = "attrsets";
description = "attribute set functions";
}
{
name = "strings";
description = "string manipulation functions";
}
{
name = "versions";
description = "version string functions";
}
{
name = "trivial";
description = "miscellaneous functions";
}
{
name = "fixedPoints";
baseName = "fixed-points";
description = "explicit recursion functions";
}
{
name = "lists";
description = "list manipulation functions";
}
{
name = "debug";
description = "debugging functions";
}
{
name = "options";
description = "NixOS / nixpkgs option handling";
}
{
name = "path";
description = "path functions";
}
{
name = "fetchers";
description = "functions which can be reused across fetchers";
}
{
name = "filesystem";
description = "filesystem functions";
}
{
name = "fileset";
description = "file set functions";
}
{
name = "sources";
description = "source filtering functions";
}
{
name = "cli";
description = "command-line serialization functions";
}
{
name = "generators";
description = "functions that create file formats from nix data structures";
}
{
name = "gvariant";
description = "GVariant formatted string serialization functions";
}
{
name = "customisation";
description = "Functions to customise (derivation-related) functions, derivations, or attribute sets";
}
{
name = "meta";
description = "functions for derivation metadata";
}
{
name = "derivations";
description = "miscellaneous derivation-specific functions";
}
],
}:
stdenvNoCC.mkDerivation {
name = "nixpkgs-lib-docs";
src = ../../lib;
nativeBuildInputs = [
nixdoc
nix
];
installPhase = ''
runHook preInstall
cd ..
export NIX_STATE_DIR=$(mktemp -d)
nix-instantiate --eval --strict --json ${./lib-function-locations.nix} \
--arg nixpkgsPath "./." \
--argstr revision ${nixpkgs.rev or "master"} \
--argstr libsetsJSON ${lib.escapeShellArg (builtins.toJSON libsets)} \
--store $(mktemp -d) \
> locations.json
function docgen {
name=$1
baseName=$2
description=$3
# TODO: wrap lib.$name in <literal>, make nixdoc not escape it
if [[ -e "lib/$baseName.nix" ]]; then
nixdoc -c "$name" -d "lib.$name: $description" -l locations.json -f "lib/$baseName.nix" > "$out/$name.md"
else
nixdoc -c "$name" -d "lib.$name: $description" -l locations.json -f "lib/$baseName/default.nix" > "$out/$name.md"
fi
echo "$out/$name.md" >> "$out/index.md"
}
mkdir -p "$out"
cat > "$out/index.md" << 'EOF'
```{=include=} sections auto-id-prefix=auto-generated
EOF
${lib.concatMapStrings (
{
name,
baseName ? name,
description,
}:
''
docgen ${name} ${baseName} ${lib.escapeShellArg description}
''
) libsets}
echo '```' >> "$out/index.md"
runHook postInstall
'';
}

View File

@@ -0,0 +1,82 @@
{
nixpkgsPath,
revision,
libsetsJSON,
}:
let
lib = import (nixpkgsPath + "/lib");
libsets = builtins.fromJSON libsetsJSON;
libDefPos =
prefix: set:
builtins.concatMap (
name:
[
{
name = builtins.concatStringsSep "." (prefix ++ [ name ]);
location = builtins.unsafeGetAttrPos name set;
}
]
++ lib.optionals (builtins.length prefix == 0 && builtins.isAttrs set.${name}) (
libDefPos (prefix ++ [ name ]) set.${name}
)
) (builtins.attrNames set);
libset =
toplib:
map (subsetname: {
subsetname = subsetname;
functions = libDefPos [ ] toplib.${subsetname};
}) (map (x: x.name) libsets);
flattenedLibSubset =
{ subsetname, functions }:
map (fn: {
name = "lib.${subsetname}.${fn.name}";
value = fn.location;
}) functions;
locatedlibsets = libs: map flattenedLibSubset (libset libs);
removeFilenamePrefix =
prefix: filename:
let
prefixLen = (builtins.stringLength prefix) + 1; # +1 to remove the leading /
filenameLen = builtins.stringLength filename;
substr = builtins.substring prefixLen filenameLen filename;
in
substr;
removeNixpkgs = removeFilenamePrefix (toString nixpkgsPath);
liblocations = builtins.filter (elem: elem.value != null) (lib.lists.flatten (locatedlibsets lib));
fnLocationRelative =
{ name, value }:
{
inherit name;
value = value // {
file = removeNixpkgs value.file;
};
};
relativeLocs = (map fnLocationRelative liblocations);
sanitizeId = builtins.replaceStrings [ "'" ] [ "-prime" ];
urlPrefix = "https://github.com/NixOS/nixpkgs/blob/${revision}";
jsonLocs = builtins.listToAttrs (
map (
{ name, value }:
{
name = sanitizeId name;
value =
let
text = "${value.file}:${toString value.line}";
target = "${urlPrefix}/${value.file}#L${toString value.line}";
in
"[${text}](${target}) in `<nixpkgs>`";
}
) relativeLocs
);
in
jsonLocs

View File

@@ -0,0 +1,28 @@
# To build this derivation, run `nix-build -A nixpkgs-manual.optionsDoc`
{ lib, nixosOptionsDoc }:
let
modules = lib.evalModules {
modules = [ ../../pkgs/top-level/config.nix ];
class = "nixpkgsConfig";
};
root = toString ../..;
transformDeclaration =
decl:
let
declStr = toString decl;
subpath = lib.removePrefix "/" (lib.removePrefix root declStr);
in
assert lib.hasPrefix root declStr;
{
url = "https://github.com/NixOS/nixpkgs/blob/master/${subpath}";
name = subpath;
};
in
nixosOptionsDoc {
inherit (modules) options;
documentType = "none";
transformOptions = opt: opt // { declarations = map transformDeclaration opt.declarations; };
}

175
doc/doc-support/package.nix Normal file
View File

@@ -0,0 +1,175 @@
# This file describes the Nixpkgs manual, which happens to use module docs infra originally
# developed for NixOS. To build this derivation, run `nix-build -A nixpkgs-manual`.
#
{
lib,
stdenvNoCC,
callPackage,
devmode,
mkShellNoCC,
documentation-highlighter,
nixos-render-docs,
nixos-render-docs-redirects,
writeShellScriptBin,
nixpkgs ? { },
markdown-code-runner,
roboto,
treefmt,
nixosOptionsDoc,
}:
stdenvNoCC.mkDerivation (
finalAttrs:
let
inherit (finalAttrs.finalPackage.optionsDoc) optionsJSON;
inherit (finalAttrs.finalPackage) epub lib-docs pythonInterpreterTable;
# Make anything from lib (the module system internals) invisible
hide-lib =
opt:
opt
// {
visible = if lib.all (decl: decl == "lib/modules.nix") opt.declarations then false else opt.visible;
};
toURL =
decl:
let
declStr = toString decl;
root = toString ../..;
subpath = lib.removePrefix "/" (lib.removePrefix root declStr);
in
if lib.hasPrefix root declStr then
{
url = "https://github.com/NixOS/nixpkgs/blob/master/${subpath}";
name = "nixpkgs/${subpath}";
}
else
decl;
mapURLs = opt: opt // { declarations = map toURL opt.declarations; };
docs.generic.meta-maintainers = nixosOptionsDoc {
inherit (lib.evalModules { modules = [ ../../modules/generic/meta-maintainers.nix ]; }) options;
transformOptions = opt: hide-lib (mapURLs opt);
};
in
{
name = "nixpkgs-manual";
nativeBuildInputs = [ nixos-render-docs ];
src = lib.cleanSourceWith {
src = ../.;
filter =
path: type:
type == "directory"
|| lib.hasSuffix ".md" path
|| lib.hasSuffix ".md.in" path
|| lib.elem path (
map toString [
../style.css
../anchor-use.js
../anchor.min.js
../manpage-urls.json
../redirects.json
]
);
};
postPatch = ''
ln -s ${optionsJSON}/share/doc/nixos/options.json ./config-options.json
ln -s ${treefmt.functionsDoc.markdown} ./packages/treefmt-functions.section.md
ln -s ${treefmt.optionsDoc.optionsJSON}/share/doc/nixos/options.json ./treefmt-options.json
ln -s ${docs.generic.meta-maintainers.optionsJSON}/share/doc/nixos/options.json ./options-modules-generic-meta-maintainers.json
'';
buildPhase = ''
runHook preBuild
substituteInPlace ./languages-frameworks/python.section.md \
--subst-var-by python-interpreter-table "$(<"${pythonInterpreterTable}")"
cat ./functions/library.md.in ${lib-docs}/index.md > ./functions/library.md
substitute ./manual.md.in ./manual.md \
--replace-fail '@MANUAL_VERSION@' '${lib.version}'
mkdir -p out/media
mkdir -p out/highlightjs
cp -t out/highlightjs \
${documentation-highlighter}/highlight.pack.js \
${documentation-highlighter}/LICENSE \
${documentation-highlighter}/mono-blue.css \
${documentation-highlighter}/loader.js
cp -t out ./style.css ./anchor.min.js ./anchor-use.js
nixos-render-docs manual html \
--manpage-urls ./manpage-urls.json \
--redirects ./redirects.json \
--revision ${nixpkgs.rev or "master"} \
--stylesheet style.css \
--stylesheet highlightjs/mono-blue.css \
--script ./highlightjs/highlight.pack.js \
--script ./highlightjs/loader.js \
--script ./anchor.min.js \
--script ./anchor-use.js \
--toc-depth 1 \
--section-toc-depth 1 \
manual.md \
out/index.html
runHook postBuild
'';
installPhase = ''
runHook preInstall
dest="$out/share/doc/nixpkgs"
mkdir -p "$(dirname "$dest")"
mv out "$dest"
cp "$dest/index.html" "$dest/manual.html"
cp ${roboto.src}/web/Roboto\[ital\,wdth\,wght\].ttf "$dest/Roboto.ttf"
cp ${epub} "$dest/nixpkgs-manual.epub"
mkdir -p $out/nix-support/
echo "doc manual $dest index.html" >> $out/nix-support/hydra-build-products
echo "doc manual $dest nixpkgs-manual.epub" >> $out/nix-support/hydra-build-products
runHook postInstall
'';
passthru = {
lib-docs = callPackage ./lib-function-docs.nix { inherit nixpkgs; };
epub = callPackage ./epub.nix { };
optionsDoc = callPackage ./options-doc.nix { };
pythonInterpreterTable = callPackage ./python-interpreter-table.nix { };
shell =
let
devmode' = devmode.override {
buildArgs = toString ../.;
open = "/share/doc/nixpkgs/index.html";
};
nixos-render-docs-redirects' = writeShellScriptBin "redirects" "${lib.getExe nixos-render-docs-redirects} --file ${toString ../redirects.json} $@";
in
mkShellNoCC {
packages = [
devmode'
nixos-render-docs-redirects'
markdown-code-runner
];
};
tests = {
manpage-urls = callPackage ../tests/manpage-urls.nix { };
};
};
}
)

View File

@@ -0,0 +1,67 @@
# To build this derivation, run `nix-build -A nixpkgs-manual.pythonInterpreterTable`
{
lib,
writeText,
pkgs,
pythonInterpreters,
}:
let
isPythonInterpreter =
name:
/*
NB: Package names that don't follow the regular expression:
- `python-cosmopolitan` is not part of `pkgs.pythonInterpreters`.
- `_prebuilt` interpreters are used for bootstrapping internally.
- `python3Minimal` contains python packages, left behind conservatively.
- `rustpython` lacks `pythonVersion` and `implementation`.
*/
(lib.strings.match "(pypy|python)([[:digit:]]*)" name) != null;
interpreterName =
pname:
let
cuteName = {
cpython = "CPython";
pypy = "PyPy";
};
interpreter = pkgs.${pname};
in
"${cuteName.${interpreter.implementation}} ${interpreter.pythonVersion}";
interpreters = lib.reverseList (
lib.naturalSort (lib.filter isPythonInterpreter (lib.attrNames pythonInterpreters))
);
aliases =
pname:
lib.attrNames (
lib.filterAttrs (
name: value:
# use tryEval to handle entries in aliases.nix
(builtins.tryEval (
isPythonInterpreter name && name != pname && interpreterName name == interpreterName pname
)).value
) pkgs
);
result = map (pname: {
inherit pname;
aliases = aliases pname;
interpreter = interpreterName pname;
}) interpreters;
toMarkdown =
data:
let
line = package: ''
| ${package.pname} | ${lib.concatStringsSep ", " package.aliases or [ ]} | ${package.interpreter} |
'';
in
lib.concatStringsSep "" (map line data);
in
writeText "python-interpreter-table.md" ''
| Package | Aliases | Interpeter |
|---------|---------|------------|
${toMarkdown result}
''

11
doc/functions.md Normal file
View File

@@ -0,0 +1,11 @@
# Functions reference {#chap-functions}
The Nixpkgs repository has several utility functions to manipulate Nix expressions.
```{=include=} sections
functions/library.md
functions/generators.section.md
functions/debug.section.md
functions/prefer-remote-fetch.section.md
functions/nix-gitignore.section.md
```

View File

@@ -0,0 +1,5 @@
# Debugging Nix Expressions {#sec-debug}
Nix is a unityped, dynamic language, this means any value can potentially appear anywhere. Since it is also non-strict, evaluation order and what is ultimately evaluated might surprise you. Therefore, it is important to be able to debug Nix expressions.
In the `lib/debug.nix` file you will find a number of functions that help (pretty-)printing values while evaluation is running. You can even specify how deep these values should be printed recursively, and transform them on the fly. Please consult the docstrings in `lib/debug.nix` for usage information.

View File

@@ -0,0 +1,63 @@
# Generators {#sec-generators}
Generators are functions that create file formats from Nix data structures, e.g. for configuration files. There are generators available for: `INI`, `JSON` and `YAML`.
All generators follow a similar call interface: `generatorName configFunctions data`, where `configFunctions` is an attrset of user-defined functions that format nested parts of the content. They each have common defaults, so often they do not need to be set manually. An example is `mkSectionName` from the `INI` generator, which defaults to `(name: libStr.escape [ "[" "]" ] name)`. It receives the name of a section and sanitizes it. The default `mkSectionName` escapes `[` and `]` with a backslash.
Generators can be fine-tuned to produce exactly the file format required by your application/service. One example is an INI file format that uses `: ` as a separator, the strings `"yes"` and `"no"` as boolean values, and requires all string values to be quoted:
```nix
let
inherit (lib) generators isString;
customToINI = generators.toINI {
# specifies how to format a key/value pair
mkKeyValue = generators.mkKeyValueDefault {
# specifies the generated string for a subset of nix values
mkValueString =
v:
if v == true then
''"yes"''
else if v == false then
''"no"''
else if isString v then
''"${v}"''
# and delegates all other values to the default generator
else
generators.mkValueStringDefault { } v;
} ":";
};
# the INI file can now be given as plain old nix values
in
customToINI {
main = {
pushinfo = true;
autopush = false;
host = "localhost";
port = 42;
};
mergetool = {
merge = "diff3";
};
}
```
This will produce the following INI file as a Nix string:
```INI
[main]
autopush:"no"
host:"localhost"
port:42
pushinfo:"yes"
str\:ange:"very::strange"
[mergetool]
merge:"diff3"
```
::: {.note}
Nix store paths can be converted to strings by enclosing a derivation attribute like so: `"${drv}"`.
:::
Detailed documentation for each generator can be found [here](#sec-functions-library-generators)

View File

@@ -0,0 +1,5 @@
# Nixpkgs Library Functions {#sec-functions-library}
Nixpkgs provides a standard library at `pkgs.lib`, or through `import <nixpkgs/lib>`.
<!-- nixdoc-generated documentation must be appended here during build! -->

View File

@@ -0,0 +1,68 @@
# pkgs.nix-gitignore {#sec-pkgs-nix-gitignore}
`pkgs.nix-gitignore` is a function that acts similarly to `builtins.filterSource` but also allows filtering with the help of the gitignore format.
## Usage {#sec-pkgs-nix-gitignore-usage}
`pkgs.nix-gitignore` exports a number of functions, but you'll most likely need either `gitignoreSource` or `gitignoreSourcePure`. As their first argument, they both accept either 1. a file with gitignore lines or 2. a string with gitignore lines, or 3. a list of either of the two. They will be concatenated into a single big string.
```nix
{
pkgs ? import <nixpkgs> { },
}:
{
src = nix-gitignore.gitignoreSource [ ] ./source;
# Simplest version
src = nix-gitignore.gitignoreSource ''
supplemental-ignores
'' ./source;
# This one reads the ./source/.gitignore and concats the auxiliary ignores
src = nix-gitignore.gitignoreSourcePure ''
ignore-this
ignore-that
'' ./source;
# Use this string as gitignore, don't read ./source/.gitignore.
src = nix-gitignore.gitignoreSourcePure [
''
ignore-this
ignore-that
''
~/.gitignore
] ./source;
# It also accepts a list (of strings and paths) that will be concatenated
# once the paths are turned to strings via readFile.
}
```
These functions are derived from the `Filter` functions by setting the first filter argument to `(_: _: true)`:
```nix
{
gitignoreSourcePure = gitignoreFilterSourcePure (_: _: true);
gitignoreSource = gitignoreFilterSource (_: _: true);
}
```
Those filter functions accept the same arguments the `builtins.filterSource` function would pass to its filters, thus `fn: gitignoreFilterSourcePure fn ""` should be extensionally equivalent to `filterSource`. The file is blacklisted if it's blacklisted by either your filter or the gitignoreFilter.
If you want to make your own filter from scratch, you may use
```nix
{ gitignoreFilter = ign: root: filterPattern (gitignoreToPatterns ign) root; }
```
## gitignore files in subdirectories {#sec-pkgs-nix-gitignore-usage-recursive}
If you wish to use a filter that would search for .gitignore files in subdirectories, just like git does by default, use this function:
```nix
{
# gitignoreFilterRecursiveSource = filter: patterns: root:
# OR
gitignoreRecursiveSource = gitignoreFilterSourcePure (_: _: true);
}
```

View File

@@ -0,0 +1,16 @@
# prefer-remote-fetch overlay {#sec-prefer-remote-fetch}
`prefer-remote-fetch` is an overlay that downloads sources on a remote builder. This is useful when the evaluating machine has a slow upload while the builder can fetch faster, directly from the source. To use it, put the following snippet as a new overlay:
```nix
self: super: (super.prefer-remote-fetch self super)
```
A full configuration example that sets the overlay up for your own account could look like this
```ShellSession
$ mkdir ~/.config/nixpkgs/overlays/
$ cat > ~/.config/nixpkgs/overlays/prefer-remote-fetch.nix <<EOF
self: super: super.prefer-remote-fetch self super
EOF
```

View File

@@ -0,0 +1,3 @@
# Autoconf {#setup-hook-autoconf}
The `autoreconfHook` derivation adds `autoreconfPhase`, which runs autoreconf, libtoolize and automake, essentially preparing the configure script in autotools-based builds. Most autotools-based packages come with the configure script pre-generated, but this hook is necessary for a few packages and when you need to patch the packages configure scripts.

View File

@@ -0,0 +1,3 @@
# Automake {#setup-hook-automake}
Adds the `share/aclocal` subdirectory of each build input to the `ACLOCAL_PATH` environment variable.

View File

@@ -0,0 +1,17 @@
# autoPatchcilHook {#setup-hook-autopatchcilhook}
This is a special setup hook which helps in packaging .NET assemblies/programs in that it automatically tries to find missing shared library dependencies of .NET assemblies based on the given `buildInputs` and `nativeBuildInputs`.
As the hook needs information for the host where the package will be run on, there's a required environment variable called `autoPatchcilRuntimeId` which should be filled in with the RID (Runtime Identifier) of the machine where the output will be run on. If you're using `buildDotnetModule`, it will fall back to `dotnetRuntimeIds` (which is set to `lib.singleton (if runtimeId != null then runtimeId else systemToDotnetRid stdenvNoCC.hostPlatform.system)`) for you if not provided.
In certain situations you may want to run the main command (`autoPatchcil`) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the `dontAutoPatchcil` environment variable to a non-empty value.
By default, `autoPatchcil` will fail as soon as any .NET assembly requires a dependency which cannot be resolved via the given build inputs. In some situations you might prefer to just leave missing dependencies unpatched and continue to patch the rest. This can be achieved by setting the `autoPatchcilIgnoreMissingDeps` environment variable to a non-empty value. `autoPatchcilIgnoreMissingDeps` can be set to a list like `autoPatchcilIgnoreMissingDeps = [ "libcuda.so.1" "libcudart.so.1" ];` or to `[ "*" ]` to ignore all missing dependencies.
The `autoPatchcil` command requires the `--rid` command line flag, informing the RID (Runtime Identifier) it should assume the assemblies will be executed on, and also recognizes a `--no-recurse` command line flag, which prevents it from recursing into subdirectories.
::: {.note}
Since, unlike most native binaries, .NET assemblies are compiled once to run on any platform, many assemblies may have PInvoke stubs for libraries that might not be available on the platform that the package will effectively run on. A few examples are assemblies that call native Windows APIs through PInvoke targeting `kernel32`, `gdi32`, `user32`, `shell32` or `ntdll`.
`autoPatchcil` does its best to ignore dependencies from other platforms by checking the requested file extensions, however not all PInvoke stubs provide an extension so in those cases it will be necessary to list those in `autoPatchcilIgnoreMissingDeps` manually.
:::

View File

@@ -0,0 +1,11 @@
# autoPatchelfHook {#setup-hook-autopatchelfhook}
This is a special setup hook which helps in packaging proprietary software in that it automatically tries to find missing shared library dependencies of ELF files based on the given `buildInputs` and `nativeBuildInputs`.
You can also specify a `runtimeDependencies` variable which lists dependencies to be unconditionally added to the rpath of all executables. This is useful for programs that use `dlopen` to load libraries at runtime.
In certain situations you may want to run the main command (`autoPatchelf`) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the `dontAutoPatchelf` environment variable to a non-empty value.
By default `autoPatchelf` will fail as soon as any ELF file requires a dependency which cannot be resolved via the given build inputs. In some situations you might prefer to just leave missing dependencies unpatched and continue to patch the rest. This can be achieved by setting the `autoPatchelfIgnoreMissingDeps` environment variable to a non-empty value. `autoPatchelfIgnoreMissingDeps` can be set to a list like `autoPatchelfIgnoreMissingDeps = [ "libcuda.so.1" "libcudart.so.1" ];` or to `[ "*" ]` to ignore all missing dependencies.
The `autoPatchelf` command also recognizes a `--no-recurse` command line flag, which prevents it from recursing into subdirectories.

View File

@@ -0,0 +1,4 @@
# `aws-c-common` {#aws-c-common}
This hook exposes its own [CMake](#cmake) modules by setting [`CMAKE_MODULE_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html) through [the `cmakeFlags` variable](#cmake-flags)
to the nonstandard `$out/lib/cmake` directory, as a workaround for [an upstream bug](https://github.com/awslabs/aws-c-common/issues/844).

View File

@@ -0,0 +1,7 @@
# bmake {#bmake-hook}
[bmake](https://www.crufty.net/help/sjg/bmake.html) is the portable variant of
NetBSD `make` utility.
In Nixpkgs, `bmake` comes with a hook that overrides the default build, check,
install and dist phases.

View File

@@ -0,0 +1,15 @@
# breakpointHook {#breakpointhook}
This hook makes a build pause instead of stopping when a failure occurs. It prevents Nix from cleaning up the build environment immediately and allows the user to attach to the build environment. Upon a build error, it will print instructions that can be used to enter the environment for debugging. The `breakpointHook` is only available on Linux. To use it, add `breakpointHook` to `nativeBuildInputs` in the package to be inspected.
```nix
{ nativeBuildInputs = [ breakpointHook ]; }
```
When a build failure occurs, an instruction will be printed showing how to attach to the build sandbox.
::: {.note}
Caution with remote builds
For remote builds, the printed instructions need to be run on the remote machine, as the build sandbox is only accessible on the machine running the builds. Remote builds can be turned off by setting `--option builders ''` for `nix-build` or `--builders ''` for `nix build`. :::
:::

View File

@@ -0,0 +1,3 @@
# CERNLIB {#cernlib-hook}
This hook sets the `CERN`, `CERN_LEVEL`, and `CERN_ROOT` environment variables. They are part of [CERNLIB's build system](https://cernlib.web.cern.ch/install/install.html) and are needed for some programs to compile correctly.

View File

@@ -0,0 +1,53 @@
# cmake {#cmake}
Overrides the default configure phase to run the CMake command.
By default, we use the Make generator of CMake.
But when Ninja is also available as a `nativeBuildInput`, this setup hook will detect that and use the ninja generator.
Dependencies are added automatically to `CMAKE_PREFIX_PATH` so that packages are correctly detected by CMake.
Some additional flags are passed in to give similar behavior to configure-based packages.
By default, parallel building is enabled as CMake supports parallel building almost everywhere.
You can disable this hooks behavior by setting `configurePhase` to a custom value, or by setting `dontUseCmakeConfigure`.
## Variables controlling CMake {#cmake-variables-controlling}
### CMake Exclusive Variables {#cmake-exclusive-variables}
#### `cmakeFlags` {#cmake-flags}
Controls the flags passed to `cmake setup` during configure phase.
#### `cmakeBuildDir` {#cmake-build-dir}
Directory where CMake will put intermediate files.
Setting this can be useful for debugging multiple CMake builds while in the same source directory, for example, when building for different platforms.
Different values for each build will prevent build artifacts from interfering with each other.
This setting has no tangible effect when running the build in a sandboxed derivation.
The default value is `build`.
#### `dontUseCmakeConfigure` {#dont-use-cmake-configure}
When set to true, don't use the predefined `cmakeConfigurePhase`.
## Controlling CTest invocation {#cmake-ctest}
By default tests are run by make in [`checkPhase`](#ssec-check-phase) or by [ninja](#ninja) if `ninja` is
available in `nativeBuildInputs`. Makefile and Ninja generators produce the `test` target, which invokes `ctest` under the hood.
This makes passing additional arguments to `ctest` difficult, so it's possible to invoke it directly in `checkPhase`
by adding `ctestCheckHook` to `nativeCheckInputs`.
### CTest Variables {#cmake-ctest-variables}
#### `disabledTests` {#cmake-ctest-disabled-tests}
Allows to disable running a list of tests. Note that regular expressions are not supported by `disabledTests`, but
it can be combined with `--exclude-regex` option.
#### `ctestFlags` {#cmake-ctest-flags}
Additional options passed to `ctest` together with `checkFlags`.

View File

@@ -0,0 +1,5 @@
# desktop-file-utils {#desktop-file-utils}
This setup hook removes the MIME cache (located at `$out/share/applications/mimeinfo.cache`) in the `preFixupPhase`.
This hook is necessary because `mimeinfo.cache` can be created when a package uses `desktop-file-utils`, resulting in collisions if multiple packages are installed that contain this file (as in [#48295](https://github.com/NixOS/nixpkgs/issues/48295)).

View File

@@ -0,0 +1,3 @@
# gdk-pixbuf {#setup-hook-gdk-pixbuf}
Exports `GDK_PIXBUF_MODULE_FILE` environment variable to the builder. Add librsvg package to `buildInputs` to get svg support. See also the [setup hook description in GNOME platform docs](#ssec-gnome-hooks-gdk-pixbuf).

3
doc/hooks/ghc.section.md Normal file
View File

@@ -0,0 +1,3 @@
# GHC {#ghc}
Creates a temporary package database and registers every Haskell build input in it (TODO: how?).

View File

@@ -0,0 +1,3 @@
# GNOME platform {#gnome-platform}
Hooks related to GNOME platform and related libraries like GLib, GTK and GStreamer are described in [](#sec-language-gnome).

View File

@@ -0,0 +1,29 @@
# `haredo` {#haredo-hook}
This hook uses [the `haredo` command runner](https://sr.ht/~autumnull/haredo/) to build, check, and install the package. It overrides `buildPhase`, `checkPhase`, and `installPhase` by default.
The hook builds its targets in parallel if [`enableParallelBuilding`](#var-stdenv-enableParallelBuilding) is set to `true`.
## `buildPhase` {#haredo-hook-buildPhase}
This phase attempts to build the default target.
[]{#haredo-hook-haredoBuildTargets} Targets can be explicitly set by adding a string to the `haredoBuildTargets` list.
[]{#haredo-hook-dontUseHaredoBuild} This behavior can be disabled by setting `dontUseHaredoBuild` to `true`.
## `checkPhase` {#haredo-hook-checkPhase}
This phase searches for the `check.do` or `test.do` targets, running them if they exist.
[]{#haredo-hook-haredoCheckTargets} Targets can be explicitly set by adding a string to the `haredoCheckTargets` list.
[]{#haredo-hook-dontUseHaredoCheck} This behavior can be disabled by setting `dontUseHaredoCheck` to `true`.
## `installPhase` {#haredo-hook-installPhase}
This phase attempts to build the `install.do` target, if it exists.
[]{#haredo-hook-haredoInstallTargets} Targets can be explicitly set by adding a string to the `haredoInstallTargets` list.
[]{#haredo-hook-dontUseHaredoInstall} This behavior can be disabled by setting `dontUseHaredoInstall` to `true`.

46
doc/hooks/index.md Normal file
View File

@@ -0,0 +1,46 @@
# Hooks reference {#chap-hooks}
Nixpkgs has several hook packages that augment the stdenv phases.
The stdenv built-in hooks are documented in [](#ssec-setup-hooks).
```{=include=} sections
autoconf.section.md
automake.section.md
autopatchcil.section.md
autopatchelf.section.md
aws-c-common.section.md
bmake.section.md
breakpoint.section.md
cernlib.section.md
cmake.section.md
desktop-file-utils.section.md
gdk-pixbuf.section.md
ghc.section.md
gnome.section.md
haredo.section.md
installShellFiles.section.md
just.section.md
libiconv.section.md
libxml2.section.md
meson.section.md
mpi-check-hook.section.md
ninja.section.md
patch-rc-path-hooks.section.md
perl.section.md
pkg-config.section.md
postgresql-test-hook.section.md
premake.section.md
python.section.md
scons.section.md
tauri.section.md
tetex-tex-live.section.md
udevCheckHook.section.md
unzip.section.md
validatePkgConfig.section.md
versionCheckHook.section.md
waf.section.md
zig.section.md
xcbuild.section.md
xfce4-dev-tools.section.md
```

View File

@@ -0,0 +1,143 @@
# `installShellFiles` {#installshellfiles}
This hook adds helpers that install artifacts like executable files, manpages
and shell completions.
It exposes the following functions that can be used from your `postInstall`
hook:
## `installBin` {#installshellfiles-installbin}
The `installBin` function takes one or more paths to files to install as
executable files.
This function will place them into [`outputBin`](#outputbin).
### Example Usage {#installshellfiles-installbin-exampleusage}
```nix
{
nativeBuildInputs = [ installShellFiles ];
# Sometimes the file has an undesirable name. It should be renamed before
# being installed via installBin
postInstall = ''
mv a.out delmar
installBin foobar delmar
'';
}
```
## `installManPage` {#installshellfiles-installmanpage}
The `installManPage` function takes one or more paths to manpages to install.
The manpages must have a section suffix, and may optionally be compressed (with
`.gz` suffix). This function will place them into the correct
`share/man/man<section>/` directory in [`outputMan`](#outputman).
### Example Usage {#installshellfiles-installmanpage-exampleusage}
```nix
{
nativeBuildInputs = [ installShellFiles ];
# Sometimes the manpage file has an undersirable name; e.g., it conflicts with
# another software with an equal name. To install it with a different name,
# the installed name must be provided before the path to the file.
#
# Below install a manpage "foobar.1" from the source file "./foobar.1", and
# also installs the manpage "fromsea.3" from the source file "./delmar.3".
postInstall = ''
installManPage \
foobar.1 \
--name fromsea.3 delmar.3
'';
}
```
The manpage may be the result of a piped input (e.g. `<(cmd)`), in which
case the name must be provided before the pipe with the `--name` flag.
```nix
{
nativeBuildInputs = [ installShellFiles ];
postInstall = ''
installManPage --name foobar.1 <($out/bin/foobar --manpage)
'';
}
```
If no parsing of arguments is desired, pass `--` to opt-out of all subsequent
arguments.
```nix
{
nativeBuildInputs = [ installShellFiles ];
# Installs a manpage from a file called "--name"
postInstall = ''
installManPage -- --name
'';
}
```
## `installShellCompletion` {#installshellfiles-installshellcompletion}
The `installShellCompletion` function takes one or more paths to shell
completion files.
By default it will autodetect the shell type from the completion file extension,
but you may also specify it by passing one of `--bash`, `--fish`, `--zsh`, or
`--nushell`. These flags apply to all paths listed after them (up until another
shell flag is given). Each path may also have a custom installation name
provided by providing a flag `--name NAME` before the path. If this flag is not
provided, zsh completions will be renamed automatically such that `foobar.zsh`
becomes `_foobar`. A root name may be provided for all paths using the flag
`--cmd NAME`; this synthesizes the appropriate name depending on the shell
(e.g. `--cmd foo` will synthesize the name `foo.bash` for bash and `_foo` for
zsh).
### Example Usage {#installshellfiles-installshellcompletion-exampleusage}
```nix
{
nativeBuildInputs = [ installShellFiles ];
postInstall = ''
# explicit behavior
installShellCompletion --bash --name foobar.bash share/completions.bash
installShellCompletion --fish --name foobar.fish share/completions.fish
installShellCompletion --nushell --name foobar share/completions.nu
installShellCompletion --zsh --name _foobar share/completions.zsh
# implicit behavior
installShellCompletion share/completions/foobar.{bash,fish,zsh,nu}
'';
}
```
The path may also be the result of process substitution (e.g. `<(cmd)`), in which
case the shell and name must be provided (see below).
If the destination shell completion file is not actually present or consists of
zero bytes after calling `installShellCompletion` this is treated as a build
failure. In particular, if completion files are not vendored but are generated
by running an executable, this is likely to fail in cross compilation
scenarios. The result will be a zero byte completion file and hence a build
failure. To prevent this, guard the completion generation commands.
### Example Usage {#installshellfiles-installshellcompletion-exampleusage-guarded}
```nix
{
nativeBuildInputs = [ installShellFiles ];
postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
# using process substitution
installShellCompletion --cmd foobar \
--bash <($out/bin/foobar --bash-completion) \
--fish <($out/bin/foobar --fish-completion) \
--nushell <($out/bin/foobar --nushell-completion) \
--zsh <($out/bin/foobar --zsh-completion)
'';
}
```

23
doc/hooks/just.section.md Normal file
View File

@@ -0,0 +1,23 @@
# `just` {#just-hook}
This setup hook attempts to use [the `just` command runner](https://just.systems/man/en/) to build, check, and install the package. The hook overrides `buildPhase`, `checkPhase`, and `installPhase` by default.
[]{#just-hook-justFlags} The `justFlags` variable can be set to a list of strings to add additional flags passed to all invocations of `just`.
## `buildPhase` {#just-hook-buildPhase}
This phase attempts to invoke `just` with [the default recipe](https://just.systems/man/en/the-default-recipe.html).
[]{#just-hook-dontUseJustBuild} This behavior can be disabled by setting `dontUseJustBuild` to `true`.
## `checkPhase` {#just-hook-checkPhase}
This phase attempts to invoke the `just test` recipe, if it is available. This can be overridden by setting `checkTarget` to a string.
[]{#just-hook-dontUseJustCheck} This behavior can be disabled by setting `dontUseJustCheck` to `true`.
## `installPhase` {#just-hook-installPhase}
This phase attempts to invoke the `just install` recipe.
[]{#just-hook-dontUseJustInstall} This behavior can be disabled by setting `dontUseJustInstall` to `true`.

View File

@@ -0,0 +1,3 @@
# libiconv, libintl {#libiconv-libintl}
A few libraries automatically add to `NIX_LDFLAGS` their library, making their symbols automatically available to the linker. This includes libiconv and libintl (gettext). This is done to provide compatibility between GNU Linux, where libiconv and libintl are bundled in, and other systems where that might not be the case. Sometimes, this behavior is not desired. To disable this behavior, set `dontAddExtraLibs`.

View File

@@ -0,0 +1,3 @@
# libxml2 {#setup-hook-libxml2}
Adds every file named `catalog.xml` found under the `xml/dtd` and `xml/xsl` subdirectories of each build input to the `XML_CATALOG_FILES` environment variable.

View File

@@ -0,0 +1,49 @@
# `memcachedTestHook` {#sec-memcachedTestHook}
This hook starts a Memcached server during `checkPhase`. Example:
```nix
{ stdenv, memcachedTestHook }:
stdenv.mkDerivation {
# ...
nativeCheckInputs = [ memcachedTestHook ];
}
```
If you use a custom `checkPhase`, remember to add the `runHook` calls:
```nix
{
checkPhase = ''
runHook preCheck
# ... your tests
runHook postCheck
'';
}
```
## Variables {#sec-memcachedTestHook-variables}
Bash-only variables:
- `memcachedTestPort`: Port to use by Memcached. Defaults to `11211`
Example usage:
```nix
{ stdenv, memcachedTestHook }:
stdenv.mkDerivation {
# ...
nativeCheckInputs = [ memcachedTestHook ];
preCheck = ''
memcachedTestPort=1234;
'';
}
```

View File

@@ -0,0 +1,94 @@
# Meson {#meson}
[Meson](https://mesonbuild.com/) is an open source meta build system meant to be
fast and user-friendly.
In Nixpkgs, meson comes with a setup hook that overrides the configure, check,
and install phases.
Being a meta build system, meson needs an accompanying backend. In the context
of Nixpkgs, the typical companion backend is [Ninja](#ninja), that provides a
setup hook registering ninja-based build and install phases.
## Variables controlling Meson {#meson-variables-controlling}
### Meson Exclusive Variables {#meson-exclusive-variables}
#### `mesonFlags` {#meson-flags}
Controls the flags passed to `meson setup` during configure phase.
#### `mesonBuildDir` {#meson-build-dir}
Directory where Meson will put intermediate files.
Setting this can be useful for debugging multiple Meson builds while in the same source directory, for example, when building for different platforms.
Different values for each build will prevent build artifacts from interfering with each other.
This setting has no tangible effect when running the build in a sandboxed derivation.
The default value is `build`.
#### `mesonWrapMode` {#meson-wrap-mode}
Which value is passed as
[`-Dwrap_mode=`](https://mesonbuild.com/Builtin-options.html#core-options).
In Nixpkgs, the default value is `nodownload`, so that no subproject will be
downloaded (since network access is already disabled during deployment in
Nixpkgs).
Note: Meson allows pre-population of subprojects that would otherwise be
downloaded.
#### `mesonBuildType` {#meson-build-type}
Which value is passed as
[`--buildtype`](https://mesonbuild.com/Builtin-options.html#core-options) to
`meson setup` during configure phase. In Nixpkgs, the default value is `plain`.
#### `mesonAutoFeatures` {#meson-auto-features}
Which value is passed as
[`-Dauto_features=`](https://mesonbuild.com/Builtin-options.html#core-options)
to `meson setup` during configure phase. In Nixpkgs, the default value is
`enabled`, meaning that every feature declared as "auto" by the meson scripts
will be enabled.
#### `mesonCheckFlags` {#meson-check-flags}
Controls the flags passed to `meson test` during check phase.
#### `mesonInstallFlags` {#meson-install-flags}
Controls the flags passed to `meson install` during install phase.
#### `mesonInstallTags` {#meson-install-tags}
A list of installation tags passed to Meson's commandline option
[`--tags`](https://mesonbuild.com/Installing.html#installation-tags) during
install phase.
Note: `mesonInstallTags` should be a list of strings that will be converted to
a comma-separated string that is recognized to `--tags`.
Example: `mesonInstallTags = [ "emulator" "assembler" ];` will be converted to
`--tags emulator,assembler`.
#### `dontUseMesonConfigure` {#dont-use-meson-configure}
When set to true, don't use the predefined `mesonConfigurePhase`.
#### `dontUseMesonCheck` {#dont-use-meson-check}
When set to true, don't use the predefined `mesonCheckPhase`.
#### `dontUseMesonInstall` {#dont-use-meson-install}
When set to true, don't use the predefined `mesonInstallPhase`.
### Honored variables {#meson-honored-variables}
The following variables commonly used by `stdenv.mkDerivation` are honored by
Meson setup hook.
- `prefixKey`
- `enableParallelBuilding`
- `enableParallelChecking`

View File

@@ -0,0 +1,25 @@
# mpiCheckPhaseHook {#setup-hook-mpi-check}
This hook can be used to setup a check phase that
requires running a MPI application. It detects the
present MPI implementation type and exports
the necessary environment variables to use
`mpirun` and `mpiexec` in a Nix sandbox.
Example:
```nix
{ mpiCheckPhaseHook, mpi, ... }:
{
# ...
nativeCheckInputs = [
openssh
mpiCheckPhaseHook
];
}
```

View File

@@ -0,0 +1,5 @@
# ninja {#ninja}
Overrides the build, install, and check phase to run ninja instead of make. You can disable this behavior with `dontUseNinjaBuild`, `dontUseNinjaInstall`, and `dontUseNinjaCheck`, respectively. Parallel building is enabled by default in Ninja.
Note that if the [Meson setup hook](#meson) is also active, Ninja's install and check phases will be disabled in favor of Meson's.

View File

@@ -0,0 +1,58 @@
# `patchRcPath` hooks {#sec-patchRcPathHooks}
These hooks provide shell-specific utilities (with the same name as the hook) to patch shell scripts meant to be sourced by software users.
The typical usage is to patch initialisation or [rc](https://unix.stackexchange.com/questions/3467/what-does-rc-in-bashrc-stand-for) scripts inside `$out/bin` or `$out/etc`.
Such scripts, when being sourced, would insert the binary locations of certain commands into `PATH`, modify other environment variables or run a series of start-up commands.
When shipped from the upstream, they sometimes use commands that might not be available in the environment they are getting sourced in.
The compatible shells for each hook are:
- `patchRcPathBash`: [Bash](https://www.gnu.org/software/bash/), [ksh](http://www.kornshell.org/), [zsh](https://www.zsh.org/) and other shells supporting the Bash-like parameter expansions.
- `patchRcPathCsh`: Csh scripts, such as those targeting [tcsh](https://www.tcsh.org/).
- `patchRcPathFish`: [Fish](https://fishshell.com/) scripts.
- `patchRcPathPosix`: POSIX-conformant shells supporting the limited parameter expansions specified by the POSIX standard. The current implementation uses the parameter expansion `${foo-}` only.
For each supported shell, it modifies the script with a `PATH` prefix that is later removed when the script ends.
It allows nested patching, which guarantees that a patched script may source another patched script.
Syntax to apply the utility to a script:
```sh
patchRcPath<shell> <file> <PATH-prefix>
```
Example usage:
Given a package `foo` containing an init script `this-foo.fish` that depends on `coreutils`, `man` and `which`,
patch the init script for users to source without having the above dependencies in their `PATH`:
```nix
{
lib,
stdenv,
patchRcPathFish,
}:
stdenv.mkDerivation {
# ...
nativeBuildInputs = [ patchRcPathFish ];
postFixup = ''
patchRcPathFish $out/bin/this-foo.fish ${
lib.makeBinPath [
coreutils
man
which
]
}
'';
}
```
::: {.note}
`patchRcPathCsh` and `patchRcPathPosix` implementation depends on `sed` to do the string processing.
The others are in vanilla shell and have no third-party dependencies.
:::

View File

@@ -0,0 +1,3 @@
# Perl {#setup-hook-perl}
Adds the `lib/site_perl` subdirectory of each build input to the `PERL5LIB` environment variable. For instance, if `buildInputs` contains Perl, then the `lib/site_perl` subdirectory of each input is added to the `PERL5LIB` environment variable.

View File

@@ -0,0 +1,3 @@
# pkg-config {#setup-hook-pkg-config}
Adds the `lib/pkgconfig` and `share/pkgconfig` subdirectories of each build input to the `PKG_CONFIG_PATH` environment variable.

View File

@@ -0,0 +1,70 @@
# `postgresqlTestHook` {#sec-postgresqlTestHook}
This hook starts a PostgreSQL server during the `checkPhase`. Example:
```nix
{
stdenv,
postgresql,
postgresqlTestHook,
}:
stdenv.mkDerivation {
# ...
nativeCheckInputs = [
postgresql
postgresqlTestHook
];
}
```
If you use a custom `checkPhase`, remember to add the `runHook` calls:
```nix
checkPhase ''
runHook preCheck
# ... your tests
runHook postCheck
''
```
## Variables {#sec-postgresqlTestHook-variables}
The hook logic will read a number of variables and set them to a default value if unset or empty.
Exported variables:
- `PGDATA`: location of server files.
- `PGHOST`: location of UNIX domain socket directory; the default `host` in a connection string.
- `PGUSER`: user to create / log in with, default: `test_user`.
- `PGDATABASE`: database name, default: `test_db`.
Bash-only variables:
- `postgresqlTestUserOptions`: SQL options to use when creating the `$PGUSER` role, default: `"LOGIN"`. Example: `"LOGIN SUPERUSER"`
- `postgresqlTestSetupSQL`: SQL commands to run as database administrator after startup, default: statements that create `$PGUSER` and `$PGDATABASE`.
- `postgresqlTestSetupCommands`: bash commands to run after database start, defaults to running `$postgresqlTestSetupSQL` as database administrator.
- `postgresqlEnableTCP`: set to `1` to enable TCP listening. Flaky; not recommended.
- `postgresqlStartCommands`: defaults to `pg_ctl start`.
- `postgresqlExtraSettings`: Additional configuration to add to `postgresql.conf`
## Hooks {#sec-postgresqlTestHook-hooks}
A number of additional hooks are run in postgresqlTestHook
- `postgresqlTestSetupPost`: run after postgresql has been set up.
## TCP and the Nix sandbox {#sec-postgresqlTestHook-tcp}
`postgresqlEnableTCP` relies on network sandboxing, which is not available on macOS and some custom Nix installations, resulting in flaky tests.
For this reason, it is disabled by default.
The preferred solution is to make the test suite use a UNIX domain socket connection. This is the default behavior when no `host` connection parameter is provided.
Some test suites hardcode a value for `host` though, so a patch may be required. If you can upstream the patch, you can make `host` default to the `PGHOST` environment variable when set. Otherwise, you can patch it locally to omit the `host` connection string parameter altogether.
::: {.note}
The error `libpq: failed (could not receive data from server: Connection refused` is generally an indication that the test suite is trying to connect through TCP.
:::

View File

@@ -0,0 +1,7 @@
# Premake {#premake-hook}
This setup hook attempts to configure the package using [the Premake build configuration system](https://premake.github.io/). It overrides the `configurePhase` by default, if none exists.
[]{#premake-hook-premakefile} The Premakefile to use can be specified by setting `premakefile` in the derivation.
[]{#premake-hook-premakeFlagsArray} The flags passed to Premake can be configured by adding strings to the `premakeFlags` list.

View File

@@ -0,0 +1,3 @@
# Python {#setup-hook-python}
Adds the `python.sitePackages` subdirectory (i.e. `lib/pythonX.Y/site-packages`) of each build input to the `PYTHONPATH` environment variable.

View File

@@ -0,0 +1,63 @@
# `redisTestHook` {#sec-redisTestHook}
This hook starts a Redis server during `checkPhase`. Example:
```nix
{
stdenv,
redis,
redisTestHook,
}:
stdenv.mkDerivation {
# ...
nativeCheckInputs = [ redisTestHook ];
}
```
If you use a custom `checkPhase`, remember to add the `runHook` calls:
```nix
{
checkPhase = ''
runHook preCheck
# ... your tests
runHook postCheck
'';
}
```
## Variables {#sec-redisTestHook-variables}
The hook logic will read the following variables and set them to a default value if unset or empty.
Exported variables:
- `REDIS_SOCKET`: UNIX domain socket path
Bash-only variables:
- `redisTestPort`: Port to use by Redis. Defaults to `6379`
Example usage:
```nix
{
stdenv,
redis,
redisTestHook,
}:
stdenv.mkDerivation {
# ...
nativeCheckInputs = [ redisTestHook ];
preCheck = ''
redisTestPort=6390;
'';
}
```

View File

@@ -0,0 +1,3 @@
# scons {#scons}
Overrides the build, install, and check phases. This uses the scons build system as a replacement for make. scons does not provide a configure phase, so everything is managed at build and install time.

View File

@@ -0,0 +1,95 @@
# cargo-tauri.hook {#tauri-hook}
[Tauri](https://tauri.app/) is a framework for building smaller, faster, and
more secure desktop applications with a web frontend.
In Nixpkgs, `cargo-tauri.hook` overrides the default build and install phases.
## Example code snippet {#tauri-hook-example-code-snippet}
```nix
{
lib,
stdenv,
rustPlatform,
fetchNpmDeps,
cargo-tauri,
glib-networking,
nodejs,
npmHooks,
openssl,
pkg-config,
webkitgtk_4_1,
wrapGAppsHook4,
}:
rustPlatform.buildRustPackage (finalAttrs: {
# ...
cargoHash = "...";
# Assuming our app's frontend uses `npm` as a package manager
npmDeps = fetchNpmDeps {
name = "${finalAttrs.pname}-${finalAttrs.version}-npm-deps";
inherit (finalAttrs) src;
hash = "...";
};
nativeBuildInputs = [
# Pull in our main hook
cargo-tauri.hook
# Setup npm
nodejs
npmHooks.npmConfigHook
# Make sure we can find our libraries
pkg-config
]
++ lib.optionals stdenv.hostPlatform.isLinux [ wrapGAppsHook4 ];
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [
glib-networking # Most Tauri apps need networking
openssl
webkitgtk_4_1
];
# Set our Tauri source directory
cargoRoot = "src-tauri";
# And make sure we build there too
buildAndTestSubdir = finalAttrs.cargoRoot;
# ...
})
```
## Variables controlling cargo-tauri {#tauri-hook-variables-controlling}
### Tauri Exclusive Variables {#tauri-hook-exclusive-variables}
#### `tauriBuildFlags` {#tauri-build-flags}
Controls the flags passed to `cargo tauri build`.
#### `tauriBundleType` {#tauri-bundle-type}
The [bundle type](https://tauri.app/v1/guides/building/) to build.
#### `dontTauriBuild` {#dont-tauri-build}
Disables using `tauriBuildHook`.
#### `dontTauriInstall` {#dont-tauri-install}
Disables using `tauriInstallPostBuildHook` and `tauriInstallHook`.
### Honored Variables {#tauri-hook-honored-variables}
Along with those found in [](#compiling-rust-applications-with-cargo), the
following variables used by `cargoBuildHook` and `cargoInstallHook` are honored
by the cargo-tauri setup hook.
- `buildAndTestSubdir`
- `cargoBuildType`
- `cargoBuildNoDefaultFeatures`
- `cargoBuildFeatures`

View File

@@ -0,0 +1,3 @@
# teTeX / TeX Live {#tetex-tex-live}
Adds the `share/texmf-nix` subdirectory of each build input to the `TEXINPUTS` environment variable.

View File

@@ -0,0 +1,34 @@
# udevCheckHook {#udevcheckhook}
The `udevCheckHook` derivation adds `udevCheckPhase` to the [`preInstallCheckHooks`](#ssec-installCheck-phase),
which finds all udev rules in all outputs and verifies them using `udevadm verify --resolve-names=never --no-style`.
It should be used in any package that has udev rules outputs to ensure the rules are and remain valid.
The hook runs in `installCheckPhase`, requiring `doInstallCheck` is enabled for the hook to take effect:
```nix
{
lib,
stdenv,
udevCheckHook,
# ...
}:
stdenv.mkDerivation (finalAttrs: {
# ...
nativeInstallCheckInputs = [ udevCheckHook ];
doInstallCheck = true;
# ...
})
```
Note that for [`buildPythonPackage`](#buildpythonpackage-function) and [`buildPythonApplication`](#buildpythonapplication-function), `doInstallCheck` is enabled by default.
All outputs are scanned for their `/{etc,lib}/udev/rules.d` paths.
If no rule output is found, the hook is basically a no-op.
The `udevCheckHook` adds a dependency on `systemdMinimal`.
It is internally guarded behind `hostPlatform` supporting udev and `buildPlatform` being able to execute `udevadm`.
The hook does not need explicit platform checks in the places where it is used.
The hook can be disabled using `dontUdevCheck`, which is necessary if you want to run some different task in `installCheckPhase` on a package with broken udev rule outputs.

View File

@@ -0,0 +1,3 @@
# unzip {#unzip}
This setup hook will allow you to unzip .zip files specified in `$src`. There are many similar packages like `unrar`, `undmg`, etc.

View File

@@ -0,0 +1,3 @@
# validatePkgConfig {#validatepkgconfig}
The `validatePkgConfig` hook validates all pkg-config (`.pc`) files in a package. This helps catch some common errors in pkg-config files, such as undefined variables.

View File

@@ -0,0 +1,38 @@
# versionCheckHook {#versioncheckhook}
This hook adds a `versionCheckPhase` to the [`preInstallCheckHooks`](#ssec-installCheck-phase) that runs the main program of the derivation with a `--help` or `--version` argument, and checks that the `${version}` string is found in that output. If this check fails then the whole build will fail. _(A softer option is [`testers.testVersion`](#tester-testVersion).)_
You use it like this:
```nix
{
lib,
stdenv,
versionCheckHook,
# ...
}:
stdenv.mkDerivation (finalAttrs: {
# ...
nativeInstallCheckInputs = [ versionCheckHook ];
doInstallCheck = true;
# ...
})
```
Note that for [`buildPythonPackage`](#buildpythonpackage-function) and [`buildPythonApplication`](#buildpythonapplication-function), `doInstallCheck` is enabled by default.
It does so in a clean environment (using `env --ignore-environment`), and it checks for the `${version}` string in both the `stdout` and the `stderr` of the command. It will report to you in the build log the output it received and it will fail the build if it failed to find `${version}`.
The variables that this phase control are:
- `dontVersionCheck`: Disable adding this hook to the [`preInstallCheckHooks`](#ssec-installCheck-phase). Useful if you do want to load the bash functions of the hook, but run them differently.
- `versionCheckProgram`: The full path to the program that should print the `${version}` string. Defaults to using the first non-empty value `$binary` out of `${NIX_MAIN_PROGRAM}` and `${pname}`, in that order, to build roughly `${placeholder "out"}/bin/$binary`. `${NIX_MAIN_PROGRAM}`'s value comes from `meta.mainProgram`, and does not normally need to be set explicitly. When setting `versionCheckProgram`, using `$out` directly won't work, as environment variables from this variable are not expanded by the hook. Hence using `placeholder "out"` is unavoidable.
- `versionCheckProgramArg`: The argument that needs to be passed to `versionCheckProgram`. If undefined the hook tries first `--help` and then `--version`. Examples: `version`, `-V`, `-v`.
- `versionCheckKeepEnvironment`: A list of environment variables to keep and pass to the command. Only those variables should be added to this list that are actually required for the version command to work. If it is not feasible to explicitly list all these environment variables you can set this parameter to the special value `"*"` to disable the `--ignore-environment` flag and thus keep all environment variables.
- `preVersionCheck`: A hook to run before the check is done.
- `postVersionCheck`: A hook to run after the check is done.
This check assumes the executable is _hermetic_. If environment variables such as `PATH` or `HOME` are required for the program to function, then [`testers.testVersion`](#tester-testVersion) is currently the better alternative.

54
doc/hooks/waf.section.md Normal file
View File

@@ -0,0 +1,54 @@
# wafHook {#waf-hook}
[Waf](https://waf.io) is a Python-based software building system.
In Nixpkgs, `wafHook` overrides the default configure, build, and install phases.
## Variables controlling wafHook {#waf-hook-variables-controlling}
### `wafHook` Exclusive Variables {#waf-hook-exclusive-variables}
The variables below are exclusive of `wafHook`.
#### `wafPath` {#waf-path}
Location of the `waf` tool. It defaults to `./waf`, to honor software projects that include it directly inside their source trees.
If the file pointed by `wafPath` doesn't exist, then `waf` provided by Nixpkgs will be used.
#### `wafFlags` {#waf-flags}
Controls the flags passed to waf tool during build and install phases. For settings specific to build or install phases, use `wafBuildFlags` or `wafInstallFlags`, respectively.
#### `dontUseWafConfigure` {#dont-use-waf-configure}
When set to true, don't use the predefined `wafConfigurePhase`.
#### `dontUseWafBuild` {#dont-use-waf-build}
When set to true, don't use the predefined `wafBuildPhase`.
#### `dontUseWafInstall` {#dont-use-waf-install}
When set to true, don't use the predefined `wafInstallPhase`.
### Similar variables {#waf-hook-similar-variables}
The following variables are similar to their `stdenv.mkDerivation` counterparts.
| `wafHook` Variable | `stdenv.mkDerivation` Counterpart |
|-----------------------|-----------------------------------|
| `wafConfigureFlags` | `configureFlags` |
| `wafConfigureTargets` | `configureTargets` |
| `wafBuildFlags` | `buildFlags` |
| `wafBuildTargets` | `buildTargets` |
| `wafInstallFlags` | `installFlags` |
| `wafInstallTargets` | `installTargets` |
### Honored variables {#waf-hook-honored-variables}
The following variables commonly used by `stdenv.mkDerivation` are honored by `wafHook`.
- `prefixKey`
- `enableParallelBuilding`
- `enableParallelInstalling`

View File

@@ -0,0 +1,3 @@
# xcbuildHook {#xcbuildhook}
Overrides the build and install phases to run the "xcbuild" command. This hook is needed when a project only comes with build files for the XCode build system. You can disable this behavior by setting buildPhase and configurePhase to a custom value. xcbuildFlags controls flags passed only to xcbuild.

View File

@@ -0,0 +1,5 @@
# `xfce.xfce4-dev-tools` {#xfce4-dev-tools}
This setup hook attempts to run `xdt-autogen` in `xdtAutogenPhase`, which is part of `preConfigurePhases`.
[]{#dontUseXdtAutogenPhase} This behavior can be disabled by setting `dontUseXdtAutogenPhase` to `true`.

62
doc/hooks/zig.section.md Normal file
View File

@@ -0,0 +1,62 @@
# zig.hook {#zig-hook}
[Zig](https://ziglang.org/) is a general-purpose programming language and toolchain for maintaining robust, optimal and reusable software.
In Nixpkgs, `zig.hook` overrides the default build, check and install phases.
## Example code snippet {#zig-hook-example-code-snippet}
```nix
{
lib,
stdenv,
zig,
}:
stdenv.mkDerivation {
# . . .
nativeBuildInputs = [ zig.hook ];
zigBuildFlags = [ "-Dman-pages=true" ];
dontUseZigCheck = true;
# . . .
}
```
## Variables controlling zig.hook {#zig-hook-variables-controlling}
### `zig.hook` Exclusive Variables {#zig-hook-exclusive-variables}
The variables below are exclusive to `zig.hook`.
#### `dontUseZigBuild` {#dont-use-zig-build}
Disables using `zigBuildPhase`.
#### `dontUseZigCheck` {#dont-use-zig-check}
Disables using `zigCheckPhase`.
#### `dontUseZigInstall` {#dont-use-zig-install}
Disables using `zigInstallPhase`.
### Similar variables {#zig-hook-similar-variables}
The following variables are similar to their `stdenv.mkDerivation` counterparts.
| `zig.hook` Variable | `stdenv.mkDerivation` Counterpart |
|---------------------|-----------------------------------|
| `zigBuildFlags` | `buildFlags` |
| `zigCheckFlags` | `checkFlags` |
| `zigInstallFlags` | `installFlags` |
### Variables honored by zig.hook {#zig-hook-variables-honored}
The following variables commonly used by `stdenv.mkDerivation` are honored by `zig.hook`.
- `prefixKey`
- `dontAddPrefix`

5
doc/interoperability.md Normal file
View File

@@ -0,0 +1,5 @@
# Interoperability Standards {#part-interoperability}
```{=include=} chapters
interoperability/cyclonedx.md
```

View File

@@ -0,0 +1,87 @@
# CycloneDX {#chap-interop-cyclonedx}
[OWASP](https://owasp.org/) [CycloneDX](https://cyclonedx.org/) is a Software [Bill of Materials](https://en.wikipedia.org/wiki/Bill_of_materials) (SBOM) standard.
The standards described here are for including Nix specific information within SBOMs in a way that is interoperable with external SBOM tooling.
## `nix` Namespace Property Taxonomy {#sec-interop.cylonedx-nix}
The following tables describe namespaces for [properties](https://cyclonedx.org/docs/1.6/json/#components_items_properties) that can be attached to components within SBOMs.
Component properties are lists of name-value-pairs where the values must be strings.
Properties with the same name may appear more than once.
Names and values are case-sensitive.
| Property | Description |
|------------------|-------------|
| `nix:store_path` | A Nix store path for the given component. This property should be contextualized by additional properties that describe the production of the store path, such as those from the `nix:narinfo:` and `nix:fod` namespaces. |
| Namespace | Description |
|---------------|-------------|
| [`nix:narinfo`](#sec-interop.cylonedx-narinfo) | Namespace for properties that are specific to how a component is stored as a [Nix archive](https://nixos.org/manual/nix/stable/glossary#gloss-nar) (NAR) in a [binary cache](https://nixos.org/manual/nix/stable/glossary#gloss-binary-cache). |
| [`nix:fod`](#sec-interop.cylonedx-fod) | Namespace for properties that describe a [fixed-output derivation](https://nixos.org/manual/nix/stable/glossary#gloss-fixed-output-derivation). |
### `nix:narinfo` {#sec-interop.cylonedx-narinfo}
Narinfo properties describe component archives that may be available from binary caches.
The `nix:narinfo` properties should be accompanied by a `nix:store_path` property within the same property list.
| Property | Description |
|---------------------------|-------------|
| `nix:narinfo:store_path` | Store path for the given store component. |
| `nix:narinfo:url` | URL path component. |
| `nix:narinfo:nar_hash` | Hash of the file system object part of the component when serialized as a Nix Archive. |
| `nix:narinfo:nar_size` | Size of the component when serialized as a Nix Archive. |
| `nix:narinfo:compression` | The compression format that component archive is in. |
| `nix:narinfo:file_hash` | A digest for the compressed component archive itself, as opposed to the data contained within. |
| `nix:narinfo:file_size` | The size of the compressed component archive itself. |
| `nix:narinfo:deriver` | The path to the derivation from which this component is produced. |
| `nix:narinfo:system` | The hardware and software platform on which this component is produced. |
| `nix:narinfo:sig` | Signatures claiming that this component is what it claims to be. |
| `nix:narinfo:ca` | Content address of this store object's file system object, used to compute its store path. |
| `nix:narinfo:references` | A whitespace separated array of store paths that this component references. |
### `nix:fod` {#sec-interop.cylonedx-fod}
FOD properties describe a [fixed-output derivation](https://nixos.org/manual/nix/stable/glossary#gloss-fixed-output-derivation).
The `nix:fod:method` property is required and must be accompanied by a `nix:store_path` property within the same property list.
All other properties in this namespace are method-specific.
To reproduce the build of a component the `nix:fod:method` value is resolved to an [appropriate function](#chap-pkgs-fetchers) within Nixpkgs whose arguments intersect with the given properties.
When generating `nix:fod` properties the method selected should be a stable function with a minimal number of arguments.
For example, the `fetchFromGitHub` is commonly used within Nixpkgs but should be reduced to a call to the function by which it is implemented, `fetchzip`.
| Property | Description |
|------------------|-------------|
| `nix:fod:method` | Nixpkgs function that produces this FOD. Required. Examples: `"fetchzip"`, `"fetchgit"` |
| `nix:fod:name` | Derivation name, present when method is `"fetchzip"` |
| `nix:fod:ref` | [Git ref](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefrefaref), present when method is `"fetchgit"` |
| `nix:fod:rev` | [Git rev](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefrevisionarevision), present when method is `"fetchgit"` |
| `nix:fod:sha256` | FOD hash |
| `nix:fod:url` | URL to fetch |
`nix:fod` properties may be extracted and evaluated to a derivation using code similar to the following, assuming a fictitious function `filterPropertiesToAttrs`:
```nix
{
pkgs,
filterPropertiesToAttrs,
properties,
}:
let
fodProps = filterPropertiesToAttrs "nix:fod:" properties;
methods = {
fetchzip =
{
name,
url,
sha256,
...
}:
pkgs.fetchzip { inherit name url sha256; };
};
in
methods.${fodProps.method} fodProps
```

View File

@@ -0,0 +1,5 @@
# OpenXR in NixOS
OpenXR is a standard for eXtended Reality (XR) applications and drivers (providers).
OpenXR runtime providers must ensure that the library path of the runtime's shared library can be loaded by Nix applications. If your OpenXR runtime provider runs in an FHSEnv, this means you may have to use `auto-patchelf` to link dependencies to the Nix store.

View File

@@ -0,0 +1,277 @@
# Agda {#agda}
## How to use Agda {#how-to-use-agda}
Agda is available as the [agda](https://search.nixos.org/packages?channel=unstable&show=agda&from=0&size=30&sort=relevance&query=agda)
package.
The `agda` package installs an Agda-wrapper, which calls `agda` with `--library-file`
set to a generated library-file within the nix store, this means your library-file in
`$HOME/.agda/libraries` will be ignored. By default the agda package installs Agda
with no libraries, i.e. the generated library-file is empty. To use Agda with libraries,
the `agda.withPackages` function can be used. This function either takes:
* A list of packages,
* or a function which returns a list of packages when given the `agdaPackages` attribute set,
* or an attribute set containing a list of packages and a GHC derivation for compilation (see below).
* or an attribute set containing a function which returns a list of packages when given the `agdaPackages` attribute set and a GHC derivation for compilation (see below).
For example, suppose we wanted a version of Agda which has access to the standard library. This can be obtained with the expressions:
```nix
agda.withPackages [ agdaPackages.standard-library ]
```
or
```nix
agda.withPackages (p: [ p.standard-library ])
```
or can be called as in the [Compiling Agda](#compiling-agda) section.
If you want to use a different version of a library (for instance a development version)
override the `src` attribute of the package to point to your local repository
```nix
agda.withPackages (p: [
(p.standard-library.overrideAttrs (oldAttrs: {
version = "local version";
src = /path/to/local/repo/agda-stdlib;
}))
])
```
You can also reference a GitHub repository
```nix
agda.withPackages (p: [
(p.standard-library.overrideAttrs (oldAttrs: {
version = "1.5";
src = fetchFromGitHub {
repo = "agda-stdlib";
owner = "agda";
rev = "v1.5";
hash = "sha256-nEyxYGSWIDNJqBfGpRDLiOAnlHJKEKAOMnIaqfVZzJk=";
};
}))
])
```
If you want to use a library not added to Nixpkgs, you can add a
dependency to a local library by calling `agdaPackages.mkDerivation`.
```nix
agda.withPackages (p: [
(p.mkDerivation {
pname = "your-agda-lib";
version = "1.0.0";
src = /path/to/your-agda-lib;
})
])
```
Again you can reference GitHub
```nix
agda.withPackages (p: [
(p.mkDerivation {
pname = "your-agda-lib";
version = "1.0.0";
src = fetchFromGitHub {
repo = "repo";
owner = "owner";
version = "...";
rev = "...";
hash = "...";
};
})
])
```
See [Building Agda Packages](#building-agda-packages) for more information on `mkDerivation`.
Agda will not by default use these libraries. To tell Agda to use a library we have some options:
* Call `agda` with the library flag:
```ShellSession
$ agda -l standard-library -i . MyFile.agda
```
* Write a `my-library.agda-lib` file for the project you are working on which may look like:
```
name: my-library
include: .
depend: standard-library
```
* Create the file `~/.agda/defaults` and add any libraries you want to use by default.
More information can be found in the [official Agda documentation on library management](https://agda.readthedocs.io/en/v2.6.1/tools/package-system.html).
## Compiling Agda {#compiling-agda}
Agda modules can be compiled using the GHC backend with the `--compile` flag. A version of `ghc` with `ieee754` is made available to the Agda program via the `--with-compiler` flag.
This can be overridden by a different version of `ghc` as follows:
```nix
agda.withPackages {
pkgs = [
# ...
];
ghc = haskell.compiler.ghcHEAD;
}
```
To install Agda without GHC, use `ghc = null;`.
## Writing Agda packages {#writing-agda-packages}
To write a nix derivation for an Agda library, first check that the library has a (single) `*.agda-lib` file.
A derivation can then be written using `agdaPackages.mkDerivation`. This has similar arguments to `stdenv.mkDerivation` with the following additions:
* `libraryName` should be the name that appears in the `*.agda-lib` file, defaulting to `pname`.
* `libraryFile` should be the file name of the `*.agda-lib` file, defaulting to `${libraryName}.agda-lib`.
Here is an example `default.nix`
```nix
{
nixpkgs ? <nixpkgs>,
}:
with (import nixpkgs { });
agdaPackages.mkDerivation {
version = "1.0";
pname = "my-agda-lib";
src = ./.;
buildInputs = [ agdaPackages.standard-library ];
}
```
### Building Agda packages {#building-agda-packages}
The default build phase for `agdaPackages.mkDerivation` runs `agda --build-library`.
If something else is needed to build the package (e.g. `make`) then the `buildPhase` should be overridden.
Additionally, a `preBuild` or `configurePhase` can be used if there are steps that need to be done prior to checking the library.
`agda` and the Agda libraries contained in `buildInputs` are made available during the build phase.
### Installing Agda packages {#installing-agda-packages}
The default install phase copies Agda source files, Agda interface files (`*.agdai`) and `*.agda-lib` files to the output directory.
This can be overridden.
By default, Agda sources are files ending on `.agda`, or literate Agda files ending on `.lagda`, `.lagda.tex`, `.lagda.org`, `.lagda.md`, `.lagda.rst`. The list of recognised Agda source extensions can be extended by setting the `extraExtensions` config variable.
## Maintaining the Agda package set on Nixpkgs {#maintaining-the-agda-package-set-on-nixpkgs}
We are aiming at providing all common Agda libraries as packages on `nixpkgs`,
and keeping them up to date.
Contributions and maintenance help is always appreciated,
but the maintenance effort is typically low since the Agda ecosystem is quite small.
The `nixpkgs` Agda package set tries to take up a role similar to that of [Stackage](https://www.stackage.org/) in the Haskell world.
It is a curated set of libraries that:
1. Always work together.
2. Are as up-to-date as possible.
While the Haskell ecosystem is huge, and Stackage is highly automated,
the Agda package set is small and can (still) be maintained by hand.
### Adding Agda packages to Nixpkgs {#adding-agda-packages-to-nixpkgs}
To add an Agda package to `nixpkgs`, the derivation should be written to `pkgs/development/libraries/agda/${library-name}/default.nix` and an entry should be added to `pkgs/top-level/agda-packages.nix`. Here it is called in a scope with access to all other Agda libraries, so the derivation could look like:
```nix
{
mkDerivation,
standard-library,
fetchFromGitHub,
}:
mkDerivation {
pname = "my-library";
version = "1.0";
src = <...>;
buildInputs = [ standard-library ];
meta = <...>;
}
```
You can look at other files under `pkgs/development/libraries/agda/` for more inspiration.
Note that the derivation function is called with `mkDerivation` set to `agdaPackages.mkDerivation`, therefore you
could use a similar set as in your `default.nix` from [Writing Agda Packages](#writing-agda-packages) with
`agdaPackages.mkDerivation` replaced with `mkDerivation`.
Here is an example skeleton derivation for iowa-stdlib:
```nix
mkDerivation {
version = "1.5.0";
pname = "iowa-stdlib";
src = <...>;
libraryFile = "";
libraryName = "IAL-1.3";
buildPhase = ''
runHook preBuild
patchShebangs find-deps.sh
make
runHook postBuild
'';
}
```
This library has a file called `.agda-lib`, and so we give an empty string to `libraryFile` as nothing precedes `.agda-lib` in the filename. This file contains `name: IAL-1.3`, and so we let `libraryName = "IAL-1.3"`. This library does not use an `Everything.agda` file and instead has a Makefile, so there is no need to set `everythingFile` and we set a custom `buildPhase`.
When writing an Agda package, it is essential to make sure that no `.agda-lib` file gets added to the store as a single file (for example by using `writeText`). This causes Agda to think that the nix store is a Agda library and it will attempt to write to it whenever it typechecks something. See [https://github.com/agda/agda/issues/4613](https://githcub.com/agda/agda/issues/4613).
In the pull request adding this library,
you can test whether it builds correctly by writing in a comment:
```
@ofborg build agdaPackages.my-library
```
### Maintaining Agda packages {#agda-maintaining-packages}
As mentioned before, the aim is to have a compatible, and up-to-date package set.
These two conditions sometimes exclude each other:
For example, if we update `agdaPackages.standard-library` because there was an upstream release,
this will typically break many reverse dependencies,
i.e. downstream Agda libraries that depend on the standard library.
In `nixpkgs` we are typically among the first to notice this,
since we have build tests in place to check this.
In a pull request updating e.g. the standard library, you should write the following comment:
```
@ofborg build agdaPackages.standard-library.passthru.tests
```
This will build all reverse dependencies of the standard library,
for example `agdaPackages.agda-categories`, or `agdaPackages.generic`.
In some cases it is useful to build _all_ Agda packages.
This can be done with the following Github comment:
```
@ofborg build agda.passthru.tests.allPackages
```
Sometimes, the builds of the reverse dependencies fail because they have not yet been updated and released.
You should drop the maintainers a quick issue notifying them of the breakage,
citing the build error (which you can get from the ofborg logs).
If you are motivated, you might even send a pull request that fixes it.
Usually, the maintainers will answer within a week or two with a new release.
Bumping the version of that reverse dependency should be a further commit on your PR.
In the rare case that a new release is not to be expected within an acceptable time,
mark the broken package as broken by setting `meta.broken = true;`.
This will exclude it from the build test.
It can be added later when it is fixed,
and does not hinder the advancement of the whole package set in the meantime.

View File

@@ -0,0 +1,384 @@
# Android {#android}
The Android build environment provides three major features and a number of
supporting features.
## Using androidenv with Android Studio {#using-androidenv-with-android-studio}
Use the `android-studio-full` attribute for a very complete Android SDK, including system images:
```nix
{ buildInputs = [ android-studio-full ]; }
```
This is identical to:
```nix
{ buildInputs = [ androidStudioPackages.stable.full ]; }
```
Alternatively, you can pass composeAndroidPackages to the `withSdk` passthrough:
```nix
{
buildInputs = [
(android-studio.withSdk (androidenv.composeAndroidPackages { includeNDK = true; }).androidsdk)
];
}
```
These will export `ANDROID_SDK_ROOT` and `ANDROID_NDK_ROOT` to the SDK and NDK directories
in the specified Android build environment.
## Deploying an Android SDK installation with plugins {#deploying-an-android-sdk-installation-with-plugins}
Alternatively, you can deploy the SDK separately with a desired set of plugins, or subsets of an SDK.
```nix
with import <nixpkgs> { };
let
androidComposition = androidenv.composeAndroidPackages {
platformVersions = [
"34"
"35"
"latest"
];
systemImageTypes = [ "google_apis_playstore" ];
abiVersions = [
"armeabi-v7a"
"arm64-v8a"
];
includeNDK = true;
includeExtras = [ "extras;google;auto" ];
};
in
androidComposition.androidsdk
```
The above function invocation states that we want an Android SDK with the above
specified plugin versions. By default, most plugins are disabled. Notable
exceptions are the tools, platform-tools and build-tools sub packages.
The following parameters are supported:
* `cmdLineToolsVersion` specifies the version of the `cmdline-tools` package to use.
It defaults to the latest.
* `toolsVersion`, specifies the version of the `tools` package. Notice `tools` is
obsolete, and currently only `26.1.1` is available, so there's not a lot of
options here, however, you can set it as `null` if you don't want it. It defaults
to the latest.
* `platformToolsVersion` specifies the version of the `platform-tools` plugin.
It defaults to the latest.
* `buildToolsVersions` specifies the versions of the `build-tools` plugins to
use. It defaults to the latest.
* `includeEmulator` specifies whether to deploy the emulator package (`false`
by default). When enabled, the version of the emulator to deploy can be
specified by setting the `emulatorVersion` parameter. If set to
`"if-supported"`, it will deploy the emulator if it's supported by the system.
* `includeCmake` specifies whether CMake should be included. It defaults to true
on x86-64 and Darwin platforms, and also supports `"if-supported"`.
* `cmakeVersions` specifies which CMake versions should be deployed.
It defaults to the latest.
* `includeNDK` specifies that the Android NDK bundle should be included.
Defaults to `false` though can be set to `true` or `"if-supported"`.
* `ndkVersions` specifies the NDK versions that we want to use. These are linked
under the `ndk` directory of the SDK root, and the first is linked under the
`ndk-bundle` directory. It defaults to the latest.
* `ndkVersion` is equivalent to specifying one entry in `ndkVersions`, and
`ndkVersions` overrides this parameter if provided.
* `includeExtras` is an array of identifier strings referring to arbitrary
add-on packages that should be installed. Note that extras may not be compatible
with all platforms (for example, the Google TV head unit, which does not
have an aarch64-linux compile).
* `platformVersions` specifies which platform SDK versions should be included.
It defaults to including only the latest API level, though you can add more.
* `numLatestPlatformVersions` specifies how many of the latest API levels to include,
if you are using the default for `platformVersions`. It defaults to 1, though you can
increase this to, for example, 5 to get the last 5 years of Android API packages.
* `minPlatformVersion` and `maxPlatformVersion` take priority over `platformVersions`
if both are provided. Note that `maxPlatformVersion` always defaults to the latest
Android SDK platform version, allowing you to specify `minPlatformVersion` to describe
the minimum SDK version your Android composition supports.
For each platform version that has been specified, we can apply the following
options:
* `includeSystemImages` specifies whether a system image for each platform SDK
should be included.
* `includeSources` specifies whether the sources for each SDK version should be
included.
* `useGoogleAPIs` specifies that for each selected platform version the
Google API should be included.
* `useGoogleTVAddOns` specifies that for each selected platform version the
Google TV add-on should be included.
For each requested system image we can specify the following options:
* `systemImageTypes` specifies what kind of system images should be included.
Defaults to: `default`.
* `abiVersions` specifies what kind of ABI version of each system image should
be included. Defaults to `armeabi-v7a` and `arm64-v8a`.
Most of the function arguments have reasonable default settings, preferring the latest
versions of tools when possible. You can additionally specify "latest" for any plugin version
that you do not care about, and just want the latest of.
You can specify license names:
* `extraLicenses` is a list of license names.
You can get these names from repo.json or `querypackages.sh licenses`. The SDK
license (`android-sdk-license`) is accepted for you if you set accept_license
to true. If you are doing something like working with preview SDKs, you will
want to add `android-sdk-preview-license` or whichever license applies here.
Additionally, you can override the repositories that composeAndroidPackages will
pull from:
* `repoJson` specifies a path to a generated repo.json file. You can generate this
by running `generate.sh`, which in turn will call into `mkrepo.rb`.
* `repoXmls` is an attribute set containing paths to repo XML files. If specified,
it takes priority over `repoJson`, and will trigger a local build writing out a
repo.json to the Nix store based on the given repository XMLs. Note that this uses
import-from-derivation.
```nix
{
repoXmls = {
packages = [ ./xml/repository2-1.xml ];
images = [
./xml/android-sys-img2-1.xml
./xml/android-tv-sys-img2-1.xml
./xml/android-wear-sys-img2-1.xml
./xml/android-wear-cn-sys-img2-1.xml
./xml/google_apis-sys-img2-1.xml
./xml/google_apis_playstore-sys-img2-1.xml
];
addons = [ ./xml/addon2-1.xml ];
};
}
```
When building the above expression with:
```bash
$ nix-build
```
The Android SDK gets deployed with all desired plugin versions.
We can also deploy subsets of the Android SDK. For example, to only the
`platform-tools` package, you can evaluate the following expression:
```nix
with import <nixpkgs> { };
let
androidComposition = androidenv.composeAndroidPackages {
# ...
};
in
androidComposition.platform-tools
```
## Using predefined Android package compositions {#using-predefined-android-package-compositions}
In addition to composing an Android package set manually, it is also possible
to use a predefined composition that contains a fairly complete set of Android packages:
The following Nix expression can be used to deploy the entire SDK:
```nix
with import <nixpkgs> { };
androidenv.androidPkgs.androidsdk
```
It is also possible to use one plugin only:
```nix
with import <nixpkgs> { };
androidenv.androidPkgs.platform-tools
```
## Spawning emulator instances {#spawning-emulator-instances}
For testing purposes, it can also be quite convenient to automatically generate
scripts that spawn emulator instances with all desired configuration settings.
An emulator spawn script can be configured by invoking the `emulateApp {}`
function:
```nix
with import <nixpkgs> { };
androidenv.emulateApp {
name = "emulate-MyAndroidApp";
platformVersion = "28";
abiVersion = "x86"; # armeabi-v7a, mips, x86_64
systemImageType = "google_apis_playstore";
}
```
Additional flags may be applied to the Android SDK's emulator through the runtime environment variable `$NIX_ANDROID_EMULATOR_FLAGS`.
It is also possible to specify an APK to deploy inside the emulator
and the package and activity names to launch it:
```nix
with import <nixpkgs> { };
androidenv.emulateApp {
name = "emulate-MyAndroidApp";
platformVersion = "24";
abiVersion = "armeabi-v7a"; # mips, x86, x86_64
systemImageType = "default";
app = ./MyApp.apk;
package = "MyApp";
activity = "MainActivity";
}
```
In addition to prebuilt APKs, you can also bind the APK parameter to a
`buildApp {}` function invocation shown in the previous example.
## Notes on environment variables in Android projects {#notes-on-environment-variables-in-android-projects}
* `ANDROID_HOME` should point to the Android SDK. In your Nix expressions, this should be
`${androidComposition.androidsdk}/libexec/android-sdk`. Note that `ANDROID_SDK_ROOT` is deprecated,
but if you rely on tools that need it, you can export it too.
* `ANDROID_NDK_ROOT` should point to the Android NDK, if you're doing NDK development.
In your Nix expressions, this should be `${ANDROID_HOME}/ndk-bundle`.
If you are running the Android Gradle plugin, you need to export GRADLE_OPTS to override aapt2
to point to the aapt2 binary in the Nix store as well, or use a FHS environment so the packaged
aapt2 can run. If you don't want to use a FHS environment, something like this should work:
```nix
let
buildToolsVersion = "30.0.3";
# Use buildToolsVersion when you define androidComposition
androidComposition = <...>;
in
pkgs.mkShell rec {
ANDROID_HOME = "${androidComposition.androidsdk}/libexec/android-sdk";
ANDROID_NDK_ROOT = "${ANDROID_HOME}/ndk-bundle";
# Use the same buildToolsVersion here
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_HOME}/build-tools/${buildToolsVersion}/aapt2";
}
```
If you are using cmake, you need to add it to PATH in a shell hook or FHS env profile.
The path is suffixed with a build number, but properly prefixed with the version.
So, something like this should suffice:
```nix
let
cmakeVersion = "3.10.2";
# Use cmakeVersion when you define androidComposition
androidComposition = <...>;
in
pkgs.mkShell rec {
ANDROID_HOME = "${androidComposition.androidsdk}/libexec/android-sdk";
ANDROID_NDK_ROOT = "${ANDROID_HOME}/ndk-bundle";
# Use the same cmakeVersion here
shellHook = ''
export PATH="$(echo "$ANDROID_HOME/cmake/${cmakeVersion}".*/bin):$PATH"
'';
}
```
Note that running Android Studio with ANDROID_HOME set will automatically write a
`local.properties` file with `sdk.dir` set to $ANDROID_HOME if one does not already
exist. If you are using the NDK as well, you may have to add `ndk.dir` to this file.
An example `shell.nix` that does all this for you is provided in `examples/shell.nix`.
This shell.nix includes a shell hook that overwrites local.properties with the correct
sdk.dir and ndk.dir values. This will ensure that the SDK and NDK directories will
both be correct when you run Android Studio inside nix-shell.
## Notes on improving build.gradle compatibility {#notes-on-improving-build.gradle-compatibility}
Ensure that your buildToolsVersion and ndkVersion match what is declared in androidenv.
If you are using cmake, make sure its declared version is correct too.
Otherwise, you may get cryptic errors from aapt2 and the Android Gradle plugin warning
that it cannot install the build tools because the SDK directory is not writeable.
```gradle
android {
buildToolsVersion "30.0.3"
ndkVersion = "22.0.7026061"
externalNativeBuild {
cmake {
version "3.10.2"
}
}
}
```
## Querying the available versions of each plugin {#querying-the-available-versions-of-each-plugin}
All androidenv packages are available on [search.nixos.org](https://search.nixos.org).
Note that `aarch64-linux` compatibility is currently spotty, though `x86_64-linux` and `aarch64-darwin`
are well supported. This is because Google's repository definitions mark some packages for "all" architectures
that are really only for `x86_64` or `aarch64`.
## Updating the generated expressions {#updating-the-generated-expressions}
repo.json is generated from XML files that the Android Studio package manager uses.
To update the expressions run the `update.sh` script that is stored in the
`pkgs/development/mobile/androidenv/` subdirectory:
```bash
./update.sh
```
This is run automatically by the nixpkgs update script.
## Building an Android application with Ant {#building-an-android-application-with-ant}
In addition to the SDK, it is also possible to build an Ant-based Android
project and automatically deploy all the Android plugins that a project
requires. Most newer Android projects use Gradle, and this is included for historical
purposes.
```nix
with import <nixpkgs> { };
androidenv.buildApp {
name = "MyAndroidApp";
src = ./myappsources;
release = true;
# If release is set to true, you need to specify the following parameters
keyStore = ./keystore;
keyAlias = "myfirstapp";
keyStorePassword = "mykeystore";
keyAliasPassword = "myfirstapp";
# Any Android SDK parameters that install all the relevant plugins that a
# build requires
platformVersions = [ "24" ];
# When we include the NDK, then ndk-build is invoked before Ant gets invoked
includeNDK = true;
}
```
Aside from the app-specific build parameters (`name`, `src`, `release` and
keystore parameters), the `buildApp {}` function supports all the function
parameters that the SDK composition function (the function shown in the
previous section) supports.
This build function is particularly useful when it is desired to use
[Hydra](https://nixos.org/hydra): the Nix-based continuous integration solution
to build Android apps. An Android APK gets exposed as a build product and can be
installed on any Android device with a web browser by navigating to the build
result page.

View File

@@ -0,0 +1,43 @@
# Astal {#astal}
Astal is a collection of building blocks for creating custom desktop shells.
## Bundling {#astal-bundling}
Bundling an Astal application is done using the `ags` tool. You can use it like this:
```nix
ags.bundle {
pname = "hyprpanel";
version = "1.0.0";
src = fetchFromGitHub {
#...
};
# change your entry file (default is `app.ts`)
entry = "app.ts";
dependencies = [
# list here astal modules that your package depends on
# `astal3`, `astal4` and `astal.io` are automatically included
astal.apps
astal.battery
astal.bluetooth
# you can also list here other runtime dependencies
hypridle
hyprpicker
hyprsunset
];
# GTK 4 support is opt-in
enableGtk4 = true;
meta = {
#...
};
}
```
You can also pass all other arguments that are supported by `stdenv.mkDerivation`.

View File

@@ -0,0 +1,415 @@
# BEAM Languages (Erlang, Elixir & LFE) {#sec-beam}
## Introduction {#beam-introduction}
In this document and related Nix expressions, we use the term, _BEAM_, to describe the environment. BEAM is the name of the Erlang Virtual Machine and, as far as we're concerned, from a packaging perspective, all languages that run on the BEAM are interchangeable. That which varies, like the build system, is transparent to users of any given BEAM package, so we make no distinction.
## Available versions and deprecations schedule {#available-versions-and-deprecations-schedule}
### Elixir {#elixir}
Nixpkgs follows the [official elixir deprecation schedule](https://hexdocs.pm/elixir/compatibility-and-deprecations.html) and keeps the last 5 released versions of Elixir available.
## Structure {#beam-structure}
All BEAM-related expressions are available via the top-level `beam` attribute, which includes:
- `interpreters`: a set of compilers running on the BEAM, including multiple Erlang/OTP versions (`beam.interpreters.erlang_22`, etc), Elixir (`beam.interpreters.elixir`) and LFE (Lisp Flavoured Erlang) (`beam.interpreters.lfe`).
- `packages`: a set of package builders (Mix and rebar3), each compiled with a specific Erlang/OTP version, e.g. `beam.packages.erlang22`.
The default Erlang compiler, defined by `beam.interpreters.erlang`, is aliased as `erlang`. The default BEAM package set is defined by `beam.packages.erlang` and aliased at the top level as `beamPackages`.
To create a package builder built with a custom Erlang version, use the lambda, `beam.packagesWith`, which accepts an Erlang/OTP derivation and produces a package builder similar to `beam.packages.erlang`.
Many Erlang/OTP distributions available in `beam.interpreters` have versions with ODBC and/or Java enabled or without wx (no observer support). For example, there's `beam.interpreters.erlang_22_odbc_javac`, which corresponds to `beam.interpreters.erlang_22` and `beam.interpreters.erlang_22_nox`, which corresponds to `beam.interpreters.erlang_22`.
## Build Tools {#build-tools}
### Rebar3 {#build-tools-rebar3}
We provide a version of Rebar3, under `rebar3`. We also provide a helper to fetch Rebar3 dependencies from a lockfile under `fetchRebar3Deps`.
We also provide a version on Rebar3 with plugins included, under `rebar3WithPlugins`. This package is a function which takes two arguments: `plugins`, a list of nix derivations to include as plugins (loaded only when specified in `rebar.config`), and `globalPlugins`, which should always be loaded by rebar3. Example: `rebar3WithPlugins { globalPlugins = [beamPackages.pc]; }`.
When adding a new plugin it is important that the `packageName` attribute is the same as the atom used by rebar3 to refer to the plugin.
### Mix & Erlang.mk {#build-tools-other}
Erlang.mk works exactly as expected. There is a bootstrap process that needs to be run, which is supported by the `buildErlangMk` derivation.
For Elixir applications use `mixRelease` to make a release. See examples for more details.
There is also a `buildMix` helper, whose behavior is closer to that of `buildErlangMk` and `buildRebar3`. The primary difference is that mixRelease makes a release, while buildMix only builds the package, making it useful for libraries and other dependencies.
## How to Install BEAM Packages {#how-to-install-beam-packages}
BEAM builders are not registered at the top level, because they are not relevant to the vast majority of Nix users.
To use any of those builders into your environment, refer to them by their attribute path under `beamPackages`, e.g. `beamPackages.rebar3`:
::: {.example #ex-beam-ephemeral-shell}
# Ephemeral shell
```ShellSession
$ nix-shell -p beamPackages.rebar3
```
:::
::: {.example #ex-beam-declarative-shell}
# Declarative shell
```nix
let
pkgs = import <nixpkgs> {
config = { };
overlays = [ ];
};
in
pkgs.mkShell { packages = [ pkgs.beamPackages.rebar3 ]; }
```
:::
## Packaging BEAM Applications {#packaging-beam-applications}
### Erlang Applications {#packaging-erlang-applications}
#### Rebar3 Packages {#rebar3-packages}
The Nix function, `buildRebar3`, defined in `beam.packages.erlang.buildRebar3` and aliased at the top level, can be used to build a derivation that understands how to build a Rebar3 project.
If a package needs to compile native code via Rebar3's port compilation mechanism, add `compilePort = true;` to the derivation.
#### Erlang.mk Packages {#erlang-mk-packages}
Erlang.mk functions similarly to Rebar3, except we use `buildErlangMk` instead of `buildRebar3`.
#### Mix Packages {#mix-packages}
`mixRelease` is used to make a release in the mix sense. Dependencies will need to be fetched with `fetchMixDeps` and passed to it.
#### mixRelease - Elixir Phoenix example {#mix-release-elixir-phoenix-example}
there are 3 steps: frontend dependencies (javascript), backend dependencies (elixir), and the final derivation that puts both of those together
##### mixRelease - Frontend dependencies (javascript) {#mix-release-javascript-deps}
For phoenix projects, inside of Nixpkgs you can either use yarn2nix (mkYarnModule) or node2nix. An example with yarn2nix can be found [here](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/web-apps/plausible/default.nix#L39). An example with node2nix will follow. To package something outside of nixpkgs, you have alternatives like [npmlock2nix](https://github.com/nix-community/npmlock2nix) or [nix-npm-buildpackage](https://github.com/serokell/nix-npm-buildpackage)
##### mixRelease - backend dependencies (mix) {#mix-release-mix-deps}
There are 2 ways to package backend dependencies. With mix2nix and with a fixed-output-derivation (FOD).
###### mix2nix {#mix2nix}
`mix2nix` is a cli tool available in Nixpkgs. It will generate a Nix expression from a `mix.lock` file. It is quite standard in the 2nix tool series.
Note that currently mix2nix can't handle git dependencies inside the mix.lock file. If you have git dependencies, you can either add them manually (see [example](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/pleroma/default.nix#L20)) or use the FOD method.
The advantage of using mix2nix is that nix will know your whole dependency graph. On a dependency update, this won't trigger a full rebuild and download of all the dependencies, where FOD will do so.
Practical steps:
- run `mix2nix > mix_deps.nix` in the upstream repo.
- pass `mixNixDeps = with pkgs; import ./mix_deps.nix { inherit lib beamPackages; };` as an argument to mixRelease.
If there are git dependencies.
- You'll need to fix the version artificially in mix.exs and regenerate the mix.lock with fixed version (on upstream). This will enable you to run `mix2nix > mix_deps.nix`.
- From the mix_deps.nix file, remove the dependencies that had git versions and pass them as an override to the import function.
```nix
{
mixNixDeps = import ./mix.nix {
inherit beamPackages lib;
overrides = (
final: prev: {
# mix2nix does not support git dependencies yet,
# so we need to add them manually
prometheus_ex = beamPackages.buildMix rec {
name = "prometheus_ex";
version = "3.0.5";
# Change the argument src with the git src that you actually need
src = fetchFromGitLab {
domain = "git.pleroma.social";
group = "pleroma";
owner = "elixir-libraries";
repo = "prometheus.ex";
rev = "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5";
hash = "sha256-U17LlN6aGUKUFnT4XyYXppRN+TvUBIBRHEUsfeIiGOw=";
};
# you can re-use the same beamDeps argument as generated
beamDeps = with final; [ prometheus ];
};
}
);
};
}
```
You will need to run the build process once to fix the hash to correspond to your new git src.
###### FOD {#fixed-output-derivation}
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir-ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir-ls/default.nix) for a usage example of FOD.
Practical steps
- start with the following argument to mixRelease
```nix
{
mixFodDeps = fetchMixDeps {
pname = "mix-deps-${pname}";
inherit src version;
hash = lib.fakeHash;
};
}
```
The first build will complain about the hash value, you can replace with the suggested value after that.
Note that if after you've replaced the value, nix suggests another hash, then mix is not fetching the dependencies reproducibly. An FOD will not work in that case and you will have to use mix2nix.
##### mixRelease - example {#mix-release-example}
Here is how your `default.nix` file would look for a Phoenix project.
```nix
with import <nixpkgs> { };
let
# beam.interpreters.erlang_26 is available if you need a particular version
packages = beam.packagesWith beam.interpreters.erlang;
pname = "your_project";
version = "0.0.1";
src = builtins.fetchgit {
url = "ssh://git@github.com/your_id/your_repo";
rev = "replace_with_your_commit";
};
# if using mix2nix you can use the mixNixDeps attribute
mixFodDeps = packages.fetchMixDeps {
pname = "mix-deps-${pname}";
inherit src version;
# nix will complain and tell you the right value to replace this with
hash = lib.fakeHash;
mixEnv = ""; # default is "prod", when empty includes all dependencies, such as "dev", "test".
# if you have build time environment variables add them here
MY_ENV_VAR = "my_value";
};
nodeDependencies = (pkgs.callPackage ./assets/default.nix { }).shell.nodeDependencies;
in
packages.mixRelease {
inherit
src
pname
version
mixFodDeps
;
# if you have build time environment variables add them here
MY_ENV_VAR = "my_value";
postBuild = ''
ln -sf ${nodeDependencies}/lib/node_modules assets/node_modules
npm run deploy --prefix ./assets
# for external task you need a workaround for the no deps check flag
# https://github.com/phoenixframework/phoenix/issues/2690
mix do deps.loadpaths --no-deps-check, phx.digest
mix phx.digest --no-deps-check
'';
}
```
Setup will require the following steps:
- Move your secrets to runtime environment variables. For more information refer to the [runtime.exs docs](https://hexdocs.pm/mix/Mix.Tasks.Release.html#module-runtime-configuration). On a fresh Phoenix build that would mean that both `DATABASE_URL` and `SECRET_KEY` need to be moved to `runtime.exs`.
- `cd assets` and `nix-shell -p node2nix --run "node2nix --development"` will generate a Nix expression containing your frontend dependencies
- commit and push those changes
- you can now `nix-build .`
- To run the release, set the `RELEASE_TMP` environment variable to a directory that your program has write access to. It will be used to store the BEAM settings.
#### Example of creating a service for an Elixir - Phoenix project {#example-of-creating-a-service-for-an-elixir---phoenix-project}
In order to create a service with your release, you could add a `service.nix`
in your project with the following
```nix
{
config,
pkgs,
lib,
...
}:
let
release = pkgs.callPackage ./default.nix;
release_name = "app";
working_directory = "/home/app";
in
{
systemd.services.${release_name} = {
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"postgresql.target"
];
# note that if you are connecting to a postgres instance on a different host
# postgresql.target should not be included in the requires.
requires = [
"network-online.target"
"postgresql.target"
];
description = "my app";
environment = {
# RELEASE_TMP is used to write the state of the
# VM configuration when the system is running
# it needs to be a writable directory
RELEASE_TMP = working_directory;
# can be generated in an elixir console with
# Base.encode32(:crypto.strong_rand_bytes(32))
RELEASE_COOKIE = "my_cookie";
MY_VAR = "my_var";
};
serviceConfig = {
Type = "exec";
DynamicUser = true;
WorkingDirectory = working_directory;
# Implied by DynamicUser, but just to emphasize due to RELEASE_TMP
PrivateTmp = true;
ExecStart = ''
${release}/bin/${release_name} start
'';
ExecStop = ''
${release}/bin/${release_name} stop
'';
ExecReload = ''
${release}/bin/${release_name} restart
'';
Restart = "on-failure";
RestartSec = 5;
};
unitConfig = {
StartLimitBurst = 3;
StartLimitInterval = 10;
};
# disksup requires bash
path = [ pkgs.bash ];
};
# in case you have migration scripts or you want to use a remote shell
environment.systemPackages = [ release ];
}
```
## How to Develop {#how-to-develop}
### Creating a Shell {#creating-a-shell}
Usually, we need to create a `shell.nix` file and do our development inside the environment specified therein. Just install your version of Erlang and any other interpreters, and then use your normal build tools. As an example, with Elixir:
```nix
{
pkgs ? import <nixpkgs> { },
}:
with pkgs;
let
elixir = beam.packages.erlang_27.elixir_1_18;
in
mkShell { buildInputs = [ elixir ]; }
```
### Using an overlay {#beam-using-overlays}
If you need to use an overlay to change some attributes of a derivation, e.g. if you need a bugfix from a version that is not yet available in Nixpkgs, you can override attributes such as `version` (and the corresponding `hash`) and then use this overlay in your development environment:
#### `shell.nix` {#beam-using-overlays-shell.nix}
```nix
let
elixir_1_18_1_overlay = (
self: super: {
elixir_1_18 = super.elixir_1_18.override {
version = "1.18.1";
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
}
);
pkgs = import <nixpkgs> { overlays = [ elixir_1_18_1_overlay ]; };
in
with pkgs;
mkShell { buildInputs = [ elixir_1_18 ]; }
```
#### Elixir - Phoenix project {#elixir---phoenix-project}
Here is an example `shell.nix`.
```nix
with import <nixpkgs> { };
let
# define packages to install
basePackages = [
git
# replace with beam.packages.erlang.elixir_1_18 if you need
beam.packages.erlang.elixir
nodejs
postgresql_14
# only used for frontend dependencies
# you are free to use yarn2nix as well
nodePackages.node2nix
# formatting js file
nodePackages.prettier
];
inputs = basePackages ++ lib.optionals stdenv.hostPlatform.isLinux [ inotify-tools ];
# define shell startup command
hooks = ''
# this allows mix to work on the local directory
mkdir -p .nix-mix .nix-hex
export MIX_HOME=$PWD/.nix-mix
export HEX_HOME=$PWD/.nix-mix
# make hex from Nixpkgs available
# `mix local.hex` will install hex into MIX_HOME and should take precedence
export MIX_PATH="${beam.packages.erlang.hex}/lib/erlang/lib/hex/ebin"
export PATH=$MIX_HOME/bin:$HEX_HOME/bin:$PATH
export LANG=C.UTF-8
# keep your shell history in iex
export ERL_AFLAGS="-kernel shell_history enabled"
# postges related
# keep all your db data in a folder inside the project
export PGDATA="$PWD/db"
# phoenix related env vars
export POOL_SIZE=15
export DB_URL="postgresql://postgres:postgres@localhost:5432/db"
export PORT=4000
export MIX_ENV=dev
# add your project env vars here, word readable in the nix store.
export ENV_VAR="your_env_var"
'';
in
mkShell {
buildInputs = inputs;
shellHook = hooks;
}
```
Initializing the project will require the following steps:
- create the db directory `initdb ./db` (inside your mix project folder)
- create the postgres user `createuser postgres -ds`
- create the db `createdb db`
- start the postgres instance `pg_ctl -l "$PGDATA/server.log" start`
- add the `/db` folder to your `.gitignore`
- you can start your Phoenix server and get a shell with `iex -S mix phx.server`

View File

@@ -0,0 +1,84 @@
# CHICKEN {#sec-chicken}
[CHICKEN](https://call-cc.org/) is a
[R⁵RS](https://schemers.org/Documents/Standards/R5RS/HTML/)-compliant Scheme
compiler. It includes an interactive mode and a custom package format, "eggs".
## Using Eggs {#sec-chicken-using}
Eggs described in Nixpkgs are available inside the
`chickenPackages.chickenEggs` attrset. Including an egg as a build input is
done in the typical Nix fashion. For example, to include support for [SRFI
189](https://srfi.schemers.org/srfi-189/srfi-189.html) in a derivation, one
might write:
```nix
{
buildInputs = [
chicken
chickenPackages.chickenEggs.srfi-189
];
}
```
Both `chicken` and its eggs have a setup hook which configures the environment
variables `CHICKEN_INCLUDE_PATH` and `CHICKEN_REPOSITORY_PATH`.
## Updating Eggs {#sec-chicken-updating-eggs}
Nixpkgs only knows about a subset of all published eggs. It uses
[egg2nix](https://github.com/the-kenny/egg2nix) to generate a
package set from a list of eggs to include.
The package set is regenerated by running the following shell commands:
```
$ nix-shell -p chickenPackages.egg2nix
$ cd pkgs/development/compilers/chicken/5/
$ egg2nix eggs.scm > eggs.nix
```
## Adding Eggs {#sec-chicken-adding-eggs}
When we run `egg2nix`, we obtain one collection of eggs with
mutually-compatible versions. This means that when we add new eggs, we may
need to update existing eggs. To keep those separate, follow the procedure for
updating eggs before including more eggs.
To include more eggs, edit `pkgs/development/compilers/chicken/5/eggs.scm`.
The first section of this file lists eggs which are required by `egg2nix`
itself; all other eggs go into the second section. After editing, follow the
procedure for updating eggs.
## Override Scope {#sec-chicken-override-scope}
The chicken package and its eggs, respectively, reside in a scope. This means,
the scope can be overridden to affect other packages in it.
This example shows how to use a local copy of `srfi-180` and have it affect
all the other eggs:
```nix
let
myChickenPackages = pkgs.chickenPackages.overrideScope (
self: super: {
# The chicken package itself can be overridden to affect the whole ecosystem.
# chicken = super.chicken.overrideAttrs {
# src = ...
# };
chickenEggs = super.chickenEggs.overrideScope (
eggself: eggsuper: {
srfi-180 = eggsuper.srfi-180.overrideAttrs {
# path to a local copy of srfi-180
src = <...>;
};
}
);
}
);
# Here, `myChickenPackages.chickenEggs.json-rpc`, which depends on `srfi-180` will use
# the local copy of `srfi-180`.
in
<...>
```

View File

@@ -0,0 +1,184 @@
# Coq and coq packages {#sec-language-coq}
## Coq derivation: `coq` {#coq-derivation-coq}
The Coq derivation is overridable through the `coq.override overrides`, where overrides is an attribute set which contains the arguments to override. We recommend overriding either of the following:
* `version` (optional, defaults to the latest version of Coq selected for nixpkgs, see `pkgs/top-level/coq-packages` to witness this choice), which follows the conventions explained in the `coqPackages` section below,
* `customOCamlPackages` (optional, defaults to `null`, which lets Coq choose a version automatically), which can be set to any of the ocaml packages attribute of `ocaml-ng` (such as `ocaml-ng.ocamlPackages_4_10` which is the default for Coq 8.11 for example).
* `coq-version` (optional, defaults to the short version e.g. "8.10"), is a version number of the form "x.y" that indicates which Coq's version build behavior to mimic when using a source which is not a release. E.g. `coq.override { version = "d370a9d1328a4e1cdb9d02ee032f605a9d94ec7a"; coq-version = "8.10"; }`.
The associated package set can be obtained using `mkCoqPackages coq`, where `coq` is the derivation to use.
## Coq packages attribute sets: `coqPackages` {#coq-packages-attribute-sets-coqpackages}
The recommended way of defining a derivation for a Coq library, is to use the `coqPackages.mkCoqDerivation` function, which is essentially a specialization of `mkDerivation` taking into account most of the specifics of Coq libraries. The following attributes are supported:
* `pname` (required) is the name of the package,
* `version` (optional, defaults to `null`), is the version to fetch and build,
this attribute is interpreted in several ways depending on its type and pattern:
* if it is a known released version string, i.e. from the `release` attribute below, the according release is picked, and the `version` attribute of the resulting derivation is set to this release string,
* if it is a majorMinor `"x.y"` prefix of a known released version (as defined above), then the latest `"x.y.z"` known released version is selected (for the ordering given by `versionAtLeast`),
* if it is a path or a string representing an absolute path (i.e. starting with `"/"`), the provided path is selected as a source, and the `version` attribute of the resulting derivation is set to `"dev"`,
* if it is a string of the form `owner:branch` then it tries to download the `branch` of owner `owner` for a project of the same name using the same vcs, and the `version` attribute of the resulting derivation is set to `"dev"`, additionally if the owner is not provided (i.e. if the `owner:` prefix is missing), it defaults to the original owner of the package (see below),
* if it is a string of the form `"#N"`, and the domain is github, then it tries to download the current head of the pull request `#N` from github,
* `defaultVersion` (optional). Coq libraries may be compatible with some specific versions of Coq only. The `defaultVersion` attribute is used when no `version` is provided (or if `version = null`) to select the version of the library to use by default, depending on the context. This selection will mainly depend on a `coq` version number but also possibly on other packages versions (e.g. `mathcomp`). If its value ends up to be `null`, the package is marked for removal in end-user `coqPackages` attribute set.
* `release` (optional, defaults to `{}`), lists all the known releases of the library and for each of them provides an attribute set with at least a `hash` attribute (you may put the empty string `""` in order to automatically insert a fake hash, this will trigger an error which will allow you to find the correct hash), each attribute set of the list of releases also takes optional overloading arguments for the fetcher as below (i.e.`domain`, `owner`, `repo`, `rev`, `artifact` assuming the default fetcher is used) and optional overrides for the result of the fetcher (i.e. `version` and `src`).
* `fetcher` (optional, defaults to a generic fetching mechanism supporting github or gitlab based infrastructures), is a function that takes at least an `owner`, a `repo`, a `rev`, and a `hash` and returns an attribute set with a `version` and `src`.
* `repo` (optional, defaults to the value of `pname`),
* `owner` (optional, defaults to `"coq-community"`).
* `domain` (optional, defaults to `"github.com"`), domains including the strings `"github"` or `"gitlab"` in their names are automatically supported, otherwise, one must change the `fetcher` argument to support them (cf `pkgs/development/coq-modules/heq/default.nix` for an example),
* `releaseRev` (optional, defaults to `(v: v)`), provides a default mapping from release names to revision hashes/branch names/tags,
* `releaseArtifact` (optional, defaults to `(v: null)`), provides a default mapping from release names to artifact names (only works for github artifact for now),
* `displayVersion` (optional), provides a way to alter the computation of `name` from `pname`, by explaining how to display version numbers,
* `namePrefix` (optional, defaults to `[ "coq" ]`), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
* `nativeBuildInputs` (optional), is a list of executables that are required to build the current derivation, in addition to the default ones (namely `which`, `dune` and `ocaml` depending on whether `useDune`, `useDuneifVersion` and `mlPlugin` are set).
* `extraNativeBuildInputs` (optional, deprecated), an additional list of derivation to add to `nativeBuildInputs`,
* `overrideNativeBuildInputs` (optional) replaces the default list of derivation to which `nativeBuildInputs` and `extraNativeBuildInputs` adds extra elements,
* `buildInputs` (optional), is a list of libraries and dependencies that are required to build and run the current derivation, in addition to the default one `[ coq ]`,
* `extraBuildInputs` (optional, deprecated), an additional list of derivation to add to `buildInputs`,
* `overrideBuildInputs` (optional) replaces the default list of derivation to which `buildInputs` and `extraBuildInputs` adds extras elements,
* `propagatedBuildInputs` (optional) is passed as is to `mkDerivation`, we recommend to use this for Coq libraries and Coq plugin dependencies, as this makes sure the paths of the compiled libraries and plugins will always be added to the build environments of subsequent derivation, which is necessary for Coq packages to work correctly,
* `mlPlugin` (optional, defaults to `false`). Some extensions (plugins) might require OCaml and sometimes other OCaml packages. Standard dependencies can be added by setting the current option to `true`. For a finer grain control, the `coq.ocamlPackages` attribute can be used in `nativeBuildInputs`, `buildInputs`, and `propagatedBuildInputs` to depend on the same package set Coq was built against.
* `useDuneifVersion` (optional, default to `(x: false)` uses Dune to build the package if the provided predicate evaluates to true on the version, e.g. `useDuneifVersion = versions.isGe "1.1"` will use dune if the version of the package is greater or equal to `"1.1"`,
* `useDune` (optional, defaults to `false`) uses Dune to build the package if set to true, the presence of this attribute overrides the behavior of the previous one.
* `opam-name` (optional, defaults to concatenating with a dash separator the components of `namePrefix` and `pname`), name of the Dune package to build.
* `enableParallelBuilding` (optional, defaults to `true`), since it is activated by default, we provide a way to disable it.
* `extraInstallFlags` (optional), allows to extend `installFlags` which initializes the variable `COQMF_COQLIB` so as to install in the proper subdirectory. Indeed Coq libraries should be installed in `$(out)/lib/coq/${coq.coq-version}/user-contrib/`. Such directories are automatically added to the `$COQPATH` environment variable by the hook defined in the Coq derivation.
* `setCOQBIN` (optional, defaults to `true`), by default, the environment variable `$COQBIN` is set to the current Coq's binary, but one can disable this behavior by setting it to `false`,
* `useMelquiondRemake` (optional, default to `null`) is an attribute set, which, if given, overloads the `preConfigurePhases`, `configureFlags`, `buildPhase`, and `installPhase` attributes of the derivation for a specific use in libraries using `remake` as set up by Guillaume Melquiond for `flocq`, `gappalib`, `interval`, and `coquelicot` (see the corresponding derivation for concrete examples of use of this option). For backward compatibility, the attribute `useMelquiondRemake.logpath` must be set to the logical root of the library (otherwise, one can pass `useMelquiondRemake = {}` to activate this without backward compatibility).
* `dropAttrs`, `keepAttrs`, `dropDerivationAttrs` are all optional and allow to tune which attribute is added or removed from the final call to `mkDerivation`.
It also takes other standard `mkDerivation` attributes, they are added as such, except for `meta` which extends an automatically computed `meta` (where the `platform` is the same as `coq` and the homepage is automatically computed).
Here is a simple package example. It is a pure Coq library, thus it depends on Coq. It builds on the Mathematical Components library, thus it also takes some `mathcomp` derivations as `extraBuildInputs`.
```nix
{
lib,
mkCoqDerivation,
version ? null,
coq,
mathcomp,
mathcomp-finmap,
mathcomp-bigenough,
}:
mkCoqDerivation {
# namePrefix leads to e.g. `name = coq8.11-mathcomp1.11-multinomials-1.5.2`
namePrefix = [
"coq"
"mathcomp"
];
pname = "multinomials";
owner = "math-comp";
inherit version;
defaultVersion =
with lib.versions;
lib.switch
[ coq.version mathcomp.version ]
[
{
cases = [
(range "8.7" "8.12")
(isEq "1.11")
];
out = "1.5.2";
}
{
cases = [
(range "8.7" "8.11")
(range "1.8" "1.10")
];
out = "1.5.0";
}
{
cases = [
(range "8.7" "8.10")
(range "1.8" "1.10")
];
out = "1.4";
}
{
cases = [
(isEq "8.6")
(range "1.6" "1.7")
];
out = "1.1";
}
]
null;
release = {
"1.5.2".hash = "sha256-mjCx9XKa38Nz9E6wNK7YSqHdJ7YTua5fD3d6J4e7WpU=";
"1.5.1".hash = "sha256-Q8tm0y2FQAt2V1kZYkDlHWRia/lTvXAMVjdmzEV11I4=";
"1.5.0".hash = "sha256-HIK0f21G69oEW8JG46gSBde/Q2LR3GiBCv680gHbmRg=";
"1.5.0".rev = "1.5";
"1.4".hash = "sha256-F9g3MSIr3B6UZ3p8QWjz3/Jpw9sudJ+KRlvjiHSO024=";
"1.3".hash = "sha256-BPJTlAL0ETHvLMBslE0KFVt3DNoaGuMrHt2SBGyJe1A=";
"1.2".hash = "sha256-mHXBXSLYO4BN+jfN50y/+XCx0Qq5g4Ac2Y/qlsbgAdY=";
"1.1".hash = "sha256-ejAsMQbB/LtU9j+g160VdGXULrCe9s0gBWzyhKqmCuE=";
"1.0".hash = "sha256-tZTOltEBBKWciDxDMs/Ye4Jnq/33CANrHJ4FBMPtq+I=";
};
propagatedBuildInputs = [
mathcomp.ssreflect
mathcomp.algebra
mathcomp-finmap
mathcomp-bigenough
];
meta = {
description = "Coq/SSReflect Library for Monoidal Rings and Multinomials";
license = lib.licenses.cecill-c;
};
}
```
## Three ways of overriding Coq packages {#coq-overriding-packages}
There are three distinct ways of changing a Coq package by overriding one of its values: `.override`, `overrideCoqDerivation`, and `.overrideAttrs`. This section explains what sort of values can be overridden with each of these methods.
### `.override` {#coq-override}
`.override` lets you change arguments to a Coq derivation. In the case of the `multinomials` package above, `.override` would let you override arguments like `mkCoqDerivation`, `version`, `coq`, `mathcomp`, `mathcom-finmap`, etc.
For example, assuming you have a special `mathcomp` dependency you want to use, here is how you could override the `mathcomp` dependency:
```nix
multinomials.override { mathcomp = my-special-mathcomp; }
```
In Nixpkgs, all Coq derivations take a `version` argument. This can be overridden in order to easily use a different version:
```nix
coqPackages.multinomials.override { version = "1.5.1"; }
```
Refer to [](#coq-packages-attribute-sets-coqpackages) for all the different formats that you can potentially pass to `version`, as well as the restrictions.
### `overrideCoqDerivation` {#coq-overrideCoqDerivation}
The `overrideCoqDerivation` function lets you easily change arguments to `mkCoqDerivation`. These arguments are described in [](#coq-packages-attribute-sets-coqpackages).
For example, here is how you could locally add a new release of the `multinomials` library, and set the `defaultVersion` to use this release:
```nix
coqPackages.lib.overrideCoqDerivation {
defaultVersion = "2.0";
release."2.0".hash = "sha256-czoP11rtrIM7+OLdMisv2EF7n/IbGuwFxHiPtg3qCNM=";
} coqPackages.multinomials
```
### `.overrideAttrs` {#coq-overrideAttrs}
`.overrideAttrs` lets you override arguments to the underlying `stdenv.mkDerivation` call. Internally, `mkCoqDerivation` uses `stdenv.mkDerivation` to create derivations for Coq libraries. You can override arguments to `stdenv.mkDerivation` with `.overrideAttrs`.
For instance, here is how you could add some code to be performed in the derivation after installation is complete:
```nix
coqPackages.multinomials.overrideAttrs (oldAttrs: {
postInstall = oldAttrs.postInstall or "" + ''
echo "you can do anything you want here"
'';
})
```

View File

@@ -0,0 +1,152 @@
# COSMIC {#sec-language-cosmic}
## Packaging COSMIC applications {#ssec-cosmic-packaging}
COSMIC (Computer Operating System Main Interface Components) is a desktop environment developed by
System76, primarily for the Pop!_OS Linux distribution. Applications in the COSMIC ecosystem are
written in Rust and use libcosmic, which builds on the Iced GUI framework. This section explains
how to properly package and integrate COSMIC applications within Nix.
### libcosmicAppHook {#ssec-cosmic-libcosmic-app-hook}
The `libcosmicAppHook` is a setup hook that helps with this by automatically configuring
and wrapping applications based on libcosmic. It handles many common requirements like:
- Setting up proper linking for libraries that may be dlopen'd by libcosmic/iced apps
- Configuring XDG paths for settings schemas, icons, and other resources
- Managing Vergen environment variables for build-time information
- Setting up Rust linker flags for specific libraries
To use the hook, simply add it to your package's `nativeBuildInputs`:
```nix
{
lib,
rustPlatform,
libcosmicAppHook,
}:
rustPlatform.buildRustPackage {
# ...
nativeBuildInputs = [ libcosmicAppHook ];
# ...
}
```
### Settings fallback {#ssec-cosmic-settings-fallback}
COSMIC applications use libcosmic's UI components, which may need access to theme settings. The
`cosmic-settings` package provides default theme settings as a fallback in its `share` directory.
By default, `libcosmicAppHook` includes this fallback path in `XDG_DATA_DIRS`, ensuring that COSMIC
applications will have access to theme settings even if they aren't available elsewhere in the
system.
This fallback behavior can be disabled by setting `includeSettings = false` when including the hook:
```nix
{
lib,
rustPlatform,
libcosmicAppHook,
}:
let
# Get build-time version of libcosmicAppHook
libcosmicAppHook' = (libcosmicAppHook.__spliced.buildHost or libcosmicAppHook).override {
includeSettings = false;
};
in
rustPlatform.buildRustPackage {
# ...
nativeBuildInputs = [ libcosmicAppHook' ];
# ...
}
```
Note that `cosmic-settings` is a separate application and not a part of the libcosmic settings
system itself. It's included by default in `libcosmicAppHook` only to provide these fallback theme
settings.
### Icons {#ssec-cosmic-icons}
COSMIC applications can use icons from the COSMIC icon theme. While COSMIC applications can build
and run without these icons, they would be missing visual elements. The `libcosmicAppHook`
automatically includes `cosmic-icons` in the wrapped application's `XDG_DATA_DIRS` as a fallback,
ensuring that the application has access to its required icons even if the system doesn't have the
COSMIC icon theme installed globally.
Unlike the `cosmic-settings` fallback, the `cosmic-icons` fallback cannot be removed or disabled, as
it is essential for COSMIC applications to have access to these icons for proper visual rendering.
### Runtime Libraries {#ssec-cosmic-runtime-libraries}
COSMIC applications built on libcosmic and Iced require several runtime libraries that are dlopen'd
rather than linked directly. The `libcosmicAppHook` ensures that these libraries are correctly
linked by setting appropriate Rust linker flags. The libraries handled include:
- Graphics libraries (EGL, Vulkan)
- Input libraries (xkbcommon)
- Display server protocols (Wayland, X11)
This ensures that the applications will work correctly at runtime, even though they use dynamic
loading for these dependencies.
### Adding custom wrapper arguments {#ssec-cosmic-custom-wrapper-args}
You can pass additional arguments to the wrapper using `libcosmicAppWrapperArgs` in the `preFixup` hook:
```nix
{
lib,
rustPlatform,
libcosmicAppHook,
}:
rustPlatform.buildRustPackage {
# ...
preFixup = ''
libcosmicAppWrapperArgs+=(--set-default ENVIRONMENT_VARIABLE VALUE)
'';
# ...
}
```
## Frequently encountered issues {#ssec-cosmic-common-issues}
### Setting up Vergen environment variables {#ssec-cosmic-common-issues-vergen}
Many COSMIC applications use the Vergen Rust crate for build-time information. The `libcosmicAppHook`
automatically sets up the `VERGEN_GIT_COMMIT_DATE` environment variable based on `SOURCE_DATE_EPOCH`
to ensure reproducible builds.
However, some applications may explicitly require additional Vergen environment variables.
Without these properly set, you may encounter build failures with errors like:
```
> cargo:rerun-if-env-changed=VERGEN_GIT_COMMIT_DATE
> cargo:rerun-if-env-changed=VERGEN_GIT_SHA
>
> --- stderr
> Error: no suitable 'git' command found!
> warning: build failed, waiting for other jobs to finish...
```
While `libcosmicAppHook` handles `VERGEN_GIT_COMMIT_DATE`, you may need to explicitly set other
variables. For applications that require these variables, you should set them directly in the
package definition:
```nix
{
lib,
rustPlatform,
libcosmicAppHook,
}:
rustPlatform.buildRustPackage {
# ...
env = {
VERGEN_GIT_COMMIT_DATE = "2025-01-01";
VERGEN_GIT_SHA = "0000000000000000000000000000000000000000"; # SHA-1 hash of the commit
};
# ...
}
```
Not all COSMIC applications require these variables, but for those that do, setting them explicitly
will prevent build failures.

View File

@@ -0,0 +1,80 @@
# Crystal {#crystal}
## Building a Crystal package {#building-a-crystal-package}
This section uses [Mint](https://github.com/mint-lang/mint) as an example for how to build a Crystal package.
If the Crystal project has any dependencies, the first step is to get a `shards.nix` file encoding those. Get a copy of the project and go to its root directory such that its `shard.lock` file is in the current directory. Executable projects should usually commit the `shard.lock` file, but sometimes that's not the case, which means you need to generate it yourself. With an existing `shard.lock` file, `crystal2nix` can be run.
```bash
$ git clone https://github.com/mint-lang/mint
$ cd mint
$ git checkout 0.5.0
$ if [ ! -f shard.lock ]; then nix-shell -p shards --run "shards lock"; fi
$ nix-shell -p crystal2nix --run crystal2nix
```
This should have generated a `shards.nix` file.
Next create a Nix file for your derivation and use `pkgs.crystal.buildCrystalPackage` as follows:
```nix
with import <nixpkgs> { };
crystal.buildCrystalPackage rec {
pname = "mint";
version = "0.5.0";
src = fetchFromGitHub {
owner = "mint-lang";
repo = "mint";
rev = version;
hash = "sha256-dFN9l5fgrM/TtOPqlQvUYgixE4KPr629aBmkwdDoq28=";
};
# Insert the path to your shards.nix file here
shardsFile = ./shards.nix;
# ...
}
```
This won't build anything yet, because we haven't told it what files build. We can specify a mapping from binary names to source files with the `crystalBinaries` attribute. The project's compilation instructions should show this. For Mint, the binary is called "mint", which is compiled from the source file `src/mint.cr`, so we'll specify this as follows:
```nix
{
crystalBinaries.mint.src = "src/mint.cr";
# ...
}
```
Additionally you can override the default `crystal build` options (which are currently `--release --progress --no-debug --verbose`) with
```nix
{
crystalBinaries.mint.options = [
"--release"
"--verbose"
];
}
```
Depending on the project, you might need additional steps to get it to compile successfully. In Mint's case, we need to link against openssl, so in the end the Nix file looks as follows:
```nix
with import <nixpkgs> { };
crystal.buildCrystalPackage rec {
version = "0.5.0";
pname = "mint";
src = fetchFromGitHub {
owner = "mint-lang";
repo = "mint";
rev = version;
hash = "sha256-dFN9l5fgrM/TtOPqlQvUYgixE4KPr629aBmkwdDoq28=";
};
shardsFile = ./shards.nix;
crystalBinaries.mint.src = "src/mint.cr";
buildInputs = [ openssl ];
}
```

View File

@@ -0,0 +1,438 @@
# CUDA {#cuda}
Compute Unified Device Architecture (CUDA) is a parallel computing platform and application programming interface (API) model created by NVIDIA. It's commonly used to accelerate computationally intensive problems and has been widely adopted for high-performance computing (HPC) and machine learning (ML) applications.
## User Guide {#cuda-user-guide}
Packages provided by NVIDIA which require CUDA are typically stored in CUDA package sets.
Nixpkgs provides a number of CUDA package sets, each based on a different CUDA release. Top-level attributes that provide access to CUDA package sets follow these naming conventions:
- `cudaPackages_x_y`: A major-minor-versioned package set for a specific CUDA release, where `x` and `y` are the major and minor versions of the CUDA release.
- `cudaPackages_x`: A major-versioned alias to the major-minor-versioned CUDA package set with the latest widely supported major CUDA release.
- `cudaPackages`: An unversioned alias to the major-versioned alias for the latest widely supported CUDA release. The package set referenced by this alias is also referred to as the "default" CUDA package set.
It is recommended to use the unversioned `cudaPackages` attribute. While versioned package sets are available (e.g., `cudaPackages_12_8`), they are periodically removed.
Here are two examples to illustrate the naming conventions:
- If `cudaPackages_12_9` is the latest release in the 12.x series, but core libraries like OpenCV or ONNX Runtime fail to build with it, `cudaPackages_12` may alias `cudaPackages_12_8` instead of `cudaPackages_12_9`.
- If `cudaPackages_13_1` is the latest release, but core libraries like PyTorch or Torch Vision fail to build with it, `cudaPackages` may alias `cudaPackages_12` instead of `cudaPackages_13`.
All CUDA package sets include common CUDA packages like `libcublas`, `cudnn`, `tensorrt`, and `nccl`.
### Configuring Nixpkgs for CUDA {#cuda-configuring-nixpkgs-for-cuda}
CUDA support is not enabled by default in Nixpkgs. To enable CUDA support, make sure Nixpkgs is imported with a configuration similar to the following:
```nix
{
allowUnfreePredicate =
let
ensureList = x: if builtins.isList x then x else [ x ];
in
package:
builtins.all (
license:
license.free
|| builtins.elem license.shortName [
"CUDA EULA"
"cuDNN EULA"
"cuSPARSELt EULA"
"cuTENSOR EULA"
"NVidia OptiX EULA"
]
) (ensureList package.meta.license);
cudaCapabilities = [ <target-architectures> ];
cudaForwardCompat = true;
cudaSupport = true;
}
```
The majority of CUDA packages are unfree, so either `allowUnfreePredicate` or `allowUnfree` should be set.
The `cudaSupport` configuration option is used by packages to conditionally enable CUDA-specific functionality. This configuration option is commonly used by packages which can be built with or without CUDA support.
The `cudaCapabilities` configuration option specifies a list of CUDA capabilities. Packages may use this option to control device code generation to take advantage of architecture-specific functionality, speed up compile times by producing less device code, or slim package closures. For example, you can build for Ada Lovelace GPUs with `cudaCapabilities = [ "8.9" ];`. If `cudaCapabilities` is not provided, the default value is calculated per-package set, derived from a list of GPUs supported by that CUDA version. Please consult [supported GPUs](https://en.wikipedia.org/wiki/CUDA#GPUs_supported) for specific cards. Library maintainers should consult [NVCC Docs](https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/) and its release notes.
::: {.caution}
Certain CUDA capabilities are not targeted by default, including capabilities belonging to the Jetson family of devices (e.g. `8.7`, which corresponds to the Jetson Orin) or non-baseline feature-sets (e.g. `9.0a`, which corresponds to the Hopper exclusive feature set). If you need to target these capabilities, you must explicitly set `cudaCapabilities` to include them.
:::
The `cudaForwardCompat` boolean configuration option determines whether PTX support for future hardware is enabled.
### Modifying CUDA package sets {#cuda-modifying-cuda-package-sets}
CUDA package sets are created by using `callPackage` on `pkgs/top-level/cuda-packages.nix` with an explicit argument for `cudaMajorMinorVersion`, a string of the form `"<major>.<minor>"` (e.g., `"12.2"`), which informs the CUDA package set tooling which version of CUDA to use. The majority of the CUDA package set tooling is available through the top-level attribute set `_cuda`, a fixed-point defined outside the CUDA package sets.
::: {.caution}
The `cudaMajorMinorVersion` and `_cuda` attributes are not part of the CUDA package set fixed-point, but are instead provided by `callPackage` from the top-level in the construction of the package set. As such, they must be modified via the package set's `override` attribute.
:::
::: {.caution}
As indicated by the underscore prefix, `_cuda` is an implementation detail and no guarantees are provided with respect to its stability or API. The `_cuda` attribute set is exposed only to ease creation or modification of CUDA package sets by expert, out-of-tree users.
:::
::: {.note}
The `_cuda` attribute set fixed-point should be modified through its `extend` attribute.
:::
The `_cuda.fixups` attribute set is a mapping from package name (`pname`) to a `callPackage`-compatible expression which will be provided to `overrideAttrs` on the result of our generic builder.
::: {.caution}
Fixups are chosen from `_cuda.fixups` by `pname`. As a result, packages with multiple versions (e.g., `cudnn`, `cudnn_8_9`, etc.) all share a single fixup function (i.e., `_cuda.fixups.cudnn`, which is `pkgs/development/cuda-modules/fixups/cudnn.nix`).
:::
As an example, you can change the fixup function used for cuDNN for only the default CUDA package set with this overlay:
```nix
final: prev: {
cudaPackages = prev.cudaPackages.override (prevArgs: {
_cuda = prevArgs._cuda.extend (
_: prevAttrs: {
fixups = prevAttrs.fixups // {
cudnn = <your-fixup-function>;
};
}
);
});
}
```
### Extending CUDA package sets {#cuda-extending-cuda-package-sets}
CUDA package sets are scopes and provide the usual `overrideScope` attribute for overriding package attributes (see the note about `cudaMajorMinorVersion` and `_cuda` in [Configuring CUDA package sets](#cuda-modifying-cuda-package-sets)).
Inspired by `pythonPackagesExtensions`, the `_cuda.extensions` attribute is a list of extensions applied to every version of the CUDA package set, allowing modification of all versions of the CUDA package set without needing to know their names or explicitly enumerate and modify them. As an example, disabling `cuda_compat` across all CUDA package sets can be accomplished with this overlay:
```nix
final: prev: {
_cuda = prev._cuda.extend (
_: prevAttrs: {
extensions = prevAttrs.extensions ++ [ (_: _: { cuda_compat = null; }) ];
}
);
}
```
### Using `cudaPackages` {#cuda-using-cudapackages}
::: {.caution}
A non-trivial amount of CUDA package discoverability and usability relies on the various setup hooks used by a CUDA package set. As a result, users will likely encounter issues trying to perform builds within a `devShell` without manually invoking phases.
:::
To use one or more CUDA packages in an expression, give the expression a `cudaPackages` parameter, and in case CUDA support is optional, add a `config` and `cudaSupport` parameter:
```nix
{
config,
cudaSupport ? config.cudaSupport,
cudaPackages,
}:
<package-expression>
```
In your package's derivation arguments, it is _strongly_ recommended that the following are set:
```nix
{
__structuredAttrs = true;
strictDeps = true;
}
```
These settings ensure that the CUDA setup hooks function as intended.
When using `callPackage`, you can choose to pass in a different variant, e.g. when a package requires a specific version of CUDA:
```nix
{ mypkg = callPackage { cudaPackages = cudaPackages_12_6; }; }
```
::: {.caution}
Overriding the CUDA package set for a package may cause inconsistencies, because the override does not affect its direct or transitive dependencies. As a result, it is easy to end up with a package that use a different CUDA package set than its dependencies. If possible, it is recommended that you change the default CUDA package set globally, to ensure a consistent environment.
:::
### Nixpkgs CUDA variants {#cuda-nixpkgs-cuda-variants}
Nixpkgs CUDA variants are provided primarily for the convenience of selecting CUDA-enabled packages by attribute path. As an example, the `pkgsForCudaArch` collection of CUDA Nixpkgs variants allows you to access an instantiation of OpenCV with CUDA support for an Ada Lovelace GPU with the attribute path `pkgsForCudaArch.sm_89.opencv`, without needing to modify the `config` provided when importing Nixpkgs.
::: {.caution}
Nixpkgs variants are not free: they require re-evaluating Nixpkgs. Where possible, import Nixpkgs once, with the desired configuration.
:::
#### Using `cudaPackages.pkgs` {#cuda-using-cudapackages-pkgs}
Each CUDA package set has a `pkgs` attribute, which is a variant of Nixpkgs in which the enclosing CUDA package set becomes the default. This was done primarily to avoid package set leakage, wherein a member of a non-default CUDA package set has a (potentially transitive) dependency on a member of the default CUDA package set.
::: {.note}
Package set leakage is a common problem in Nixpkgs and is not limited to CUDA package sets.
:::
As an added benefit of `pkgs` being configured this way, building a package with a non-default version of CUDA is as simple as accessing an attribute. As an example, `cudaPackages_12_8.pkgs.opencv` provides OpenCV built against CUDA 12.8.
#### Using `pkgsCuda` {#cuda-using-pkgscuda}
The `pkgsCuda` attribute set is a variant of Nixpkgs configured with `cudaSupport = true;` and `rocmSupport = false`. It is a convenient way to access a variant of Nixpkgs configured with the default set of CUDA capabilities.
#### Using `pkgsForCudaArch` {#cuda-using-pkgsforcudaarch}
The `pkgsForCudaArch` attribute set maps CUDA architectures (e.g., `sm_89` for Ada Lovelace or `sm_90a` for architecture-specific Hopper) to Nixpkgs variants configured to support exactly that architecture. As an example, `pkgsForCudaArch.sm_89` is a Nixpkgs variant extending `pkgs` and setting the following values in `config`:
```nix
{
cudaSupport = true;
cudaCapabilities = [ "8.9" ];
cudaForwardCompat = false;
}
```
::: {.note}
In `pkgsForCudaArch`, the `cudaForwardCompat` option is set to `false` because exactly one CUDA architecture is supported by the corresponding Nixpkgs variant. Furthermore, some architectures, including architecture-specific feature sets like `sm_90a`, cannot be built with forward compatibility.
:::
::: {.caution}
Not every version of CUDA supports every architecture!
To illustrate: support for Blackwell (e.g., `sm_100`) was added in CUDA 12.8. Assume our Nixpkgs' default CUDA package set is to CUDA 12.6. Then the Nixpkgs variant available through `pkgsForCudaArch.sm_100` is useless, since packages like `pkgsForCudaArch.sm_100.opencv` and `pkgsForCudaArch.sm_100.python3Packages.torch` will try to generate code for `sm_100`, an architecture unknown to CUDA 12.6. In that case, you should use `pkgsForCudaArch.sm_100.cudaPackages_12_8.pkgs` instead (see [Using cudaPackages.pkgs](#cuda-using-cudapackages-pkgs) for more details).
:::
The `pkgsForCudaArch` attribute set makes it possible to access packages built for a specific architecture without needing to manually call `pkgs.extend` and supply a new `config`. As an example, `pkgsForCudaArch.sm_89.python3Packages.torch` provides PyTorch built for Ada Lovelace GPUs.
### Running Docker or Podman containers with CUDA support {#cuda-docker-podman}
It is possible to run Docker or Podman containers with CUDA support. The recommended mechanism to perform this task is to use the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html).
The NVIDIA Container Toolkit can be enabled in NixOS like follows:
```nix
{ hardware.nvidia-container-toolkit.enable = true; }
```
This will automatically enable a service that generates a CDI specification (located at `/var/run/cdi/nvidia-container-toolkit.json`) based on the auto-detected hardware of your machine. You can check this service by running:
```ShellSession
$ systemctl status nvidia-container-toolkit-cdi-generator.service
```
::: {.note}
Depending on what settings you had already enabled in your system, you might need to restart your machine in order for the NVIDIA Container Toolkit to generate a valid CDI specification for your machine.
:::
Once that a valid CDI specification has been generated for your machine on boot time, both Podman and Docker (> 25) will use this spec if you provide them with the `--device` flag:
```ShellSession
$ podman run --rm -it --device=nvidia.com/gpu=all ubuntu:latest nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 4090 (UUID: <REDACTED>)
GPU 1: NVIDIA GeForce RTX 2080 SUPER (UUID: <REDACTED>)
```
```ShellSession
$ docker run --rm -it --device=nvidia.com/gpu=all ubuntu:latest nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 4090 (UUID: <REDACTED>)
GPU 1: NVIDIA GeForce RTX 2080 SUPER (UUID: <REDACTED>)
```
You can check all the identifiers that have been generated for your auto-detected hardware by checking the contents of the `/var/run/cdi/nvidia-container-toolkit.json` file:
```ShellSession
$ nix run nixpkgs#jq -- -r '.devices[].name' < /var/run/cdi/nvidia-container-toolkit.json
0
1
all
```
#### Specifying what devices to expose to the container {#cuda-specifying-what-devices-to-expose-to-the-container}
You can choose what devices are exposed to your containers by using the identifier on the generated CDI specification. Like follows:
```ShellSession
$ podman run --rm -it --device=nvidia.com/gpu=0 ubuntu:latest nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 4090 (UUID: <REDACTED>)
```
You can repeat the `--device` argument as many times as necessary if you have multiple GPU's and you want to pick up which ones to expose to the container:
```ShellSession
$ podman run --rm -it --device=nvidia.com/gpu=0 --device=nvidia.com/gpu=1 ubuntu:latest nvidia-smi -L
GPU 0: NVIDIA GeForce RTX 4090 (UUID: <REDACTED>)
GPU 1: NVIDIA GeForce RTX 2080 SUPER (UUID: <REDACTED>)
```
::: {.note}
By default, the NVIDIA Container Toolkit will use the GPU index to identify specific devices. You can change the way to identify what devices to expose by using the `hardware.nvidia-container-toolkit.device-name-strategy` NixOS attribute.
:::
#### Using docker-compose {#cuda-using-docker-compose}
It's possible to expose GPUs to a `docker-compose` environment as well. With a `docker-compose.yaml` file like follows:
```yaml
services:
some-service:
image: ubuntu:latest
command: sleep infinity
deploy:
resources:
reservations:
devices:
- driver: cdi
device_ids:
- nvidia.com/gpu=all
```
In the same manner, you can pick specific devices that will be exposed to the container:
```yaml
services:
some-service:
image: ubuntu:latest
command: sleep infinity
deploy:
resources:
reservations:
devices:
- driver: cdi
device_ids:
- nvidia.com/gpu=0
- nvidia.com/gpu=1
```
## Contributing {#cuda-contributing}
::: {.warning}
This section of the docs is still very much in progress. Feedback is welcome in GitHub Issues tagging @NixOS/cuda-maintainers or on [Matrix](https://matrix.to/#/#cuda:nixos.org).
:::
### Package set maintenance {#cuda-package-set-maintenance}
The CUDA Toolkit is a suite of CUDA libraries and software meant to provide a development environment for CUDA-accelerated applications. Until the release of CUDA 11.4, NVIDIA had only made the CUDA Toolkit available as a multi-gigabyte runfile installer, which we provide through the [`cudaPackages.cudatoolkit`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages.cudatoolkit) attribute. From CUDA 11.4 and onwards, NVIDIA has also provided CUDA redistributables (“CUDA-redist”): individually packaged CUDA Toolkit components meant to facilitate redistribution and inclusion in downstream projects. These packages are available in the [`cudaPackages`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages) package set.
All new projects should use the CUDA redistributables available in [`cudaPackages`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages) in place of [`cudaPackages.cudatoolkit`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages.cudatoolkit), as they are much easier to maintain and update.
#### Updating redistributables {#cuda-updating-redistributables}
1. Go to NVIDIA's index of CUDA redistributables: <https://developer.download.nvidia.com/compute/cuda/redist/>
2. Make a note of the new version of CUDA available.
3. Run
```bash
nix run github:connorbaker/cuda-redist-find-features -- \
download-manifests \
--log-level DEBUG \
--version <newest CUDA version> \
https://developer.download.nvidia.com/compute/cuda/redist \
./pkgs/development/cuda-modules/cuda/manifests
```
This will download a copy of the manifest for the new version of CUDA.
4. Run
```bash
nix run github:connorbaker/cuda-redist-find-features -- \
process-manifests \
--log-level DEBUG \
--version <newest CUDA version> \
https://developer.download.nvidia.com/compute/cuda/redist \
./pkgs/development/cuda-modules/cuda/manifests
```
This will generate a `redistrib_features_<newest CUDA version>.json` file in the same directory as the manifest.
5. Update the `cudaVersionMap` attribute set in `pkgs/development/cuda-modules/cuda/extension.nix`.
#### Updating cuTensor {#cuda-updating-cutensor}
1. Repeat the steps present in [Updating CUDA redistributables](#cuda-updating-redistributables) with the following changes:
- Use the index of cuTensor redistributables: <https://developer.download.nvidia.com/compute/cutensor/redist>
- Use the newest version of cuTensor available instead of the newest version of CUDA.
- Use `pkgs/development/cuda-modules/cutensor/manifests` instead of `pkgs/development/cuda-modules/cuda/manifests`.
- Skip the step of updating `cudaVersionMap` in `pkgs/development/cuda-modules/cuda/extension.nix`.
#### Updating supported compilers and GPUs {#cuda-updating-supported-compilers-and-gpus}
1. Update `nvccCompatibilities` in `pkgs/development/cuda-modules/_cuda/data/nvcc.nix` to include the newest release of NVCC, as well as any newly supported host compilers.
2. Update `cudaCapabilityToInfo` in `pkgs/development/cuda-modules/_cuda/data/cuda.nix` to include any new GPUs supported by the new release of CUDA.
#### Updating the CUDA Toolkit runfile installer {#cuda-updating-the-cuda-toolkit}
::: {.warning}
While the CUDA Toolkit runfile installer is still available in Nixpkgs as the [`cudaPackages.cudatoolkit`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages.cudatoolkit) attribute, its use is not recommended, and it should be considered deprecated. Please migrate to the CUDA redistributables provided by the [`cudaPackages`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages) package set.
To ensure packages relying on the CUDA Toolkit runfile installer continue to build, it will continue to be updated until a migration path is available.
:::
1. Go to NVIDIA's CUDA Toolkit runfile installer download page: <https://developer.nvidia.com/cuda-downloads>
2. Select the appropriate OS, architecture, distribution, and version, and installer type.
- For example: Linux, x86_64, Ubuntu, 22.04, runfile (local)
- NOTE: Typically, we use the Ubuntu runfile. It is unclear if the runfile for other distributions will work.
3. Take the link provided by the installer instructions on the webpage after selecting the installer type and get its hash by running:
```bash
nix store prefetch-file --hash-type sha256 <link>
```
4. Update `pkgs/development/cuda-modules/cudatoolkit/releases.nix` to include the release.
#### Updating the CUDA package set {#cuda-updating-the-cuda-package-set}
1. Include a new `cudaPackages_<major>_<minor>` package set in `pkgs/top-level/all-packages.nix`.
- NOTE: Changing the default CUDA package set should occur in a separate PR, allowing time for additional testing.
2. Successfully build the closure of the new package set, updating `pkgs/development/cuda-modules/cuda/overrides.nix` as needed. Below are some common failures:
| Unable to ... | During ... | Reason | Solution | Note |
| -------------- | -------------------------------- | ------------------------------------------------ | -------------------------- | ------------------------------------------------------------ |
| Find headers | `configurePhase` or `buildPhase` | Missing dependency on a `dev` output | Add the missing dependency | The `dev` output typically contains the headers |
| Find libraries | `configurePhase` | Missing dependency on a `dev` output | Add the missing dependency | The `dev` output typically contains CMake configuration files |
| Find libraries | `buildPhase` or `patchelf` | Missing dependency on a `lib` or `static` output | Add the missing dependency | The `lib` or `static` output typically contains the libraries |
Failure to run the resulting binary is typically the most challenging to diagnose, as it may involve a combination of the aforementioned issues. This type of failure typically occurs when a library attempts to load or open a library it depends on that it does not declare in its `DT_NEEDED` section. Try the following debugging steps:
1. First ensure that dependencies are patched with [`autoAddDriverRunpath`](https://search.nixos.org/packages?channel=unstable&type=packages&query=autoAddDriverRunpath).
2. Failing that, try running the application with [`nixGL`](https://github.com/guibou/nixGL) or a similar wrapper tool.
3. If that works, it likely means that the application is attempting to load a library that is not in the `RPATH` or `RUNPATH` of the binary.
### Writing tests {#cuda-writing-tests}
::: {.caution}
The existence of `passthru.testers` and `passthru.tests` should be considered an implementation detail -- they are not meant to be a public or stable interface.
:::
In general, there are two attribute sets in `passthru` that are used to build and run tests for CUDA packages: `passthru.testers` and `passthru.tests`. Each attribute set may contain an attribute set named `cuda`, which contains CUDA-specific derivations. The `cuda` attribute set is used to separate CUDA-specific derivations from those which support multiple implementations (e.g., OpenCL, ROCm, etc.) or have different licenses. For an example of such generic derivations, see the `magma` package.
::: {.note}
Derivations are nested under the `cuda` attribute due to an OfBorg quirk: if evaluation fails (e.g., because of unfree licenses), the entire enclosing attribute set is discarded. This prevents other attributes in the set from being discovered, evaluated, or built.
:::
#### `passthru.testers` {#cuda-passthru-testers}
Attributes added to `passthru.testers` are derivations which produce an executable which runs a test. The produced executable should:
- Take care to set up the environment, make temporary directories, and so on.
- Be registered as the derivation's `meta.mainProgram` so that it can be run directly.
::: {.note}
Testers which always require CUDA should be placed in `passthru.testers.cuda`, while those which are generic should be placed in `passthru.testers`.
:::
The `passthru.testers` attribute set allows running tests outside the Nix sandbox. There are a number of reasons why this is useful, since such a test:
- Can be run on non-NixOS systems, when wrapped with utilities like `nixGL` or `nix-gl-host`.
- Has network access patterns which are difficult or impossible to sandbox.
- Is free to produce output which is not deterministic, such as timing information.
#### `passthru.tests` {#cuda-passthru-tests}
Attributes added to `passthru.tests` are derivations which run tests inside the Nix sandbox. Tests should:
- Use the executables produced by `passthru.testers`, where possible, to avoid duplication of test logic.
- Include `requiredSystemFeatures = [ "cuda" ];`, possibly conditioned on the value of `cudaSupport` if they are generic, to ensure that they are only run on systems exposing a CUDA-capable GPU.
::: {.note}
Tests which always require CUDA should be placed in `passthru.tests.cuda`, while those which are generic should be placed in `passthru.tests`.
:::
This is useful for tests which are deterministic (e.g., checking exit codes) and which can be provided with all necessary resources in the sandbox.

View File

@@ -0,0 +1,91 @@
# Cue (Cuelang) {#cuelang}
[Cuelang](https://cuelang.org/) is a language to:
- describe schemas and validate backward-compatibility
- generate code and schemas in various formats (e.g. JSON Schema, OpenAPI)
- do configuration akin to [Dhall Lang](https://dhall-lang.org/)
- perform data validation
## Cuelang schema quick start {#cuelang-quickstart}
Cuelang schemas are similar to JSON, here is a quick cheatsheet:
- Default types includes: `null`, `string`, `bool`, `bytes`, `number`, `int`, `float`, lists as `[...T]` where `T` is a type.
- All structures, defined by: `myStructName: { <fields> }` are **open** -- they accept fields which are not specified.
- Closed structures can be built by doing `myStructName: close({ <fields> })` -- they are strict in what they accept.
- `#X` are **definitions**, referenced definitions are **recursively closed**, i.e. all its children structures are **closed**.
- `&` operator is the [unification operator](https://cuelang.org/docs/references/spec/#unification) (similar to a type-level merging operator), `|` is the [disjunction operator](https://cuelang.org/docs/references/spec/#disjunction) (similar to a type-level union operator).
- Values **are** types, i.e. `myStruct: { a: 3 }` is a valid type definition that only allows `3` as value.
- Read <https://cuelang.org/docs/concepts/logic/> to learn more about the semantics.
- Read <https://cuelang.org/docs/references/spec/> to learn about the language specification.
## `writeCueValidator` {#cuelang-writeCueValidator}
Nixpkgs provides a `pkgs.writeCueValidator` helper, which will write a validation script based on the provided Cuelang schema.
Here is an example:
```nix
pkgs.writeCueValidator (pkgs.writeText "schema.cue" ''
#Def1: {
field1: string
}
'') { document = "#Def1"; }
```
- The first parameter is the Cue schema file.
- The second parameter is an options parameter, currently, only: `document` can be passed.
`document` : match your input data against this fragment of structure or definition, e.g. you may use the same schema file but different documents based on the data you are validating.
Another example, given the following `validator.nix` :
```nix
{
pkgs ? import <nixpkgs> { },
}:
let
genericValidator =
version:
pkgs.writeCueValidator (pkgs.writeText "schema.cue" ''
#Version1: {
field1: string
}
#Version2: #Version1 & {
field1: "unused"
}'') { document = "#Version${toString version}"; };
in
{
validateV1 = genericValidator 1;
validateV2 = genericValidator 2;
}
```
The result is a script that will validate the file you pass as the first argument against the schema you provided `writeCueValidator`.
It can be any format that `cue vet` supports, i.e. YAML or JSON for example.
Here is an example, named `example.json`, given the following JSON:
```
{ "field1": "abc" }
```
You can run the result script (named `validate`) as the following:
```console
$ nix-build validator.nix
$ ./result example.json
$ ./result-2 example.json
field1: conflicting values "unused" and "abc":
./example.json:1:13
../../../../../../nix/store/v64dzx3vr3glpk0cq4hzmh450lrwh6sg-schema.cue:5:11
$ sed -i 's/"abc"/3/' example.json
$ ./result example.json
field1: conflicting values 3 and string (mismatched types int and string):
./example.json:1:13
../../../../../../nix/store/v64dzx3vr3glpk0cq4hzmh450lrwh6sg-schema.cue:5:11
```
**Known limitations**
* The script will enforce **concrete** values and will not accept lossy transformations (strictness). You can add these options if you need them.

View File

@@ -0,0 +1,142 @@
# Dart {#sec-language-dart}
## Dart applications {#ssec-dart-applications}
The function `buildDartApplication` builds Dart applications managed with pub.
It fetches its Dart dependencies automatically through `pub2nix`, and (through a series of hooks) builds and installs the executables specified in the pubspec file. The hooks can be used in other derivations, if needed. The phases can also be overridden to do something different from installing binaries.
If you are packaging a Flutter desktop application, use [`buildFlutterApplication`](#ssec-dart-flutter) instead.
`pubspecLock` is the parsed pubspec.lock file. pub2nix uses this to download required packages.
This can be converted to JSON from YAML with something like `yq . pubspec.lock`, and then read by Nix.
Alternatively, `autoPubspecLock` can be used instead, and set to a path to a regular `pubspec.lock` file. This relies on import-from-derivation, and is not permitted in Nixpkgs, but can be useful at other times.
::: {.warning}
When using `autoPubspecLock` with a local source directory, make sure to use a
concatenation operator (e.g. `autoPubspecLock = src + "/pubspec.lock";`), and
not string interpolation.
String interpolation will copy your entire source directory to the Nix store and
use its store path, meaning that unrelated changes to your source tree will
cause the generated `pubspec.lock` derivation to rebuild!
:::
If the package has Git package dependencies, the hashes must be provided in the `gitHashes` set. If a hash is missing, an error message prompting you to add it will be shown.
The `dart` commands run can be overridden through `pubGetScript` and `dartCompileCommand`; you can also add flags using `dartCompileFlags` or `dartJitFlags`.
Dart supports multiple [outputs types](https://dart.dev/tools/dart-compile#types-of-output); you can choose between them using `dartOutputType` (defaults to `exe`). If you want to override the binaries path or the source path they come from, you can use `dartEntryPoints`. Outputs that require a runtime will automatically be wrapped with the relevant runtime (`dartaotruntime` for `aot-snapshot`, `dart run` for `jit-snapshot` and `kernel`, `node` for `js`); this can be overridden through `dartRuntimeCommand`.
```nix
{
lib,
buildDartApplication,
fetchFromGitHub,
}:
buildDartApplication rec {
pname = "dart-sass";
version = "1.62.1";
src = fetchFromGitHub {
owner = "sass";
repo = "dart-sass";
tag = version;
hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4=";
};
pubspecLock = lib.importJSON ./pubspec.lock.json;
}
```
### Patching dependencies {#ssec-dart-applications-patching-dependencies}
Some Dart packages require patches or build environment changes. Package derivations can be customised with the `customSourceBuilders` argument.
A collection of such customisations can be found in Nixpkgs, in the `development/compilers/dart/package-source-builders` directory.
This allows fixes for packages to be shared between all applications that use them. It is strongly recommended to add to this collection instead of including fixes in your application derivation itself.
### Running executables from dev_dependencies {#ssec-dart-applications-build-tools}
Many Dart applications require executables from the `dev_dependencies` section in `pubspec.yaml` to be run before building them.
This can be done in `preBuild`, in one of two ways:
1. Packaging the tool with `buildDartApplication`, adding it to Nixpkgs, and running it like any other application
2. Running the tool from the package cache
Of these methods, the first is recommended when using a tool that does not need
to be of a specific version.
For the second method, the `packageRun` function from the `dartConfigHook` can be used.
This is an alternative to `dart run` that does not rely on Pub.
e.g., for `build_runner`:
```bash
packageRun build_runner build
```
Do _not_ use `dart run <package_name>`, as this will attempt to download dependencies with Pub.
### Usage with nix-shell {#ssec-dart-applications-nix-shell}
#### Using dependencies from the Nix store {#ssec-dart-applications-nix-shell-deps}
As `buildDartApplication` provides dependencies instead of `pub get`, Dart needs to be explicitly told where to find them.
Run the following commands in the source directory to configure Dart appropriately.
Do not use `pub` after doing so; it will download the dependencies itself and overwrite these changes.
```bash
cp --no-preserve=all "$pubspecLockFilePath" pubspec.lock
mkdir -p .dart_tool && cp --no-preserve=all "$packageConfig" .dart_tool/package_config.json
```
## Flutter applications {#ssec-dart-flutter}
The function `buildFlutterApplication` builds Flutter applications.
See the [Dart documentation](#ssec-dart-applications) for more details on required files and arguments.
`flutter` in Nixpkgs always points to `flutterPackages.stable`, which is the latest packaged version. To avoid unforeseen breakage during upgrade, packages in Nixpkgs should use a specific flutter version, such as `flutter319` and `flutter322`, instead of using `flutter` directly.
```nix
{ flutter322, fetchFromGitHub }:
flutter322.buildFlutterApplication {
pname = "firmware-updater";
version = "0-unstable-2023-04-30";
# To build for the Web, use the targetFlutterPlatform argument.
# targetFlutterPlatform = "web";
src = fetchFromGitHub {
owner = "canonical";
repo = "firmware-updater";
rev = "6e7dbdb64e344633ea62874b54ff3990bd3b8440";
hash = "sha256-s5mwtr5MSPqLMN+k851+pFIFFPa0N1hqz97ys050tFA=";
fetchSubmodules = true;
};
pubspecLock = lib.importJSON ./pubspec.lock.json;
}
```
### Usage with nix-shell {#ssec-dart-flutter-nix-shell}
Flutter-specific `nix-shell` usage notes are included here. See the [Dart documentation](#ssec-dart-applications-nix-shell) for general `nix-shell` instructions.
#### Entering the shell {#ssec-dart-flutter-nix-shell-enter}
By default, dependencies for only the `targetFlutterPlatform` are available in the
build environment. This is useful for keeping closures small but can be problematic
during development. It's common, for example, to build Web apps for Linux during
development to take advantage of native features such as stateful hot reload.
To enter a shell with all the usual target platforms available, use the `multiShell` attribute.
e.g. `nix-shell '<nixpkgs>' -A fluffychat-web.multiShell`.

Some files were not shown because too many files have changed in this diff Show More