1
0
Fork 0
mirror of https://github.com/NixOS/nix-pills synced 2024-09-19 04:00:13 -04:00

Manually added backticks for <package> tags in original

This commit is contained in:
Noam Yorav-Raphael 2024-04-07 19:32:58 +03:00 committed by Jan Tojnar
parent 511cd615e0
commit 32e1503b84
9 changed files with 27 additions and 27 deletions

View file

@ -82,7 +82,7 @@ manifest.nix -> /nix/store/q8b5238akq07lj9gfb3qb5ycq4dxxiwm-<b>env-manifest.nix<
share -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-<b>nix-2.1.3</b>/share share -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-<b>nix-2.1.3</b>/share
</code></pre> </code></pre>
That nix-2.1.3 derivation in the Nix store is Nix itself, with binaries and libraries. The process of "installing" the derivation in the profile basically reproduces the hierarchy of the nix-2.1.3 store derivation in the profile by means of symbolic links. That `nix-2.1.3` derivation in the Nix store is Nix itself, with binaries and libraries. The process of "installing" the derivation in the profile basically reproduces the hierarchy of the `nix-2.1.3` store derivation in the profile by means of symbolic links.
The contents of this profile are special, because only one program has been installed in our profile, therefore e.g. the `bin` directory points to the only program which has been installed (Nix itself). The contents of this profile are special, because only one program has been installed in our profile, therefore e.g. the `bin` directory points to the only program which has been installed (Nix itself).
@ -121,7 +121,7 @@ Read `nix.sh`, it's short.
## FAQ: Can I change /nix to something else? ## FAQ: Can I change /nix to something else?
You can, but there's a good reason to keep using `/nix` instead of a different directory. All the derivations depend on other derivations by using absolute paths. We saw in the first article that bash referenced a glibc under a specific absolute path in `/nix/store`. You can, but there's a good reason to keep using `/nix` instead of a different directory. All the derivations depend on other derivations by using absolute paths. We saw in the first article that bash referenced a `glibc` under a specific absolute path in `/nix/store`.
You can see for yourself, don't worry if you see multiple bash derivations: You can see for yourself, don't worry if you see multiple bash derivations:
@ -132,9 +132,9 @@ $ ldd /nix/store/*bash*/bin/bash
Keeping the store in `/nix` means we can grab the binary cache from nixos.org (just like you grab packages from debian mirrors) otherwise: Keeping the store in `/nix` means we can grab the binary cache from nixos.org (just like you grab packages from debian mirrors) otherwise:
- glibc would be installed under `/foo/store` - `glibc` would be installed under `/foo/store`
- Thus bash would need to point to glibc under `/foo/store`, instead of under `/nix/store` - Thus bash would need to point to `glibc` under `/foo/store`, instead of under `/nix/store`
- So the binary cache can't help, because we need a _different_ bash, and so we'd have to recompile everything ourselves. - So the binary cache can't help, because we need a _different_ bash, and so we'd have to recompile everything ourselves.

View file

@ -103,7 +103,7 @@ Running `nix-collect-garbage` after deleting the GC root or the indirect GC root
## Cleanup everything ## Cleanup everything
The main source of software duplication in the nix store comes from GC roots, due to `nix-build` and profile generations. Running `nix-build` results in a GC root for the build that refers to a specific version of specific libraries, such as glibc. After an upgrade, we must delete the previous build if we want the garbage collector to remove the corresponding derivation, as well as if we want old dependencies cleaned up. The main source of software duplication in the nix store comes from GC roots, due to `nix-build` and profile generations. Running `nix-build` results in a GC root for the build that refers to a specific version of specific libraries, such as `glibc`. After an upgrade, we must delete the previous build if we want the garbage collector to remove the corresponding derivation, as well as if we want old dependencies cleaned up.
The same holds for profiles. Manipulating the `nix-env` profile will create further generations. Old generations refer to old software, thus increasing duplication in the nix store after an upgrade. The same holds for profiles. Manipulating the `nix-env` profile will create further generations. Old generations refer to old software, thus increasing duplication in the nix store after an upgrade.

View file

@ -1,6 +1,6 @@
# Callpackage Design Pattern # Callpackage Design Pattern
Welcome to the 13th Nix pill. In the previous [12th pill](12-inputs-design-pattern.md), we introduced the first basic design pattern for organizing a repository of software. In addition, we packaged graphviz so that we had two packages to bundle into an example repository. Welcome to the 13th Nix pill. In the previous [12th pill](12-inputs-design-pattern.md), we introduced the first basic design pattern for organizing a repository of software. In addition, we packaged `graphviz` so that we had two packages to bundle into an example repository.
The next design pattern we will examine is called the `callPackage` pattern. This technique is extensively used in [nixpkgs](https://github.com/NixOS/nixpkgs), and it's the current de facto standard for importing packages in a repository. Its purpose is to reduce the duplication of identifiers between package derivation inputs and repository derivations. The next design pattern we will examine is called the `callPackage` pattern. This technique is extensively used in [nixpkgs](https://github.com/NixOS/nixpkgs), and it's the current de facto standard for importing packages in a repository. Its purpose is to reduce the duplication of identifiers between package derivation inputs and repository derivations.
@ -169,4 +169,4 @@ Writing a repository in Nix is an evolution of writing convenient functions for
## Next pill ## Next pill
In the next pill, we will talk about the "`override`" design pattern. The `graphvizCore` seems straightforward. It starts from `graphviz.nix` and builds it without gd. In the next pill, we will consider another point of view: starting from `pkgs.graphviz` and disabling gd? In the next pill, we will talk about the "`override`" design pattern. The `graphvizCore` seems straightforward. It starts from `graphviz.nix` and builds it without `gd`. In the next pill, we will consider another point of view: starting from `pkgs.graphviz` and disabling `gd`?

View file

@ -24,13 +24,13 @@ Designing such utilities is not trivial in a functional language without static
In [pill 12](12-inputs-design-pattern.md) we introduced the inputs design pattern. We do not return a derivation picking dependencies directly from the repository; rather we declare the inputs and let the callers pass the necessary arguments. In [pill 12](12-inputs-design-pattern.md) we introduced the inputs design pattern. We do not return a derivation picking dependencies directly from the repository; rather we declare the inputs and let the callers pass the necessary arguments.
In our repository we have a set of attributes that import the expressions of the packages and pass these arguments, getting back a derivation. Let's take for example the graphviz attribute: In our repository we have a set of attributes that import the expressions of the packages and pass these arguments, getting back a derivation. Let's take for example the `graphviz` attribute:
```nix ```nix
graphviz = import ./graphviz.nix { inherit mkDerivation gd fontconfig libjpeg bzip2; }; graphviz = import ./graphviz.nix { inherit mkDerivation gd fontconfig libjpeg bzip2; };
``` ```
If we wanted to produce a derivation of graphviz with a customized gd version, we would have to repeat most of the above plus specifying an alternative gd: If we wanted to produce a derivation of `graphviz` with a customized `gd` version, we would have to repeat most of the above plus specifying an alternative `gd`:
```nix ```nix
{ {
@ -54,7 +54,7 @@ mygraphviz = callPackage ./graphviz.nix { gd = customgd; };
But we may still be diverging from the original graphviz in the repository. But we may still be diverging from the original graphviz in the repository.
We would like to avoid specifying the nix expression again. Instead, we would like to reuse the original graphviz attribute in the repository and add our overrides like so: We would like to avoid specifying the nix expression again. Instead, we would like to reuse the original `graphviz` attribute in the repository and add our overrides like so:
```nix ```nix
mygraphviz = graphviz.override { gd = customgd; }; mygraphviz = graphviz.override { gd = customgd; };
@ -66,7 +66,7 @@ Note: that `.override` is not a "method" in the OO sense as you may think. Nix i
## The override implementation ## The override implementation
Recall that the graphviz attribute in the repository is the derivation returned by the function imported from `graphviz.nix`. We would like to add a further attribute named "`override`" to the returned set. Recall that the `graphviz` attribute in the repository is the derivation returned by the function imported from `graphviz.nix`. We would like to add a further attribute named "`override`" to the returned set.
Let's start by first creating a function "`makeOverridable`". This function will take two arguments: a function (that must return a set) and the set of original arguments to be passed to the function. Let's start by first creating a function "`makeOverridable`". This function will take two arguments: a function (that must return a set) and the set of original arguments to be passed to the function.
@ -148,7 +148,7 @@ Now it would be nice if `callPackage` made our derivations overridable. This is
The "`override`" pattern simplifies the way we customize packages starting from an existing set of packages. This opens a world of possibilities for using a central repository like `nixpkgs` and defining overrides on our local machine without modifying the original package. The "`override`" pattern simplifies the way we customize packages starting from an existing set of packages. This opens a world of possibilities for using a central repository like `nixpkgs` and defining overrides on our local machine without modifying the original package.
We can dream of a custom, isolated `nix-shell` environment for testing graphviz with a custom gd: We can dream of a custom, isolated `nix-shell` environment for testing `graphviz` with a custom `gd`:
```nix ```nix
debugVersion (graphviz.override { gd = customgd; }) debugVersion (graphviz.override { gd = customgd; })

View file

@ -71,7 +71,7 @@ $ nix-instantiate --eval '<mypkgs>'
{ graphviz = <code>; graphvizCore = <code>; hello = <code>; mkDerivation = <code>; } { graphviz = <code>; graphvizCore = <code>; hello = <code>; mkDerivation = <code>; }
``` ```
Yes, `nix-build` also accepts paths with angular brackets. We first evaluate the whole repository (`default.nix`) and then pick the graphviz attribute. Yes, `nix-build` also accepts paths with angular brackets. We first evaluate the whole repository (`default.nix`) and then pick the `graphviz` attribute.
## A big word about nix-env ## A big word about nix-env
@ -92,7 +92,7 @@ replacing old `graphviz'
installing `graphviz' installing `graphviz'
``` ```
Oh why did it say there's another derivation named graphviz? Because both `graphviz` and `graphvizCore` attributes in our repository have the name "graphviz" for the derivation: Oh why did it say there's another derivation named `graphviz`? Because both `graphviz` and `graphvizCore` attributes in our repository have the name "graphviz" for the derivation:
```console ```console
$ nix-env -f '<mypkgs>' -qaP $ nix-env -f '<mypkgs>' -qaP

View file

@ -45,7 +45,7 @@ Why is it useful? With this parameter it's very easy to select a set of packages
nix-build -A psmisc --argstr system i686-linux nix-build -A psmisc --argstr system i686-linux
``` ```
This will build the psmisc derivation for i686-linux instead of x86_64-linux. This concept is very similar to multi-arch of Debian. This will build the `psmisc` derivation for i686-linux instead of x86_64-linux. This concept is very similar to multi-arch of Debian.
The setup for cross compiling is also in `nixpkgs`, however it's a little contrived to talk about it and I don't know much of it either. The setup for cross compiling is also in `nixpkgs`, however it's a little contrived to talk about it and I don't know much of it either.
@ -71,7 +71,7 @@ nix-repl> pkgs.config
What attributes go in `config` is a matter of convenience and conventions. What attributes go in `config` is a matter of convenience and conventions.
For example, `config.allowUnfree` is an attribute that forbids building packages that have an unfree license by default. The `config.pulseaudio` setting tells whether to build packages with pulseaudio support or not where applicable and when the derivation obeys to the setting. For example, `config.allowUnfree` is an attribute that forbids building packages that have an unfree license by default. The `config.pulseaudio` setting tells whether to build packages with `pulseaudio` support or not where applicable and when the derivation obeys to the setting.
## About .nix functions ## About .nix functions

View file

@ -10,7 +10,7 @@ Recall the override design pattern from the [nix pill 14](14-override-design-pat
We put the override function in the returned attribute set of the original function call. We put the override function in the returned attribute set of the original function call.
Take for example graphviz. It has an input parameter xorg. If it's null, then graphviz will build without X support. Take for example `graphviz`. It has an input parameter `xorg`. If it's null, then `graphviz` will build without X support.
```console ```console
$ nix repl $ nix repl
@ -19,9 +19,9 @@ Added 4360 variables.
nix-repl> :b graphviz.override { withXorg = false; } nix-repl> :b graphviz.override { withXorg = false; }
``` ```
This will build graphviz without X support, it's as simple as that. This will build `graphviz` without X support, it's as simple as that.
However, let's say a package `P` depends on graphviz, how do we make `P` depend on the new graphviz without X support? However, let's say a package `P` depends on `graphviz`, how do we make `P` depend on the new `graphviz` without X support?
## In an imperative world... ## In an imperative world...
@ -33,7 +33,7 @@ pkgs.graphviz = pkgs.graphviz.override { withXorg = false; };
build(pkgs.P) build(pkgs.P)
``` ```
Given `pkgs.P` depends on `pkgs.graphviz`, it's easy to build `P` with the replaced graphviz. In a pure functional language it's not that easy because you can assign to variables only once. Given `pkgs.P` depends on `pkgs.graphviz`, it's easy to build `P` with the replaced `graphviz`. In a pure functional language it's not that easy because you can assign to variables only once.
## Fixed point ## Fixed point
@ -109,16 +109,16 @@ Create a `config.nix` file like this somewhere:
} }
``` ```
Now we can build e.g. asciidoc-full and it will automatically use the overridden graphviz: Now we can build e.g. `asciidoc-full` and it will automatically use the overridden `graphviz`:
```console ```console
nix-repl> pkgs = import <nixpkgs> { config = import ./config.nix; } nix-repl> pkgs = import <nixpkgs> { config = import ./config.nix; }
nix-repl> :b pkgs.asciidoc-full nix-repl> :b pkgs.asciidoc-full
``` ```
Note how we pass the `config` with `packageOverrides` when importing `nixpkgs`. Then `pkgs.asciidoc-full` is a derivation that has graphviz input (`pkgs.asciidoc` is the lighter version and doesn't use graphviz at all). Note how we pass the `config` with `packageOverrides` when importing `nixpkgs`. Then `pkgs.asciidoc-full` is a derivation that has `graphviz` input (`pkgs.asciidoc` is the lighter version and doesn't use `graphviz` at all).
Since there's no version of asciidoc with graphviz without X support in the binary cache, Nix will recompile the needed stuff for you. Since there's no version of `asciidoc` with `graphviz` without X support in the binary cache, Nix will recompile the needed stuff for you.
## The \~/.config/nixpkgs/config.nix file ## The \~/.config/nixpkgs/config.nix file
@ -132,9 +132,9 @@ We've learned about a new design pattern: using fixed point for overriding packa
Whereas in an imperative setting, like with other package managers, a library is installed replacing the old version and applications will use it, in Nix it's not that straight and simple. But it's more precise. Whereas in an imperative setting, like with other package managers, a library is installed replacing the old version and applications will use it, in Nix it's not that straight and simple. But it's more precise.
Nix applications will depend on specific versions of libraries, hence the reason why we have to recompile asciidoc to use the new graphviz library. Nix applications will depend on specific versions of libraries, hence the reason why we have to recompile `asciidoc` to use the new `graphviz` library.
The newly built asciidoc will depend on the new graphviz, and old asciidoc will keep using the old graphviz undisturbed. The newly built `asciidoc` will depend on the new `graphviz`, and old `asciidoc` will keep using the old `graphviz` undisturbed.
## Next pill ## Next pill

View file

@ -181,4 +181,4 @@ Also we've introduced some fundamentals, in particular the fact that Nix knows b
## Next pill ## Next pill
...we will introduce `stdenv`. In the previous pills we rolled our own `mkDerivation` convenience function for wrapping the builtin derivation, but the `nixpkgs` repository also has its own convenience functions for dealing with autotools projects and other build systems. ...we will introduce `stdenv`. In the previous pills we rolled our own `mkDerivation` convenience function for wrapping the builtin derivation, but the `nixpkgs` repository also has its own convenience functions for dealing with `autotools` projects and other build systems.

View file

@ -45,7 +45,7 @@ defaultNativeBuildInputs="/nix/store/sgwq15xg00xnm435gjicspm048rqg9y6-patchelf-0
## The setup file ## The setup file
Remember our generic `builder.sh` in [Pill 8](08-generic-builders.md)? It sets up a basic `PATH`, unpacks the source and runs the usual autotools commands for us. Remember our generic `builder.sh` in [Pill 8](08-generic-builders.md)? It sets up a basic `PATH`, unpacks the source and runs the usual `autotools` commands for us.
The [stdenv setup file](https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh) is exactly that. It sets up several environment variables like `PATH` and creates some helper bash functions to build a package. I invite you to read it. The [stdenv setup file](https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh) is exactly that. It sets up several environment variables like `PATH` and creates some helper bash functions to build a package. I invite you to read it.