mkDerivationVom Tool-Nutzer zum Tool-Bauer. Die Phasen, aus denen jedes Nix-Paket entsteht.
stdenv.mkDerivation und seine Build-Phasen;
in Lektion 10 dann der bequeme Go-Builder für unsere toolbox-CLI.
mkDerivation ist auch nur eine Funktion
stdenv.mkDerivation nimmt – du ahnst es (Lektion 3) – ein Set und erzeugt daraus eine
Derivation, die ein Programm baut. Das Minimalgerüst:
pkgs.stdenv.mkDerivation {
pname = "hello-toolbox";
version = "1.0";
src = ./.; # Quelle: dieses Verzeichnis (ein Pfad, Lektion 2!)
installPhase = ''
mkdir -p $out/bin
cp hello.sh $out/bin/hello-toolbox
chmod +x $out/bin/hello-toolbox
'';
}
Nix baut ein Paket in einer festen Reihenfolge von Phasen. Du überschreibst nur die, die du brauchst – der Rest hat sinnvolle Defaults:
$out$out ist der Ziel-Pfad im Store. Was dort landet, ist dein Paket.$out ist die wichtigste Variable: der Store-Pfad, in den du installierst.
Üblich ist $out/bin/… für Programme.dontUnpack = true;
und macht alles in installPhase.nativeBuildInputs: Werkzeuge zur Bauzeit
Brauchst du beim Bauen Tools (z. B. make, pkg-config), kommen sie in
nativeBuildInputs – jetzt zahlt sich Lektion 7 aus:
nativeBuildInputs = [ pkgs.makeWrapper ];
buildInputs = [ pkgs.openssl ]; # Libraries zum Linken
Holst du die Quelle aus dem Netz (statt aus ./.), verlangt Nix einen Hash
– die Garantie, dass alle bit-genau dieselbe Quelle bekommen:
src = pkgs.fetchFromGitHub {
owner = "you";
repo = "toolbox";
rev = "v1.0";
hash = "sha256-AAAA…"; # Inhalts-Prüfsumme der Quelle
};
hash = pkgs.lib.fakeHash; (lauter Nullen),
baue einmal – Nix bricht ab und nennt dir den echten Hash in der Fehlermeldung.
Den trägst du ein, fertig.
src, Phasen, $out. Damit kannst du jedes Paket lesen und einfache
selbst schreiben.
src/fetch* mit Hash deklariert sein. Ein curl in der
buildPhase schlägt fehl – das ist Absicht, nicht ein Bug.
$out zählt
Was du nicht nach $out kopierst, existiert nach dem Build nicht. Vergessene
mkdir -p $out/bin oder ein Tippfehler im Zielpfad ist die häufigste Ursache für
„Paket gebaut, aber Befehl fehlt".
pkgs.writeShellApplication { name = …; text = …; }
in einer Zeile – inklusive PATH-Wrapping. mkDerivation ist der allgemeine Weg darunter.
Nicht spicken – Abrufen aus dem Gedächtnis ist genau die Übung, die hängen bleibt.
Was bedeutet die Variable $out in einer Derivation?
$out ist das Ziel im /nix/store. Was dort landet, ist das Paket – typisch
$out/bin/programm.
Warum verlangt fetchFromGitHub einen Hash?
Der Hash fixiert den Inhalt der Quelle – dieselbe Reproduzierbarkeits-Logik wie beim Store-Pfad und
bei der flake.lock.
Warum schlägt ein curl in der buildPhase fehl?
Die Sandbox kappt das Netzwerk, damit Builds reproduzierbar bleiben. Quellen müssen vorab per
fetch* mit Hash deklariert werden.
Ziel: Ein winziges Shell-Tool als Nix-Paket bauen.
hello.sh an: #!/bin/sh + echo "hallo aus toolbox".tool.nix mit stdenv.mkDerivation, dontUnpack = true;
und einer installPhase, die das Skript nach $out/bin/hello-toolbox kopiert.nix-build tool.nix (oder via Flake, Lektion 11) und führe ./result/bin/hello-toolbox aus.Tipp: src = ./.; nimmt das aktuelle Verzeichnis als Quelle – inklusive deiner hello.sh.
# tool.nix
let pkgs = import <nixpkgs> {}; in
pkgs.stdenv.mkDerivation {
pname = "hello-toolbox"; version = "1.0";
src = ./.; dontUnpack = true;
installPhase = ''
mkdir -p $out/bin
cp $src/hello.sh $out/bin/hello-toolbox
chmod +x $out/bin/hello-toolbox
'';
}
# $ nix-build tool.nix && ./result/bin/hello-toolbox → "hallo aus toolbox"
Du hast gerade dein erstes Nix-Paket gebaut. In Lektion 10 machen wir daraus ein echtes Go-CLI.
stdenv & Phasen.
Die maßgebliche Erklärung der Build-Phasen. Lies „Phases" und „Attributes" – kompakt und definitiv.
tool.nix und die Fehlermeldung – Hash-Fehler löst man in 30 Sekunden.
buildGoModule & Co.)