Skip to content

Commit

Permalink
tuto 2 content
Browse files Browse the repository at this point in the history
  • Loading branch information
viperML committed Sep 17, 2024
1 parent 13f1301 commit 25f17b5
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 17 deletions.
16 changes: 16 additions & 0 deletions src/components/NixTuto.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
---
<ul>
<li>
<a href="/blog/nix-tuto-1">Part 1: Language Basics</a>
</li>
<li>
<a href="/blog/nix-tuto-2">Part 2: Derivations</a>
</li>
<li>
<a href="/blog/nix-tuto-3">Part 3: NixOS and module system</a>
</li>
<li>
<a href="/blog/nix-tuto-4">Part 4: Integration</a>
</li>
</ul>
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ slug: nix-tuto-1
This is part 1 of a tutorial series that covers all of Nix. You can find the
rest here:

- Part 1: Language basics
- Part 2: Derivations
- Part 3: Module system
- Part 4: Integration
import NixTuto from "../../../components/NixTuto.astro";

<NixTuto/>

In this part of the tutorial I want to set the base upon we will build the rest
of our knowledge of Nix. We will cover the syntax of the language itself, the
Expand Down Expand Up @@ -736,7 +735,7 @@ about this. Or you might want to read ahead because of curiosity.
### Merging attribute sets
I decided to skip the merging operator `//` when talking about attrsets. It
takes two attrsets, and inserts the keys from the right-hand side into the
takes two attrsets, and inserts the keys from the right-hand side into the
left-hand side. Notice that this definition is very specific to what it does: **it
does not try to merge any child attrsets**. Looking at an example:
Expand Down Expand Up @@ -788,8 +787,8 @@ that are best (or only) implemented with recursion.
The nixpkgs' lib also offers `lib.fix`, which has a simple definition:
```nix
fix =
f:
fix =
f:
let
x = f x;
in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
title: "The Nix lectures, part 2: Derivations"
pubDate: 2024-09-16T07:07:01Z
draft: true
summary: FIXME
summary: |
From builtins.derivation to stdenv.mkDerivation, and the language-specific
builders. All you need to know to start packaging software with Nix.
slug: nix-tuto-2
---

This is part 2 of a tutorial series that covers all of Nix. We covered
language basics in the first part, and in this post we will cover derivations.

import NixTuto from "../../../components/NixTuto.astro";

<NixTuto/>

## builtins.derivation

This is the primitive that Nix uses to define derivations. You will probably
Expand All @@ -22,7 +28,7 @@ of `builtins.derivation`.
> useful when you want to use a current Nix binary to evaluate some nixpkgs from
> *many* years ago.
`builtins.derivation` is a function that takes an attrset with some
`builtins.derivation` is a function that takes an attrset with some
**known keys**, and the rest are set as environment variables. You can check the
reference documentation in the [nix manual](https://nix.dev/manual/nix/stable/language/derivations).
A simple invocation might look like this:
Expand Down Expand Up @@ -93,7 +99,7 @@ build system, Nix also implements a *sandbox* that is used during builds. This
sandbox only allows access to:

- `/bin/sh` -- to be able to bootstrap everything.
- `/nix/store` -- deliberate use of other programs in the store
- `/nix/store` -- deliberate use of other programs in the store
is not concerning because of the cryptographic hashes.
- "Private" versions of `/proc`, `/dev`, etc.
- Private PID, mount, etc. namespaces.
Expand Down Expand Up @@ -128,6 +134,36 @@ built-in to the language itself, with the `outputHash*` options:
# got: sha256-3FWguG761jOvjXDVGi2BkN+hLCUurMCBzeF4m0AEr4A=
```

### Building derivations

Nix is an expression-based language, and every nix file must return a single
value. If it returns a derivation, instead of `nix eval`, you use `nix build` to
tell the nix-daemon to build the derivation for you.

`nix build` takes an "installable", which can follow the different types:

- `-f [filename.nix] [attribute]`
- `[flake.nix]#[flake output]`
- `--expr "literal nix expression"`

When using `-f`, instead of returning a derivation, you can return an attrset of
derivations, which you select with the name:

```nix
# filename.nix
{
foo = builtins.derivation { ... };
bar = builtins.derivation { ... };
}
# $ nix build -f ./filename.nix foo
```

Some of the flags you should know about are:

- `-L` or `--print-build-logs` -- to make Nix print the build logs.
- `--keep-failed` -- put the working directory somewhere after failing a build.


## stdenv

Expand Down Expand Up @@ -225,21 +261,72 @@ in
pkgs.stdenv.mkDerivation {
# ...
patches = [
./my.patch
./my.patch
];
postPatch = ''
postPatch = ''
# this runs after the standard patchPhase, which applies `patches`
'';
buildPhase = ''
buildPhase = ''
# completely change the build phase
'';
postBuild = ''
postBuild = ''
# this won't run
# if you want, you can add `runHook preBuild` and `runHook postBuild`
# to your custom buildPhase
'';
}
```

Many phases also have some configuration. For example, you can control
`unpackPhase` by setting the env variable `dontUnpack`. Refer to the manual for
specifics of each phase.

The default behavior of the stdenv for `buildPhase` and `installPhase` is `make` +
`make install`. If you have a simple C program, then you don't need anything
else. But you probably don't, so let's keep dissecting stdenv.


### Dependencies

The different types of dependencies can be a complex topic. It gets messy when
handling cross-compilation, because you must not mix the different architecures
(e.g. using an x86_64 GCC to build an ARM64 binary).

In Nix, you will use 2 kind of dependencies:

- `nativeBuildInputs` -- packages that are needed on the **build** machine.
- For example: GCC, make, pkg-config, etc (*usually* programs).
- `buildInputs` -- packages that are needed on the machine that **runs** the
package.
- For example: libc, QT, zlib, etc (*usually* libraries).

By default, Nix doesn't check that the dependencies do respect this difference,
unless you use `strictDeps = true;`

### Hooks

One of the difference of `nativeBuildInputs`, is that they may contain some bash
code that is sourced by the bash builder. The hook will only be executed if the
package is in `nativeBuildInputs`.

Hooks augment the capabilities of `mkDerivation`, depending on the package.
Usually, they are executed for the program to be able to function properly. This
is best shown by using the example of the hook of `pkg-config`.

`pkg-config` is a program that allows use to find the path to libraries. This is
essential in Nix, because there is no global library path. However, how do we
transmit to `pkg-config`, that the packages in `buildInputs` are available? The
hook is what "glues" everything together. For `pkg-config`, its hook will export
`PKG_CONFIG_PATH`, which is used by the CLI:

```nix file: "pkg-config.nix"
# $ nix build -f ./pkg-config.nix -L
# with-pkg-config> PKG_CONFIG_PATH:/nix/store/0w4q8asq9sn56dl0sxp1m8gk4vy2ygs8-zlib-1.3.1-dev/lib/pkgconfig
# with-pkg-config> zlib zlib - zlib compression library
```

### Compiler wrappers
23 changes: 23 additions & 0 deletions src/content/blog/nix-tuto-2/pkg-config.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# pkg-config.nix
let
pkgs = import <nixpkgs> {};
in
pkgs.stdenv.mkDerivation {
name = "with-pkg-config";
src = null;
dontUnpack = true;

nativeBuildInputs = [
pkgs.pkg-config
];

buildInputs = [
pkgs.zlib
];

buildPhase = ''
echo "PKG_CONFIG_PATH:$PKG_CONFIG_PATH"
pkg-config --list-all
printenv
'';
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: "The Nix lectures, part 3: Module system"
title: "The Nix lectures, part 3: NixOS and module system"
pubDate: 2024-09-16T07:08:21Z
draft: true
summary: FIXME
slug: nix-tuto-3
---

## hello
## TODO
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ summary: FIXME
slug: nix-tuto-4
---

## hello
## TODO

0 comments on commit 25f17b5

Please sign in to comment.