From 2abcfaff2f3203d5e568044beffbb964684b99a0 Mon Sep 17 00:00:00 2001 From: user <> Date: Sun, 11 Dec 2022 00:44:07 +0100 Subject: [PATCH] many different, rather small changes --- one.md | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/one.md b/one.md index cb2c9d9..ccd0397 100644 --- a/one.md +++ b/one.md @@ -4,7 +4,7 @@ author: ( tags: Dissecting Guix, Functional package management, Programming interfaces, Scheme API --- To a new user, Guix's functional architecture can seem quite alien, and -possibly offputting. With a combination of extensive `#guix`-querying, +possibly be off-putting. With a combination of extensive `#guix`-querying, determined manual-reading, and plenty of source-perusing, they may eventually figure out how everything fits together by themselves, but this can be frustrating and often takes a fairly long time. @@ -118,7 +118,7 @@ Derive([("out","/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3","","")] It's... not exactly human-readable. We could try to format it and break it down, but it'd still be pretty hard to understand, since `.drv` files -contain no labels for the "arguments" or any other human-readable indicators. +contain no labels for their fields or any other human-readable indicators. Instead, we're going to explore derivations in a Guile REPL. # Exploring Guix Interactively @@ -128,9 +128,8 @@ the Guix Guile API interactively. To run a REPL in the terminal, simply [call `guix repl`](https://guix.gnu.org/manual/devel/en/html_node/Using-Guix-Interactively.html). If you're using Emacs, you can instead install [Geiser](https://nongnu.org/geiser), -which provides a comfortable Emacs UI for various Lisp REPLs, invoke -`guix repl --listen=tcp:37146 &`, and type `M-x geiser-connect RET RET RET` to -connect to the running Guile instance. +which provides a comfortable Emacs UI for various Lisp REPLs, run +`M-x geiser RET`. There are a few Guix modules we'll need. Run this Scheme code to import them: @@ -149,7 +148,7 @@ APIs, along with the `irssi` and `glib` `` objects. # Creating a `` -The Guix API for derivations revolves around the `` record, +The Guix API for derivations revolves around the [`` record](https://guix.gnu.org/en/manual/en/html_node/Derivations.html), which is the Scheme representation of that whole block of text surrounded by `Derive(...)`. If we look in `guix/derivations.scm`, we can see that it's defined like this: @@ -170,7 +169,7 @@ defined like this: ``` With the exception of `file-name`, each of those fields corresponds to -an "argument" in the `Derive(...)` form. Before we can examine them, +a field in the `Derive(...)` form. Before we can examine them, though, we need to figure out how to _lower_ that `irssi` `` object into a derivation. @@ -183,7 +182,7 @@ However, this doesn't produce a derivation: ;;; (#) ``` -`pk` is an abbreviation for the procedure `peek`, which takes the given +`pk` is an abbreviation for the Guile procedure `peek`, which takes the given object, writes a representation of it to the output, and returns it. It's especially handy when you want to view an intermediate value in a complex expression. @@ -212,7 +211,9 @@ with. # Exploring `` -The first "argument" in the `.drv` file is `outputs`, which tells the +## Outputs + +The first derivation record field in the `.drv` file is `outputs`, which tells the Guix daemon about the outputs that this build can produce: ```scheme @@ -221,6 +222,7 @@ Guix daemon about the outputs that this build can produce: ;;; ((("out" . #< path: "/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3" hash-algo: #f hash: #f recursive?: #f>))) (pk (assoc-ref irssi-outputs "out")) +;;; (#< path: "/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.1" hash-algo: #f hash: #f recursive?: #f>) (define glib-outputs (pk (derivation-outputs glib-drv))) @@ -231,7 +233,7 @@ Guix daemon about the outputs that this build can produce: ``` It's a simple association list mapping output names to `` -records, and it's equivalent to the first "argument" in the `.drv` file: +records, and it's equivalent to the first field in the `.drv` file: ``` [ ("out", "/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3", "", "") @@ -260,7 +262,7 @@ will be in advance. For instance, `origin`s produce fixed-output derivations: Note how the `hash` and `hash-algo` now have values. -Perceptive readers may note that the `` has four fields, +You might have noted that the `` has four fields, whereas the tuple in the `.drv` file only has three (minus the label). If we read the source for `write-derivation`, we can see that the `recursive?` field is serialised by prefixing the `hash-algo` with `r:` if it's true: @@ -285,8 +287,10 @@ field is serialised by prefixing the `hash-algo` with `r:` if it's true: The purpose of `recursive?` is difficult to explain, and is out of scope for this post. +## Inputs + The next field is `inputs`, which corresponds to, you guessed it, the -second pseudo-"argument" in the `.drv` file format: +second field in the `.drv` file format: ``` [ ("/gnu/store/9mv9xg4kyj4h1cvsgrw7b9x34y8yppph-glib-2.70.2.drv", ["out"]), @@ -317,8 +321,9 @@ Unlike `derivation-outputs`, `derivation-inputs` maps 1:1 to the `.drv` form; the `drv` field is a `` to be built, and the `sub-derivations` field is a list of outputs. -The other pseudo-"arguments" are pretty simple; none of them involve new -records. The third is `derivation-sources`, which contains a list of all +## Sources + +The third is `derivation-sources`, which contains a list of all store items used in the build which aren't themselves built using derivations, whereas `derivation-inputs` contains the dependencies which are. @@ -328,8 +333,10 @@ realises the store items when run, which we'll examine in a later post, and the path to a directory containing extra modules to add to the build script's `%load-path`, called `/gnu/store/...-module-import`. -The next "argument" is self-explanatory: `derivation-system`, which specifies -the Nix system we're building for. Next is `derivation-builder`, pointing to +## System, Builder and Arguments + +The next record field is `derivation-system`, which specifies +the Nix system we're building for. Then, there is `derivation-builder`, pointing to the `guile` executable that runs the script; and the second-to-last is `derivation-args`, which is a list of arguments to pass to `derivation-builder`. Note how we use `-L` and `-C` to extend the Guile `%load-path` and @@ -347,7 +354,7 @@ directories: ;;; (("--no-auto-compile" "-L" "/gnu/store/af18nrrsk98c5a71h3fifnxg1zi5mx7y-module-import" "-C" "/gnu/store/6rkkvvb7pl1l9ng8vvywvwf357vhm3va-module-import-compiled" "/gnu/store/qnrwmby5cwqdqxyiv1ga6azvakmdvgl7-irssi-1.4.3-builder")) ``` -The final "argument" contains a list of environment variables to set before +The final record field contains a list of environment variables to set before we start the build process: ```scheme @@ -355,9 +362,16 @@ we start the build process: ;;; ((("allowSubstitutes" . "0") ("guix properties" . "((type . graft) (graft (count . 2)))") ("out" . "/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3") ("preferLocalBuild" . "1"))) ``` -Obviously, the last record field, `derivation-file-name`, simply allows you to +## File Name + +The last record field, `derivation-file-name`, simply allows you to retrieve the path to the `.drv` file in Scheme, and so isn't represented -in a serialised derivation. Speaking of serialisation, to convert between the +in a serialised derivation. But how to do the inverse? How to read a +derivation from a path? + +# Reading a derivation from file + +Speaking of serialisation, to convert between the `.drv` text format and the Scheme `` record, you can use `write-derivation`, `read-derivation`, and `read-derivation-from-file`. -- 2.38.1