mirror of
https://github.com/NixOS/nix.dev.git
synced 2024-10-18 00:06:26 -04:00
Compare commits
6 commits
f732ebed47
...
00082e27a9
Author | SHA1 | Date | |
---|---|---|---|
00082e27a9 | |||
53cbd112d7 | |||
3d5d896d6c | |||
e52438b8c6 | |||
1f6a1219ae | |||
2720a4121e |
|
@ -22,39 +22,6 @@ Adapted from the [Contributor Covenant] and [The Carpentries Code of Conduct]:
|
|||
[Contributor Covenant]: https://github.com/EthicalSource/contributor_covenant/blob/cd7fcf684249786b7f7d47ba49c23a6bcb3233eb/content/version/2/1/code_of_conduct.md
|
||||
[The Carpentries Code of Conduct]: https://github.com/carpentries/docs.carpentries.org/blob/4691971d9f49544054410334140a4fd391a738da/topic_folders/policies/code-of-conduct.md
|
||||
|
||||
## Updating reference manuals
|
||||
|
||||
With the current setup, the Nix manual hosted on nix.dev does not get updated automatically with new releases.
|
||||
The following manual steps are required:
|
||||
|
||||
- Regularly update the inputs to use the latest versions of the Nix release branches with `nix shell --run "niv update"`
|
||||
|
||||
To avoid long build times, make sure Nix can be fetched from the cache.
|
||||
If it doesn't, find the latest commit that is [built by Hydra](https://hydra.nixos.org/project/nix). For example, to pin Nix 2.18:
|
||||
|
||||
```bash
|
||||
niv update nix_2-18 -r f5f4de6a550327b4b1a06123c2e450f1b92c73b6
|
||||
```
|
||||
|
||||
- On each new Nix release:
|
||||
|
||||
1. Add the latest version in [`default.nix`](./default.nix).
|
||||
For example, to add Nix 2.19:
|
||||
|
||||
```bash
|
||||
niv add nixos/nix -n nix_2-19 -b 2.19-maintenance
|
||||
```
|
||||
|
||||
2. Reference the latest version in [`source/reference/nix-manual.md`](./source/reference/nix-manual.md).
|
||||
|
||||
- If an unstable or stable release of Nixpkgs adopt a new version of Nix, update the corresponding references here.
|
||||
|
||||
Also update URLs to the the Nix manual to the version used by Nixpkgs unstable.
|
||||
For example, if one wants to move from 2.18 to 2.19:
|
||||
```bash
|
||||
sed -i 's#https://nix.dev/manual/nix/2.18/#https://nix.dev/manual/nix/2.19/#g' $(ls **/*.md)
|
||||
```
|
||||
|
||||
## What you can do
|
||||
|
||||
### You want to learn and use Nix?
|
||||
|
|
167
default.nix
167
default.nix
|
@ -3,65 +3,128 @@
|
|||
,
|
||||
}:
|
||||
let
|
||||
pkgs = import inputs.nixpkgs {
|
||||
pkgs = import inputs.nixpkgs-prev-stable {
|
||||
config = { };
|
||||
overlays = [ (import ./overlay.nix) ];
|
||||
inherit system;
|
||||
};
|
||||
lib = pkgs.lib;
|
||||
|
||||
nix-dev = pkgs.stdenv.mkDerivation {
|
||||
name = "nix-dev";
|
||||
src = ./.;
|
||||
nativeBuildInputs = with pkgs.python310.pkgs; [
|
||||
linkify-it-py
|
||||
myst-parser
|
||||
sphinx
|
||||
sphinx-book-theme
|
||||
sphinx-copybutton
|
||||
sphinx-design
|
||||
sphinx-notfound-page
|
||||
sphinx-sitemap
|
||||
];
|
||||
buildPhase = ''
|
||||
make html
|
||||
'';
|
||||
installPhase =
|
||||
let
|
||||
# Various versions of the Nix manuals, grep for (nix-manual)= to find where they are displayed
|
||||
# FIXME: This requires human interaction to update! See ./CONTRIBUTING.md for details.
|
||||
releases = {
|
||||
latest = "2.19";
|
||||
rolling = "2.18";
|
||||
stable = "2.18";
|
||||
prev-stable = "2.13";
|
||||
};
|
||||
inputName = version: pkgs.lib.strings.replaceStrings [ "." ] [ "-" ] version;
|
||||
src = version: inputs."nix_${inputName version}";
|
||||
manual = version: (import (src version)).default.doc;
|
||||
copy = version: ''
|
||||
cp -Rf ${manual version}/share/doc/nix/manual/* $out/manual/nix/${version}
|
||||
nix-dev =
|
||||
let
|
||||
# Various versions of the Nix manuals, grep for (nix-manual)= to find where they are displayed.
|
||||
# XXX: With the current setup, the Nix manual hosted on nix.dev does not get updated automatically with new releases.
|
||||
# The following manual steps are required:
|
||||
#
|
||||
# - Regularly update the inputs to use the latest versions of the Nix release branches with `nix shell --run "niv update"`
|
||||
#
|
||||
# To avoid long build times, make sure Nix can be fetched from the cache.
|
||||
# If it doesn't, find the latest commit that is [built by Hydra](https://hydra.nixos.org/project/nix). For example, to update the latest Nix release to 2.20:
|
||||
#
|
||||
# ```bash
|
||||
# niv update nix-stable -b 2.18-maintenance -r f5f4de6a550327b4b1a06123c2e450f1b92c73b6
|
||||
# ```
|
||||
#
|
||||
# - On each new Nix release, update the `nix-latest` to the corresponding release branch:
|
||||
#
|
||||
# ```bash
|
||||
# niv update nix-latest -b 2.20-maintenance
|
||||
# ```
|
||||
#
|
||||
# - On each new Nixpkgs release, update `nixpkgs-stable` and `nixpkgs-prev-stable` and the corresponding Nix versions:
|
||||
#
|
||||
# ```bash
|
||||
# niv update nixpkgs-stable -b nixos-24.05
|
||||
# niv update nix-stable -b 2.19-maintenance
|
||||
# niv update nixpkgs-prev-stable -b nixos-23.11
|
||||
# niv update nix-prev-stable -b 2.18-maintenance
|
||||
# ```
|
||||
#
|
||||
# It would be nice to have *efficient* automatic updates.
|
||||
releases = rec {
|
||||
nixpkgs-rolling = import inputs.nixpkgs-rolling { } // { inherit (nixpkgs-rolling.lib) version; };
|
||||
nixpkgs-stable = import inputs.nixpkgs-stable { } // { inherit (nixpkgs-stable.lib) version; };
|
||||
nixpkgs-prev-stable = import inputs.nixpkgs-prev-stable { } // { inherit (nixpkgs-prev-stable.lib) version; };
|
||||
nix-latest = (import inputs.nix-latest).default;
|
||||
# TODO: to further simplify this and get Nix from Nixpkgs with all required files present,
|
||||
# make a patch release of Nix after https://github.com/NixOS/nix/pull/9949 lands,
|
||||
# and bump the respective version in the respective Nixpkgs `release-*` branch.
|
||||
nix-rolling = (import inputs.nix-rolling).default;
|
||||
nix-stable = (import inputs.nix-stable).default;
|
||||
nix-prev-stable = (import inputs.nix-prev-stable).default;
|
||||
};
|
||||
version = package: lib.versions.majorMinor package.version;
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "nix-dev";
|
||||
src = ./.;
|
||||
nativeBuildInputs = with pkgs.python310.pkgs; [
|
||||
linkify-it-py
|
||||
myst-parser
|
||||
sphinx
|
||||
sphinx-book-theme
|
||||
sphinx-copybutton
|
||||
sphinx-design
|
||||
sphinx-notfound-page
|
||||
sphinx-sitemap
|
||||
];
|
||||
buildPhase =
|
||||
let
|
||||
nix-manual-index =
|
||||
with lib.attrsets;
|
||||
with lib.strings;
|
||||
replaceStrings
|
||||
(mapAttrsToList (release: _: "@${release}@") releases)
|
||||
(mapAttrsToList (_: package: version package) releases)
|
||||
(builtins.readFile ./source/reference/nix-manual.md);
|
||||
in
|
||||
''
|
||||
cp -f ${builtins.toFile "nix-manual.md" nix-manual-index} $TMP/nix.dev/source/reference/nix-manual.md
|
||||
make html
|
||||
'';
|
||||
# add upstream page redirects of the form `<from> <to> <status>`, excluding comment lines and empty
|
||||
redirects = version: ''
|
||||
sed '/^#/d;/^$/d;s#^\(.*\) \(.*\) #/manual/nix/${version}\1 /manual/nix/${version}\2 #g' ${src version}/doc/manual/_redirects >> $out/_redirects
|
||||
installPhase =
|
||||
with lib.attrsets;
|
||||
with lib.strings;
|
||||
let
|
||||
nix-releases =
|
||||
let
|
||||
package = name: elemAt (splitString "-" name) 0;
|
||||
release = name: elemAt (splitString "-" name) 1;
|
||||
filtered = filterAttrs (name: value: (package name) == "nix") releases;
|
||||
in
|
||||
mapAttrs' (name: value: { name = release name; inherit value; }) filtered;
|
||||
# the same Nix version could appear in multiple Nixpkgs releases,
|
||||
# but we want to copy each exactly once.
|
||||
unique-version =
|
||||
let
|
||||
version-exists = p: ps: elem (version p) (map (x: version x) ps);
|
||||
in
|
||||
lib.lists.foldl' (acc: elem: if version-exists elem acc then acc else acc ++ [ elem ]) [ ];
|
||||
copy = nix: ''
|
||||
cp -Rf ${nix.doc}/share/doc/nix/manual/* $out/manual/nix/${version nix}
|
||||
'';
|
||||
# add upstream page redirects of the form `<from> <to> <status>`, excluding comments and empty lines
|
||||
# TODO: once https://github.com/NixOS/nix/pull/9949 lands, bump the source and use:
|
||||
# ${nix.doc}/share/doc/nix/manual/_redirects
|
||||
# also remove the then unnecessary file from the root directory of the manual:
|
||||
# rm $out/manual/nix/${version nix}/_redirects
|
||||
redirects = nix: ''
|
||||
sed '/^#/d;/^$/d;s#^\(.*\) \(.*\) #/manual/nix/${version nix}\1 /manual/nix/${version nix}\2 #g' ${nix.src}/doc/manual/_redirects >> $out/_redirects
|
||||
'';
|
||||
shortlink = release: nix: ''
|
||||
echo /nix/manual/${release} /nix/manual/${nix.version}/ 302 >> $out/_redirects
|
||||
'';
|
||||
in
|
||||
''
|
||||
mkdir -p $out
|
||||
cp -R build/html/* $out/
|
||||
# NOTE: the comma in the shell expansion makes it also work for singleton lists
|
||||
mkdir -p $out/manual/nix/{${concatStringsSep "," (mapAttrsToList (_: nix: version nix) nix-releases)},}
|
||||
${concatStringsSep "\n" (map copy (unique-version (attrValues nix-releases)))}
|
||||
${concatStringsSep "\n" (map redirects (unique-version (attrValues nix-releases)))}
|
||||
${concatStringsSep "\n" (mapAttrsToList shortlink nix-releases)}
|
||||
'';
|
||||
shortlink = release: version: ''
|
||||
echo /nix/manual/${release} /nix/manual/${version} >> $out/_redirects
|
||||
'';
|
||||
versions = with pkgs.lib; lists.unique (attrsets.attrValues releases);
|
||||
in
|
||||
with pkgs.lib.attrsets;
|
||||
with pkgs.lib.strings;
|
||||
''
|
||||
mkdir -p $out
|
||||
cp -R build/html/* $out/
|
||||
# NOTE: the comma in the shell expansion makes it also work for singleton lists
|
||||
mkdir -p $out/manual/nix/{${concatStringsSep "," versions},}
|
||||
${concatStringsSep "\n" (map copy versions)}
|
||||
${concatStringsSep "\n" (map redirects versions)}
|
||||
${concatStringsSep "\n" (mapAttrsToList shortlink releases)}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
devmode =
|
||||
let
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"nix_2-13": {
|
||||
"nix-prev-stable": {
|
||||
"branch": "2.13-maintenance",
|
||||
"description": "Nix, the purely functional package manager",
|
||||
"homepage": "https://nixos.org/",
|
||||
|
@ -11,7 +11,7 @@
|
|||
"url": "https://github.com/nixos/nix/archive/25f2dfc6e41d8c30e7abc443a7b262e34e49253b.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nix_2-18": {
|
||||
"nix-rolling": {
|
||||
"branch": "2.18-maintenance",
|
||||
"description": "Nix, the purely functional package manager",
|
||||
"homepage": "https://nixos.org/",
|
||||
|
@ -23,7 +23,7 @@
|
|||
"url": "https://github.com/nixos/nix/archive/60eb80593f3a18aebc7672ad7007cb23c14db061.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nix_2-19": {
|
||||
"nix-latest": {
|
||||
"branch": "2.19-maintenance",
|
||||
"description": "Nix, the purely functional package manager",
|
||||
"homepage": "https://nixos.org/",
|
||||
|
@ -35,7 +35,19 @@
|
|||
"url": "https://github.com/nixos/nix/archive/dc09e6193bffcab37d3d43107eae9464395ab51d.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixpkgs": {
|
||||
"nix-stable": {
|
||||
"branch": "2.18-maintenance",
|
||||
"description": "Nix, the purely functional package manager",
|
||||
"homepage": "https://nixos.org/",
|
||||
"owner": "nixos",
|
||||
"repo": "nix",
|
||||
"rev": "60eb80593f3a18aebc7672ad7007cb23c14db061",
|
||||
"sha256": "0nyssab6skn9qd7mz4v0y3ycnhck7is6agm0i26l1anrgs90x37l",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nixos/nix/archive/60eb80593f3a18aebc7672ad7007cb23c14db061.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixpkgs-prev-stable": {
|
||||
"branch": "nixos-23.05",
|
||||
"description": "Nix Packages collection & NixOS",
|
||||
"homepage": "",
|
||||
|
@ -47,6 +59,30 @@
|
|||
"url": "https://github.com/NixOS/nixpkgs/archive/898cb2064b6e98b8c5499f37e81adbdf2925f7c5.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixpkgs-rolling": {
|
||||
"branch": "nixpkgs-unstable",
|
||||
"description": "Nix Packages collection & NixOS",
|
||||
"homepage": "",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8cc79aa39bbc6eaedaf286ae655b224c71e02907",
|
||||
"sha256": "08yj32spm74bqnwq7wyaxzqjw3dc67bb3myx1baix506as54jr3y",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nixos/nixpkgs/archive/8cc79aa39bbc6eaedaf286ae655b224c71e02907.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"branch": "nixos-23.11",
|
||||
"description": "Nix Packages collection & NixOS",
|
||||
"homepage": "",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9f2ee8c91ac42da3ae6c6a1d21555f283458247e",
|
||||
"sha256": "0imgfxzq7d7l6fcgnzzjvv6ch560svcm8s8bx8vqyvf60w24ma1d",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nixos/nixpkgs/archive/9f2ee8c91ac42da3ae6c6a1d21555f283458247e.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"poetry2nix": {
|
||||
"branch": "master",
|
||||
"description": "Convert poetry projects to nix automagically [maintainer=@adisbladis] ",
|
||||
|
|
|
@ -1,35 +1,41 @@
|
|||
(nix-manual)=
|
||||
# Nix reference manual
|
||||
|
||||
<!--
|
||||
This page is pre-processed before rendering with Sphinx. For details:
|
||||
|
||||
grep -n nix-manual.md default.nix
|
||||
-->
|
||||
|
||||
```{toctree}
|
||||
:hidden:
|
||||
|
||||
Nix pre-release (development) <https://hydra.nixos.org/job/nix/master/build.x86_64-linux/latest/download>
|
||||
Nix 2.19 (latest) <https://nix.dev/manual/nix/2.19/>
|
||||
Nix 2.18 (rolling) <https://nix.dev/manual/nix/2.18/>
|
||||
Nix 2.18 (stable 23.11) <https://nix.dev/manual/nix/2.18/>
|
||||
Nix 2.13 (stable 23.05) <https://nix.dev/manual/nix/2.13/>
|
||||
Nix @nix-latest@ (latest) <https://nix.dev/manual/nix/latest/>
|
||||
Nix @nix-rolling@ (in Nixpkgs rolling) <https://nix.dev/manual/nix/rolling/>
|
||||
Nix @nix-stable@ (in Nixpkgs @nixpkgs-stable@) <https://nix.dev/manual/nix/stable/>
|
||||
Nix @nix-prev-stable@ (in Nixpkgs @nixpkgs-prev-stable@) <https://nix.dev/manual/nix/prev-stable/>
|
||||
```
|
||||
|
||||
- [Nix pre-release](https://hydra.nixos.org/job/nix/master/build.x86_64-linux/latest/download)
|
||||
|
||||
Reference documentation for the latest build from the `master` branch of the [Nix repository](https://github.com/NixOS/nix)
|
||||
Latest build from the `master` branch of the [Nix repository](https://github.com/NixOS/nix)
|
||||
|
||||
- [Nix 2.19](https://nix.dev/manual/nix/2.19/)
|
||||
- [Nix @nix-latest@](https://nix.dev/manual/nix/latest/)
|
||||
|
||||
Reference documentation for the latest Nix release
|
||||
Latest Nix release
|
||||
|
||||
- [Nix 2.18](https://nix.dev/manual/nix/2.18/)
|
||||
- [Nix @nix-rolling@](https://nix.dev/manual/nix/rolling/)
|
||||
|
||||
Reference documentation for the Nix version shipped with the {term}`Nixpkgs` and {term}`NixOS` rolling release
|
||||
Shipped with the {term}`Nixpkgs` and {term}`NixOS` rolling release
|
||||
|
||||
- [Nix 2.18](https://nix.dev/manual/nix/2.18/)
|
||||
- [Nix @nix-stable@](https://nix.dev/manual/nix/stable/)
|
||||
|
||||
Reference documentation for the Nix version shipped with the current {term}`Nixpkgs` and {term}`NixOS` stable release
|
||||
Shipped with the current {term}`Nixpkgs` and {term}`NixOS` @nixpkgs-stable@ stable release
|
||||
|
||||
- [Nix 2.13](https://nix.dev/manual/nix/2.13/)
|
||||
- [Nix @nix-prev-stable@](https://nix.dev/manual/nix/prev-stable/)
|
||||
|
||||
Reference documentation for the Nix version shipped with the previous {term}`Nixpkgs` and {term}`NixOS` stable release
|
||||
Shipped with the previous {term}`Nixpkgs` and {term}`NixOS` @nixpkgs-prev-stable@ stable release
|
||||
|
||||
:::{tip}
|
||||
More information on Nixpkgs and NixOS releases: [](channel-branches)
|
||||
|
|
|
@ -28,9 +28,9 @@ This file can be shared with anyone to recreate the same environment on a differ
|
|||
|
||||
30 minutes
|
||||
|
||||
### What will you need?
|
||||
### What do you need?
|
||||
|
||||
- A basic understanding of the [Nix language](reading-nix-language)
|
||||
- A rudimentary understanding of the [Nix language](reading-nix-language)
|
||||
|
||||
## Entering a temporary shell
|
||||
|
||||
|
|
|
@ -8,26 +8,45 @@ myst:
|
|||
(packaging-existing-software)=
|
||||
# Packaging existing software with Nix
|
||||
|
||||
One of Nix's primary use-cases is in addressing common difficulties encountered while packaging software, like managing dependencies.
|
||||
One of Nix's primary use-cases is in addressing common difficulties encountered with packaging software, such as specifying and obtaining dependencies.
|
||||
|
||||
In the long term, Nix helps tremendously in alleviating that stress, but when *first* packaging existing software with Nix, it's common to encounter missing dependencies preventing builds from succeeding.
|
||||
In the long term, Nix helps tremendously with alleviating such problems.
|
||||
But when *first* packaging existing software with Nix, it's common to encounter errors that seem inscrutable.
|
||||
|
||||
In this tutorial, you'll create your first Nix derivations to package C/C++ software, taking advantage of the [Nixpkgs Standard Environment](https://nixos.org/manual/nixpkgs/stable/#part-stdenv) (`stdenv`) which automates much of the work of building self-contained C/C++ packages.
|
||||
## Introduction
|
||||
|
||||
The tutorial begins by considering `hello`, an implementation of "hello world" which only requires dependencies provided by `stdenv`.
|
||||
In this tutorial, you'll create your first [Nix derivations](https://nix.dev/manual/nix/2.18/language/derivations) to package C/C++ software, taking advantage of the [Nixpkgs Standard Environment](https://nixos.org/manual/nixpkgs/stable/#part-stdenv) (`stdenv`), which automates much of the work involved.
|
||||
|
||||
### What will you learn?
|
||||
|
||||
The tutorial begins with `hello`, an implementation of "hello world" which only requires dependencies already provided by `stdenv`.
|
||||
Next, you will build more complex packages with their own dependencies, leading you to use additional derivation features.
|
||||
|
||||
You'll encounter and address Nix error messages, build failures, and a host of other issues, developing your iterative debugging techniques along the way.
|
||||
|
||||
:::{note}
|
||||
A _package_ is an informally defined Nixpkgs concept referring to a Nix derivation representing an installation of some project.
|
||||
Packages have mostly standardised attributes and output layouts, allowing them to be discovered in searches and installed into environments alongside other packages.
|
||||
### What do you need?
|
||||
|
||||
For the purposes of this tutorial, "package" means something like "result of a derivation"; this is the artifact you or others will use, as a consequence of having "packaged existing software with Nix".
|
||||
- Familiarity with the Unix shell and plain text editors
|
||||
- You should be confident with [reading the Nix language](reading-nix-language). Feel free to go back and work through the tutorial first.
|
||||
|
||||
### How long does it take?
|
||||
|
||||
Going through all the steps carefully will take around 60 minutes.
|
||||
|
||||
## Your first package
|
||||
|
||||
:::{note}
|
||||
<!--
|
||||
TODO: link to the Nix manual glossary entry once it's in a released build:
|
||||
https://hydra.nixos.org/job/nix/master/build.x86_64-linux/latest/download/manual/glossary.html#package
|
||||
-->
|
||||
A _package_ is a loosely defined concept that refers to either a collection of files and other data, or a {term}`Nix expression` representing such a collection before it comes into being.
|
||||
Packages in Nixpkgs have a conventional structure, allowing them to be discovered in searches and composed in environments alongside other packages.
|
||||
|
||||
For the purposes of this tutorial, a "package" is a Nix language function that will evaluate to a derivation.
|
||||
It will enable you or others to produce an artifact for practical use, as a consequence of having "packaged existing software with Nix".
|
||||
:::
|
||||
|
||||
## A simple project
|
||||
To start, consider this skeleton derivation:
|
||||
|
||||
```nix
|
||||
|
@ -38,37 +57,42 @@ stdenv.mkDerivation { };
|
|||
|
||||
This is a function which takes an attribute set containing `stdenv`, and produces a derivation (which currently does nothing).
|
||||
|
||||
As you progress through this tutorial, you will update this several times, adding more details while following the general pattern.
|
||||
### A package function
|
||||
|
||||
### Hello, World!
|
||||
GNU Hello is an implementation of the "hello world" program, with source code accessible [from the GNU Project's FTP server](https://ftp.gnu.org/gnu/hello/).
|
||||
|
||||
To begin, you should add a `name` attribute to the set passed to `mkDerivation`; every derivation needs a name, and Nix will throw `error: derivation name missing` without one.
|
||||
To begin, add a `name` attribute to the set passed to `mkDerivation`.
|
||||
Every package needs a name and a version, and Nix will throw `error: derivation name missing` without.
|
||||
|
||||
```diff
|
||||
...
|
||||
|
||||
stdenv.mkDerivation {
|
||||
+ name = "hello";
|
||||
...
|
||||
+ pname = "hello";
|
||||
+ version = "2.12.1";
|
||||
|
||||
```
|
||||
|
||||
Next, you will download the [latest version](https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz) of `hello` using `fetchzip`, which takes the URI path to the download file and a SHA256 hash of its contents.
|
||||
Next, you will declare a dependency on the latest version of `hello`, and instruct Nix to use `fetchzip` to download the [source code archive](https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz).
|
||||
|
||||
:::{note}
|
||||
`fetchzip` can fetch [more archives](https://nixos.org/manual/nixpkgs/stable/#fetchurl) than just zip files!
|
||||
`fetchzip` can fetch [more archives](https://nixos.org/manual/nixpkgs/stable/#fetchurl) than just] zip files!
|
||||
:::
|
||||
|
||||
The hash cannot be known until after the tarball has been downloaded and unpacked, but Nix will complain if the hash supplied to `fetchzip` was incorrect, so it is common practice to supply a fake one with `lib.fakeSha256` and change the derivation definition after Nix reports the correct hash:
|
||||
The hash cannot be known until after the archive has been downloaded and unpacked.
|
||||
Nix will complain if the hash supplied to `fetchzip` is incorrect.
|
||||
It is common practice to supply a fake one with `lib.fakeSha256` and change the derivation definition after Nix reports the correct hash:
|
||||
|
||||
```nix
|
||||
# hello.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchzip
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchzip,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "hello";
|
||||
pname = "hello";
|
||||
version = "2.12.1";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz";
|
||||
|
@ -77,7 +101,7 @@ stdenv.mkDerivation {
|
|||
}
|
||||
```
|
||||
|
||||
Save this file to `hello.nix` and try to build it with `nix-build`, observing your first build failure:
|
||||
Save this file to `hello.nix` and run `nix-build` to observe your first build failure:
|
||||
|
||||
```console
|
||||
$ nix-build hello.nix
|
||||
|
@ -97,22 +121,24 @@ error: cannot evaluate a function that has an argument without a value ('lib')
|
|||
|
||||
Problem: the expression in `hello.nix` is a *function*, which only produces its intended output if it is passed the correct *arguments*.
|
||||
|
||||
### A new command
|
||||
`lib` is available from `nixpkgs`, which must be imported with another Nix expression in order to pass it as an argument to this derivation.
|
||||
### Building with `nix-build`
|
||||
|
||||
The recommended way to do this is to create a `default.nix` in the same directory as `hello.nix`, with the following contents:
|
||||
`lib` is available from [`nixpkgs`](https://github.com/NixOS/nixpkgs/), which must be imported with another Nix expression in order to pass it as an argument to this derivation.
|
||||
|
||||
The recommended way to do this is to create a `default.nix` file in the same directory as `hello.nix`, with the following contents:
|
||||
|
||||
```nix
|
||||
# default.nix
|
||||
let
|
||||
pkgs = import <nixpkgs> { };
|
||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-22.11";
|
||||
pkgs = import nixpkgs { config = {}; overlays = []; };
|
||||
in
|
||||
{
|
||||
hello = pkgs.callPackage ./hello.nix { };
|
||||
}
|
||||
```
|
||||
|
||||
This allows you to use `nix-build -A hello` to realize the derivation in `hello.nix`, similar to the current convention used in `nixpkgs`.
|
||||
This allows you to run `nix-build -A hello` to realize the derivation in `hello.nix`, similar to the current convention used in Nixpkgs.
|
||||
|
||||
:::{note}
|
||||
[`callPackage`] automatically passes attributes from `pkgs` to the given function, if they match attributes required by that function's argument attrset.
|
||||
|
@ -141,17 +167,20 @@ error:
|
|||
```
|
||||
|
||||
### Finding the file hash
|
||||
As expected, the incorrect file hash caused an error, and Nix helpfully provided the correct one, which you can now substitute into `hello.nix` to replace `lib.fakeSha256`:
|
||||
As expected, the incorrect file hash caused an error, and Nix helpfully provided the correct one.
|
||||
In `hello.nix`, replace `lib.fakeSha256` with the correct hash:
|
||||
|
||||
```nix
|
||||
# hello.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchzip
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchzip,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "hello";
|
||||
pname = "hello";
|
||||
version = "2.12.1";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz";
|
||||
|
@ -179,7 +208,7 @@ building
|
|||
Great news: the derivation built successfully!
|
||||
|
||||
The console output shows that `configure` was called, which produced a `Makefile` that was then used to build the project.
|
||||
It wasn't necessary to write any build instructions in this case because the `stdenv` build system is based on `autoconf`, which automatically detected the structure of the project directory.
|
||||
It wasn't necessary to write any build instructions in this case because the `stdenv` build system is based on [GNU Autoconf](https://www.gnu.org/software/autoconf/), which automatically detected the structure of the project directory.
|
||||
|
||||
### Build result
|
||||
Check your working directory for the result:
|
||||
|
@ -189,7 +218,7 @@ $ ls
|
|||
default.nix hello.nix result
|
||||
```
|
||||
|
||||
This `result` is a symbolic link to a Nix store location containing the built binary; you can call `./result/bin/hello` to execute this program:
|
||||
This `result` is a [symbolic link](https://en.wikipedia.org/wiki/Symbolic_link) to a Nix store location containing the built binary; you can call `./result/bin/hello` to execute this program:
|
||||
|
||||
```console
|
||||
$ ./result/bin/hello
|
||||
|
@ -200,15 +229,17 @@ Congratulations, you have successfully packaged your first program with Nix!
|
|||
|
||||
Next, you'll package another piece of software with external-to-`stdenv` dependencies that present new challenges, requiring you to make use of more `mkDerivation` features.
|
||||
|
||||
## Something bigger
|
||||
## A package with dependencies
|
||||
|
||||
Now you will package a somewhat more complicated program, [`icat`](https://github.com/atextor/icat), which allows you to render images in your terminal.
|
||||
|
||||
To start, modify the `default.nix` from the previous section by adding a new attribute for `icat`:
|
||||
Change the `default.nix` from the previous section by adding a new attribute for `icat`:
|
||||
|
||||
```nix
|
||||
# default.nix
|
||||
let
|
||||
pkgs = import <nixpkgs> { };
|
||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-22.11";
|
||||
pkgs = import nixpkgs { config = {}; overlays = []; };
|
||||
in
|
||||
{
|
||||
hello = pkgs.callPackage ./hello.nix { };
|
||||
|
@ -216,39 +247,44 @@ in
|
|||
}
|
||||
```
|
||||
|
||||
Now copy `hello.nix` to a new file, `icat.nix`, and update the `name` attribute in that file:
|
||||
Copy `hello.nix` to a new file `icat.nix`, and update the `pname` and `version` attributes in that file:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchzip
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchzip,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "icat";
|
||||
pname = "icat";
|
||||
version = "v0.5";
|
||||
|
||||
src = fetchzip {
|
||||
...
|
||||
# ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Now to download the source code.
|
||||
`icat`'s upstream repository is hosted on [GitHub](https://github.com/atextor/icat), so you should modify the previous [source fetcher](https://nixos.org/manual/nixpkgs/stable/#chap-pkgs-fetchers), this time using `fetchFromGitHub` instead of `fetchzip`, updating the argument attribute set to the function accordingly:
|
||||
`icat`'s upstream repository is hosted on [GitHub](https://github.com/atextor/icat), so you should replace the previous [source fetcher](https://nixos.org/manual/nixpkgs/stable/#chap-pkgs-fetchers).
|
||||
This time you will use [`fetchFromGitHub`](https://nixos.org/manual/nixpkgs/stable/#fetchfromgithub) instead of `fetchzip`, by updating the argument attribute set to the function accordingly:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "icat";
|
||||
pname = "icat";
|
||||
version = "v0.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
...
|
||||
# ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
@ -256,19 +292,27 @@ stdenv.mkDerivation {
|
|||
### Fetching source from GitHub
|
||||
While `fetchzip` required `url` and `sha256` arguments, more are needed for [`fetchFromGitHub`](https://nixos.org/manual/nixpkgs/stable/#fetchfromgithub).
|
||||
|
||||
The source is hosted on GitHub at `https://github.com/atextor/icat`, which already gives the first two arguments:
|
||||
- `owner`: the name of the account controlling the repository; `owner = "atextor";`
|
||||
- `repo`: the name of the repository to fetch; `repo = "icat";`
|
||||
The source is URL is `https://github.com/atextor/icat`, which already gives the first two arguments:
|
||||
- `owner`: the name of the account controlling the repository
|
||||
|
||||
You can navigate to the project's [Tags page](https://github.com/atextor/icat/tags) to find a suitable `rev`, such as the git commit hash or tag (e.g. `v1.0`) corresponding to the release you want to fetch.
|
||||
```
|
||||
owner = "atextor";
|
||||
```
|
||||
- `repo`: the name of the repository to fetch
|
||||
|
||||
```
|
||||
repo = "icat";
|
||||
``````
|
||||
|
||||
Navigate to the project's [Tags page](https://github.com/atextor/icat/tags) to find a suitable [Git revision](https://git-scm.com/docs/revisions) (`rev`), such as the Git commit hash or tag (e.g. `v1.0`) corresponding to the release you want to fetch.
|
||||
|
||||
In this case, the latest release tag is `v0.5`.
|
||||
|
||||
As in the `hello` example, a hash must also be supplied.
|
||||
|
||||
This time, instead of using `lib.fakeSha256` and letting `nix-build` report the correct one in an error, you can fetch the correct hash in the first place with the `nix-prefetch-url` command.
|
||||
|
||||
You need the SHA256 hash of the *contents* of the tarball (as opposed to the hash of the tarball file itself), so you will need to pass the `--unpack` and `--type sha256` arguments too:
|
||||
You need the SHA256 hash of the *contents* of the tarball (as opposed to the hash of the tarball file itself).
|
||||
Therefore pass the `--unpack` and `--type sha256` arguments:
|
||||
|
||||
```console
|
||||
$ nix-prefetch-url --unpack https://github.com/atextor/icat/archive/refs/tags/v0.5.tar.gz --type sha256
|
||||
|
@ -276,17 +320,19 @@ path is '/nix/store/p8jl1jlqxcsc7ryiazbpm7c1mqb6848b-v0.5.tar.gz'
|
|||
0wyy2ksxp95vnh71ybj1bbmqd5ggp13x3mk37pzr99ljs9awy8ka
|
||||
```
|
||||
|
||||
Now you can supply the correct hash to `fetchFromGitHub`:
|
||||
Set the correct hash for `fetchFromGitHub`:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "icat";
|
||||
pname = "icat";
|
||||
version = "v0.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "atextor";
|
||||
|
@ -298,7 +344,8 @@ stdenv.mkDerivation {
|
|||
```
|
||||
|
||||
### Missing dependencies
|
||||
Running `nix-build` with the new `icat` attribute, an entirely new issue is reported:
|
||||
|
||||
Running `nix-build` with the new `icat` attribute, an entirely new issue is reported:
|
||||
|
||||
```console
|
||||
$ nix-build -A icat
|
||||
|
@ -324,20 +371,23 @@ error: builder for '/nix/store/l5wz9inkvkf0qhl8kpl39vpg2xfm2qpy-icat.drv' failed
|
|||
A compiler error!
|
||||
The `icat` source was pulled from GitHub, and Nix tried to build what it found, but compilation failed due to a missing dependency: the `imlib2` header.
|
||||
|
||||
If you [search for `imlib2` on search.nixos.org](https://search.nixos.org/packages?channel=23.05&from=0&size=50&sort=relevance&type=packages&query=imlib2), you'll find that `imlib2` is already in `nixpkgs`.
|
||||
If you [search for `imlib2` on search.nixos.org](https://search.nixos.org/packages?query=imlib2), you'll find that `imlib2` is already in Nixpkgs.
|
||||
|
||||
You can add this package to your build environment by adding `imlib2` to the set of inputs to the expression in `icat.nix`, and then adding `imlib2` to the list of `buildInputs` in `stdenv.mkDerivation`:
|
||||
Add this package to your build environment by adding `imlib2` to the arguments of the function in `icat.nix`.
|
||||
Then add the argument's value `imlib2` to the list of `buildInputs` in `stdenv.mkDerivation`:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, imlib2
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
imlib2,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "icat";
|
||||
pname = "icat";
|
||||
version = "v0.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "atextor";
|
||||
|
@ -372,30 +422,99 @@ error: builder for '/nix/store/bw2d4rp2k1l5rg49hds199ma2mz36x47-icat.drv' failed
|
|||
For full logs, run 'nix log /nix/store/bw2d4rp2k1l5rg49hds199ma2mz36x47-icat.drv'.
|
||||
```
|
||||
|
||||
You can see a few warnings which should be corrected in the upstream code, but the important bit for this tutorial is `fatal error: X11/Xlib.h: No such file or directory`: another dependency is missing.
|
||||
You can see a few warnings which should be corrected in the upstream code.
|
||||
But the important bit for this tutorial is `fatal error: X11/Xlib.h: No such file or directory`: another dependency is missing.
|
||||
|
||||
## Finding packages
|
||||
|
||||
:::{note}
|
||||
Determining from where to source a dependency is currently a somewhat-involved process: it helps to become familiar with searching the `nixpkgs` source for keywords.
|
||||
|
||||
Consider using `nix-locate` from the [`nix-index`](https://github.com/nix-community/nix-index) tool to find derivations that provide what you need.
|
||||
:::
|
||||
Determining from where to source a dependency is currently a somewhat involved, because package names don't always correspond to library or program names.
|
||||
|
||||
You will need the `Xlib.h` headers from the `X11` C package, the Nixpkgs derivation for which is `libX11`, available in the `xorg` package set.
|
||||
There are multiple ways to figure this out:
|
||||
|
||||
### `search.nixos.org`
|
||||
|
||||
:::{tip}
|
||||
The easiest way to find what you need is on search.nixos.org/packages.
|
||||
:::
|
||||
|
||||
Unfortunately in this case, [searching for `x11`](https://search.nixos.org/packages?query=x11) produces too many irrelevant results because X11 is ubiquitous.
|
||||
On the left side bar there is a list package sets, and [selecting `xorg`](https://search.nixos.org/packages?channel=23.11&buckets={%22package_attr_set%22%3A[%22xorg%22]%2C%22package_license_set%22%3A[]%2C%22package_maintainers_set%22%3A[]%2C%22package_platforms%22%3A[]}&query=x11) shows something promising.
|
||||
|
||||
In case all else fails, it helps to become familiar with searching the [Nixpkgs source code](https://github.com/nixos/nixpkgs) for keywords.
|
||||
|
||||
### Git and `rg`
|
||||
|
||||
To find name assignments in the source, search for `"<keyword> ="`.
|
||||
For example, these are the search results for [`"x11 = "`](https://github.com/search?q=repo%3ANixOS%2Fnixpkgs+%22x11+%3D%22&type=code) or [`"libx11 ="`](https://github.com/search?q=repo%3ANixOS%2Fnixpkgs+%22libx11+%3D%22&type=code) on Github .
|
||||
|
||||
Or fetch a local clone of the repository and use `rg`.
|
||||
Nixpkgs is huge.
|
||||
Only clone the latest revision if you don't want to wait a long time:
|
||||
|
||||
```console
|
||||
$ nix-shell -p git ripgrep
|
||||
[nix-shell:~]$ git glone https://github.com/NixOS/nixpkgs --depth 1
|
||||
```
|
||||
|
||||
To narrow down results, specify which subdirectory you want to search:
|
||||
|
||||
```console
|
||||
[nix-shell:~]$ rg "x11 =" pkgs
|
||||
pkgs/tools/X11/primus/default.nix
|
||||
21: primus = if useNvidia then primusLib_ else primusLib_.override { nvidia_x11 = null; };
|
||||
22: primus_i686 = if useNvidia then primusLib_i686_ else primusLib_i686_.override { nvidia_x11 = null; };
|
||||
|
||||
pkgs/applications/graphics/imv/default.nix
|
||||
38: x11 = [ libGLU xorg.libxcb xorg.libX11 ];
|
||||
|
||||
pkgs/tools/X11/primus/lib.nix
|
||||
14: if nvidia_x11 == null then libGL
|
||||
|
||||
pkgs/top-level/linux-kernels.nix
|
||||
573: ati_drivers_x11 = throw "ati drivers are no longer supported by any kernel >=4.1"; # added 2021-05-18;
|
||||
... <a lot more results>
|
||||
```
|
||||
|
||||
Since `rg` is case sensitive by default,
|
||||
Add `-i` to make sure you don't miss anything:
|
||||
|
||||
```
|
||||
[nix-shell:~]$ rg -i "libx11 =" pkgs
|
||||
pkgs/applications/version-management/monotone-viz/graphviz-2.0.nix
|
||||
55: ++ lib.optional (libX11 == null) "--without-x";
|
||||
|
||||
pkgs/top-level/all-packages.nix
|
||||
14191: libX11 = xorg.libX11;
|
||||
|
||||
pkgs/servers/x11/xorg/default.nix
|
||||
1119: libX11 = callPackage ({ stdenv, pkg-config, fetchurl, xorgproto, libpthreadstubs, libxcb, xtrans, testers }: stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
pkgs/servers/x11/xorg/overrides.nix
|
||||
147: libX11 = super.libX11.overrideAttrs (attrs: {
|
||||
```
|
||||
|
||||
### `nix-locate`
|
||||
|
||||
Consider using `nix-locate` from the [`nix-index`](https://github.com/nix-community/nix-index) tool to find derivations that provide what you need.
|
||||
|
||||
### Adding package sets as dependencies
|
||||
|
||||
Add this to your derivation's input attribute set and to `buildInputs`:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, imlib2
|
||||
, xorg
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
imlib2,
|
||||
xorg,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "icat";
|
||||
pname = "icat";
|
||||
version = "v0.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "atextor";
|
||||
|
@ -414,7 +533,10 @@ Only add the top-level `xorg` derivation to the input attrset, rather than the f
|
|||
Because Nix is lazily-evaluated, using `xorg.libX11` means that we only include the `libX11` attribute and the derivation doesn't actually include all of `xorg` into the build context.
|
||||
:::
|
||||
|
||||
## Fixing build failures
|
||||
|
||||
Run the last command again:
|
||||
|
||||
```console
|
||||
$ nix-build -A icat
|
||||
this derivation will be built:
|
||||
|
@ -438,28 +560,36 @@ error: builder for '/nix/store/x1d79ld8jxqdla5zw2b47d2sl87mf56k-icat.drv' failed
|
|||
The missing dependency error is solved, but there is now another problem: `make: *** No rule to make target 'install'. Stop.`
|
||||
|
||||
### `installPhase`
|
||||
The `stdenv` is automatically working with the `Makefile` that comes with `icat`: you can see in the console output that `configure` and `make` are executed without issue, so the `icat` binary is compiling successfully.
|
||||
`stdenv` is automatically working with the `Makefile` that comes with `icat`.
|
||||
The console output showas that `configure` and `make` are executed without issue, so the `icat` binary is compiling successfully.
|
||||
|
||||
The failure occurs when the `stdenv` attempts to run `make install`: the `Makefile` included in the project happens to lack an `install` target, and the `README` in the `icat` repository only mentions using `make` to build the tool, leaving the installation step up to users.
|
||||
The failure occurs when the `stdenv` attempts to run `make install`.
|
||||
The `Makefile` included in the project happens to lack an `install` target.
|
||||
The `README` in the `icat` repository only mentions using `make` to build the tool, leaving the installation step up to users.
|
||||
|
||||
To add this step to your derivation, use the [`installPhase` attribute](https://nixos.org/manual/nixpkgs/stable/#ssec-install-phase), which contains a list of command strings to execute to perform the installation.
|
||||
To add this step to your derivation, use the [`installPhase` attribute](https://nixos.org/manual/nixpkgs/stable/#ssec-install-phase).
|
||||
It contains a list of command strings that are executed to perform the installation.
|
||||
|
||||
Because the `make` step completes successfully, the `icat` executable is available in the build directory, and you only need to copy it from there to the output directory.
|
||||
Because `make` finishes successfully, the `icat` executable is available in the build directory.
|
||||
You only need to copy it from there to the output directory.
|
||||
|
||||
In Nix, the output directory is stored in the `$out` variable, accessible in the derivation's component scripts.
|
||||
In Nix, the output directory is stored in the `$out` variable.
|
||||
That variable is accessible in the derivation's [`builder` execution environment](https://nix.dev/manual/nix/2.19/language/derivations#builder-execution).
|
||||
Create a `bin` directory within the `$out` directory and copy the `icat` binary there:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, imlib2
|
||||
, xorg
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
imlib2,
|
||||
xorg,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "icat";
|
||||
pname = "icat";
|
||||
version = "v0.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "atextor";
|
||||
|
@ -478,35 +608,45 @@ stdenv.mkDerivation {
|
|||
```
|
||||
|
||||
### Phases and hooks
|
||||
Nixpkgs `stdenv.mkDerivation` derivations are separated into [phases](https://nixos.org/manual/nixpkgs/stable/#sec-stdenv-phases), each of which is intended to control some aspect of the build process.
|
||||
|
||||
You saw earlier how `stdenv.mkDerivation` expected the project's `Makefile` to have an `install` target, and failed when it didn't.
|
||||
Nixpkgs `stdenv.mkDerivation` derivations are separated into [phases](https://nixos.org/manual/nixpkgs/stable/#sec-stdenv-phases).
|
||||
Each is intended to control some aspect of the build process.
|
||||
|
||||
Earlier you observed how `stdenv.mkDerivation` expected the project's `Makefile` to have an `install` target, and failed when it didn't.
|
||||
To fix this, you defined a custom `installPhase` containing instructions for copying the `icat` binary to the correct output location, in effect installing it.
|
||||
|
||||
Up to that point, the `stdenv.mkDerivation` automatically determined the `buildPhase` information for the `icat` package.
|
||||
|
||||
During derivation realisation, there are a number of shell functions ("hooks", in `nixpkgs`) which may execute in each derivation phase, which do things like set variables, source files, create directories, and so on.
|
||||
During derivation realisation, there are a number of shell functions ("hooks", in Nixpkgs) which may execute in each derivation phase.
|
||||
Hooks do things like set variables, source files, create directories, and so on.
|
||||
|
||||
These are specific to each phase, and run both before and after that phase's execution, controlling the build environment and helping to prevent environment-modifying behavior defined within packages from creating sources of nondeterminism within and between Nix derivations.
|
||||
These are specific to each phase, and run both before and after that phase's execution.
|
||||
They modify the build environment for common operations during the build.
|
||||
|
||||
It's good practice when packaging software with Nix to include calls to these hooks in the derivation phases you define, even when you don't make direct use of them; this facilitates easy [overriding](https://nixos.org/manual/nixpkgs/stable/#chap-overrides) of specific parts of the derivation later, in addition to the previously-mentioned reproducibility benefits.
|
||||
It's good practice when packaging software with Nix to include calls to these hooks in the derivation phases you define, even when you don't make direct use of them.
|
||||
This facilitates easy [overriding](https://nixos.org/manual/nixpkgs/stable/#chap-overrides) of specific parts of the derivation later.
|
||||
And it keeps the code tidy and makes it easier to read.
|
||||
|
||||
You should now adjust your `installPhase` to call the appropriate hooks:
|
||||
Adjust your `installPhase` to call the appropriate hooks:
|
||||
|
||||
```nix
|
||||
# icat.nix
|
||||
...
|
||||
|
||||
# ...
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/bin
|
||||
cp icat $out/bin
|
||||
runHook postInstall
|
||||
'';
|
||||
...
|
||||
|
||||
# ...
|
||||
|
||||
```
|
||||
### A successful build
|
||||
Running the `nix-build` command once more will finally do what you want, and more safely than before; you can `ls` in the local directory to find a `result` symlink to a location in the Nix store:
|
||||
## A successful build
|
||||
|
||||
Running the `nix-build` command once more will finally do what you want, repeatably.
|
||||
Call `ls` in the local directory to find a `result` symlink to a location in the Nix store:
|
||||
|
||||
```console
|
||||
$ ls
|
||||
|
@ -524,6 +664,9 @@ default.nix hello.nix icat.nix result
|
|||
|
||||
## Next steps
|
||||
|
||||
- [Add your own new packages to Nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md)
|
||||
- [](../contributing/how-to-contribute.md)
|
||||
- [](../contributing/how-to-get-help.md)
|
||||
- [](sharing-dependencies)
|
||||
- [](automatic-direnv)
|
||||
- [](python-dev-environment)
|
||||
|
|
Loading…
Reference in a new issue