guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dissecting Guix -- blog post series


From: Mekeor Melire
Subject: Re: Dissecting Guix -- blog post series
Date: Sat, 10 Dec 2022 21:25:49 +0000

2022-12-08 18:24 paren@disroot.org:

> Some of you may have seen on IRC that I've been writing a post for the Guix 
> blog that I hope will form the first part of a series. This series aims to 
> dissect the internals of Guix, from bottom to top.

Great, I'm looking forward to read it! Especially, personally, I'm eager for 
the rather fundamental concepts of Guix (and Nix).

> Perhaps they could go in the cookbook once the series is done?

Yes, I personally think the content should be published at two places at the 
same time: OTOH, it should either be incorporated into either the manual or the 
cookbook; and OTOH, it should be published as a blog-post. The blog-post should 
also link to the respective section of the manual or cookbook in a preamble.

> * Dissecting Guix, Part 1: Derivations
> * Dissecting Guix, Part 2: The Humble G-Expression
> * Dissecting Guix, Part 3: Packages
> * Dissecting Guix, Part 4: Monads
> * Dissecting Guix, Part 5: Profiles and Search Paths
> * Dissecting Guix, Part 6: Goings-On in the Build Container
> * Dissecting Guix, Part 7: Record Types
> * Dissecting Guix, Part 8: Substitutes and Grafts
> * Dissecting Guix, Part 9: Cross-Compilation

I think it'd also be fine to come up with the titles during the process of 
writing as sometimes that process itself is insightful. E.g. I could imagine 
parts 2 and 4 to collapse. Maybe, maybe not, you'll see.

> * Dissecting Guix, Part 10: Services
>
> Walks you through the process of creating a service, and thouroughly explains 
> system configuration.

How'd this part differ from section "12.18 Defining Services" of the manual?

> * Dissecting Guix, Part 11: Home Services
> * Dissecting Guix, Part 12: Writing a Subcommand
> * Dissecting Guix, Part 13: Lending a Hand
>
> How to edit the Guix source code and submit patches to be reviewed by the 
> lovely Guix community!

How'd this part differ from sections 22 and "22.6 Submitting Patches" from the 
manual?

Now, as for the actual article. Firstly, I added some comments below. Secondly, 
I created a "patch" suggesting some changes.

By the way, the text does not seem to strictly fill columns at a certain line 
width. So I did not bother to fill columns in the "patch".

> title: Dissecting Guix, Part 1: Derivations and Derivation
> date: TBC
> 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,
> 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.
>
> However, once you peel back the layers, the "Nix way" is actually rather
> elegant, if perhaps not as simple as the mutable, imperative style
> implemented by the likes of [`dpkg`](https://wiki.debian.org/dpkg) and,
> [`pacman`](https://wiki.archlinux.org/title/pacman).  This series of blog
> posts will cover basic Guix concepts, taking a "ground-up" approach by
> dealing with lower-level concepts first, and hopefully make those months of
> information-gathering unnecessary.
>
> Before we dig in to Guix-specific concepts, we'll need to learn about one
> inherited from [Nix](https://nixos.org), the original functional package
> manager and the inspiration for Guix; the idea of a _derivation_ and its
> corresponding _store items_.
>
> These concepts were originally described by Eelco Dolstra, the author of Nix,
> in their [PhD thesis](https://edolstra.github.io/pubs/phd-thesis.pdf); see
> _§ 2.1 The Nix store_ and _§ 2.4 Store Derivations_.
>
> # Store Items
>
> As you almost certainly know, everything that Guix builds is stored in the
> _store_, which is almost always the `/gnu/store` directory.  It's the job of
> the 
> [`guix-daemon`](https://guix.gnu.org/manual/en/html_node/Invoking-guix_002ddaemon.html)
> to manage the store and build things.  If you run
> [`guix build 
> PKG`](https://guix.gnu.org/manual/en/html_node/Invoking-guix-build.html),
> `PKG` will be built or downloaded from a substitute server if available, and
> a path to an item in the store will be displayed.
>
> ```
> $ guix build irssi
> /gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3
> ```
>
> This item contains the final result of building [`irssi`](https://irssi.org).
> Let's peek inside:
>
> ```
> $ ls $(guix build irssi)
> bin/  etc/  include/  lib/  share/
> $ ls $(guix build irssi)/bin
> irssi*
> ```
>
> `irssi` is quite a simple package.  What about a more complex one, like
> [`glib`](https://docs.gtk.org/glib)?
>
> ```
> $ guix build glib
> /gnu/store/bx8qq76idlmjrlqf1faslsq6zjc6f426-glib-2.73.3-bin
> /gnu/store/j65bhqwr7qq7l77nj0ahmk1f1ilnjr3a-glib-2.73.3-debug
> /gnu/store/3pn4ll6qakgfvfpc4mw89qrrbsgj3jf3-glib-2.73.3-doc
> /gnu/store/dvsk6x7d26nmwsqhnzws4iirb6dhhr1d-glib-2.73.3
> /gnu/store/4c8ycz501n2d0xdi4blahvnbjhd5hpa8-glib-2.73.3-static
> ```
>
> `glib` produces five `/gnu/store` items, because it's possible for a package
> to produce multiple 
> [outputs](https://guix.gnu.org/manual/en/html_node/Packages-with-Multiple-Outputs.html).
> Each output can be referred to separately, by prefixing a package's name with
> `:OUTPUT` where supported.  For example, this
> [`guix 
> install`](https://guix.gnu.org/manual/en/html_node/Invoking-guix-package.html)
> invocation will add `glib`'s `bin` output to your profile:
>
> ```
> $ guix install glib:bin
> ```
>
> The default output is `out`, so when you pass `glib` by itself to that
> command, it will actually install `glib:out` to the profile.
>
> `guix build` also provides the `--source` flag, which produces the store
> item corresponding to the given package's downloaded source code.
>
> ```
> $ guix build --source irssi
> /gnu/store/cflbi4nbak0v9xbyc43lamzl4a539hhb-irssi-1.4.3.tar.xz
> $ guix build --source glib
> /gnu/store/d22wzjq3xm3q8hwnhbgk2xd3ph7lb6ay-glib-2.73.3.tar.xz
> ```
>
> But how does Guix know how to build these store outputs in the first place?
> That's where derivations come in.
>
> # `.drv` Files
>
> You've probably seen these being printed by the Guix CLI now and again.
> Derivations, represented in the daemon's eyes by `.drv` files, contain
> instructions for building store items.  We can retrieve the paths of
> these `.drv` files with the `guix build --derivations` command:
>
> ```
> $ guix build --derivations irssi
> /gnu/store/zcgmhac8r4kdj2s6bcvcmhh4k35qvihx-irssi-1.4.3.drv
> ```
>
> `guix build` can actually also accept derivation paths as an argument, in
> lieu of a package, like so:
>
> ```
> $ guix build /gnu/store/zcgmhac8r4kdj2s6bcvcmhh4k35qvihx-irssi-1.4.3.drv
> /gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3
> ```
>
> Let's look inside this derivation file.
>
> ```
> Derive([("out","/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3","","")],[("/gnu/store/9mv9xg4kyj4h1cvsgrw7b9x34y8yppph-glib-2.70.2.drv",["out"]),("/gnu/store/baqpbl4wck7nkxrbyc9nlhma7kq5dyfl-guile-2.0.14.drv",["out"]),("/gnu/store/bfirgq65ndhf63nn4q6vlkbha9zd931q-openssl-1.1.1l.drv",["out"]),("/gnu/store/gjwpqzvfhz13shix6a6cs2hjc18pj7wy-module-import-compiled.drv",["out"]),("/gnu/store/ij8651x4yh53hhcn6qw2644nhh2s8kcn-glib-2.70.2.drv",["out"]),("/gnu/store/jg2vv6yc2yqzi3qzs82dxvqmi5k21lhy-irssi-1.4.3.drv",["out"]),("/gnu/store/qggpjl9g6ic3cq09qrwkm0dfsdjf7pyr-glibc-utf8-locales-2.33.drv",["out"]),("/gnu/store/zafabw13yyhz93jwrcz7axak1kn1f2cx-openssl-1.1.1s.drv",["out"])],["/gnu/store/af18nrrsk98c5a71h3fifnxg1zi5mx7y-module-import","/gnu/store/qnrwmby5cwqdqxyiv1ga6azvakmdvgl7-irssi-1.4.3-builder"],"x86_64-linux","/gnu/store/hnr4r2d0h0xarx52i6jq9gvsrlc3q81a-guile-2.0.14/bin/guile",["--no-auto-compile","-L","/gnu/store/af18nrrsk98c5a71h3fifnxg1zi5mx7y-module-import","-C","/gnu/store/6rkkvvb7pl1l9ng8vvywvwf357vhm3va-module-import-compiled","/gnu/store/qnrwmby5cwqdqxyiv1ga6azvakmdvgl7-irssi-1.4.3-builder"],[("allowSubstitutes","0"),("guix
>  properties","((type . graft) (graft (count . 
> 2)))"),("out","/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3"),("preferLocalBuild","1")])
> ```
>
> 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.
> Instead, we're going to explore derivations in a Guile REPL.
>
> # Exploring Guix Interactively
>
> Before we continue, we'll want to start a REPL, so that we can try out
> 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.

This approach did not work nicely for me. In particular, the last command made 
Emacs freeze (even with and 'emacs -Q'). And then, when evaluating the first 
code block below, i.e. the module-import, I got the warning "Unknown meta 
command: geiser-no-values". That's why, in the "patch", I suggest to simply run 
'M-x geiser RET' which works just fine.

(I guess this is due to the fact that "Geiser invokes geiser-guile-binary with 
certain flags": <https://gitlab.com/emacs-guix/emacs-guix/-/issues/16>.)

> There are a few Guix modules we'll need.  Run this Scheme code to import
> them:
>
> ```scheme
> (use-modules (guix derivations)
>              (guix gexp)
>              (guix packages)
>              (guix store)
>              (gnu packages glib)
>              (gnu packages irc))
> ```
>
> We now have access to the store, G-expression, package, and derivation
> APIs, along with the `irssi` and `glib` `<package>` objects.
>
> # Creating a `<derivation>`
>
> The Guix API for derivations revolves around the `<derivation>` record,
> 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:
>
> ```scheme
> (define-immutable-record-type <derivation>
>   (make-derivation outputs inputs sources system builder args env-vars
>                    file-name)
>   derivation?
>   (outputs  derivation-outputs)      ; list of name/<derivation-output> pairs
>   (inputs   derivation-inputs)       ; list of <derivation-input>
>   (sources  derivation-sources)      ; list of store paths
>   (system   derivation-system)       ; string
>   (builder  derivation-builder)      ; store path
>   (args     derivation-builder-arguments)         ; list of strings
>   (env-vars derivation-builder-environment-vars)  ; list of name/value pairs
>   (file-name derivation-file-name))               ; the .drv file name
> ```
>
> With the exception of `file-name`, each of those fields corresponds to
> an "argument" in the `Derive(...)` form.  Before we can examine them,
> though, we need to figure out how to _lower_ that `irssi` `<package>`
> object into a derivation.
>
> The procedure we use to turn a high-level object like `<package>` into a
> derivation is called `lower-object`; more on that in a future post.
> However, this doesn't produce a derivation:
>
> ```scheme
> (pk (lower-object irssi))
> ;;; (#<procedure 7fe17c7af540 at guix/store.scm:1994:2 (state)>)
> ```
>
> `pk` is an abbreviation for the 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.
>
> The returned object is a procedure that needs to be evaluated in the
> context of a store connection.  We do this by first using `with-store`
> to connect to the store and bind the connection to a name, then wrapping
> the `lower-object` call with `run-with-store`:
>
> ```scheme
> (define irssi-drv
>   (pk (with-store %store
>         (run-with-store %store
>           (lower-object irssi)))))
> ;;; (#<derivation /gnu/store/zcgmhac8r4kdj2s6bcvcmhh4k35qvihx-irssi-1.4.3.drv 
> => /gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3 7fe1902b6140>)
>
> (define glib-drv
>   (pk (with-store %store
>         (run-with-store %store
>           (lower-object glib)))))
> ;;; (#<derivation /gnu/store/81qqs7xah2ln39znrji4r6xj85zi15bi-glib-2.70.2.drv 
> => /gnu/store/lp7k9ygvpwxgxjvmf8bix8d2aar0azr7-glib-2.70.2-bin 
> /gnu/store/22mkp8cr6rxg6w8br9q8dbymf51b44m8-glib-2.70.2-debug 
> /gnu/store/a6qb5arvir4vm1zlkp4chnl7d8qzzd7x-glib-2.70.2 
> /gnu/store/y4ak268dcdwkc6lmqfk9g1dgk2jr9i34-glib-2.70.2-static 7fe17ca13b90>)
> ```
>
> And we have liftoff!  Now we've got two `<derivation>` records to play
> with.
>
> # Exploring `<derivation>`

I suggest to use subheadings within this chapter because otherwise readers 
loose the overview.

> The first "argument" in the `.drv` file is `outputs`, which tells the
> Guix daemon about the outputs that this build can produce:
>
> ```scheme
> (define irssi-outputs
>   (pk (derivation-outputs irssi-drv)))
> ;;; ((("out" . #<<derivation-output> path: 
> "/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3" hash-algo: #f hash: 
> #f recursive?: #f>)))
>
> (pk (assoc-ref irssi-outputs "out"))
>
> (define glib-outputs
>   (pk (derivation-outputs glib-drv)))
> ;;; ((("bin" . #<<derivation-output> path: 
> "/gnu/store/lp7k9ygvpwxgxjvmf8bix8d2aar0azr7-glib-2.70.2-bin" hash-algo: #f 
> hash: #f recursive?: #f>) ("debug" . #<<derivation-output> path: 
> "/gnu/store/22mkp8cr6rxg6w8br9q8dbymf51b44m8-glib-2.70.2-debug" hash-algo: #f 
> hash: #f recursive?: #f>) ("out" . #<<derivation-output> path: 
> "/gnu/store/a6qb5arvir4vm1zlkp4chnl7d8qzzd7x-glib-2.70.2" hash-algo: #f hash: 
> #f recursive?: #f>) ("static" . #<<derivation-output> path: 
> "/gnu/store/y4ak268dcdwkc6lmqfk9g1dgk2jr9i34-glib-2.70.2-static" hash-algo: 
> #f hash: #f recursive?: #f>)))
>
> (pk (assoc-ref glib-outputs "bin"))
> ;;; (#<<derivation-output> path: 
> "/gnu/store/lp7k9ygvpwxgxjvmf8bix8d2aar0azr7-glib-2.70.2-bin" hash-algo: #f 
> hash: #f recursive?: #f>)
> ```
>
> It's a simple association list mapping output names to `<derivation-output>`
> records, and it's equivalent to the first "argument" in the `.drv` file:
>
> ```
> [ ("out", "/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3", "", "")
> ]
> ```
>
> The `hash-algo` and `hash` fields are for storing the content hash and the
> algorithm used with that hash for what we term a _fixed-output derivation_,
> which is essentially a derivation where we know what the hash of the content
> will be in advance.  For instance, `origin`s produce fixed-output derivations:
>
> ```scheme
> (define irssi-src-drv
>   (pk (with-store %store
>         (run-with-store %store
>           (lower-object (package-source irssi))))))
> ;;; (#<derivation 
> /gnu/store/mcz3vzq7lwwaqjb8dy7cd69lvmi6d241-irssi-1.4.3.tar.xz.drv => 
> /gnu/store/cflbi4nbak0v9xbyc43lamzl4a539hhb-irssi-1.4.3.tar.xz 7fe17b3c8d70>)
>
> (define irssi-src-outputs
>   (pk (derivation-outputs irssi-src-drv)))
> ;;; ((("out" . #<<derivation-output> path: 
> "/gnu/store/cflbi4nbak0v9xbyc43lamzl4a539hhb-irssi-1.4.3.tar.xz" hash-algo: 
> sha256 hash: #vu8(185 63 113 82 35 163 34 230 127 66 182 26 8 165 18 174 41 
> 227 75 212 165 61 127 34 55 102 102 10 170 90 4 52) recursive?: #f>)))
>
> (pk (assoc-ref irssi-src-outputs "out"))
> ;;; (#<<derivation-output> path: 
> "/gnu/store/cflbi4nbak0v9xbyc43lamzl4a539hhb-irssi-1.4.3.tar.xz" hash-algo: 
> sha256 hash: #vu8(185 63 113 82 35 163 34 230 127 66 182 26 8 165 18 174 41 
> 227 75 212 165 61 127 34 55 102 102 10 170 90 4 52) recursive?: #f>)
> ```
>
> Note how the `hash` and `hash-algo` now have values.
>
> Perceptive readers may note that the `<derivation-output>` 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:
>
> ```scheme
> ;;; guix/derivations.scm:630:2
>
> (define (write-output output port)
>   (match output
>     ((name . ($ <derivation-output> path hash-algo hash recursive?))
>      (write-tuple (list name path
>                         (if hash-algo
>                             (string-append (if recursive? "r:" "")
>                                            (symbol->string hash-algo))
>                             "")
>                         (or (and=> hash bytevector->base16-string)
>                             ""))
>                   write-escaped-string
>                   port))))
> ```
>
> The purpose of `recursive?` is difficult to explain, and is out of scope for
> this post.

If the purpose is out of scope, then we should not dive in that deeply. 
Especially, I'd suggest skip the code snippet.

> The next field is `inputs`, which corresponds to, you guessed it, the
> second pseudo-"argument" in the `.drv` file format:
>
> ```
> [ ("/gnu/store/9mv9xg4kyj4h1cvsgrw7b9x34y8yppph-glib-2.70.2.drv", ["out"]),
>   ("/gnu/store/baqpbl4wck7nkxrbyc9nlhma7kq5dyfl-guile-2.0.14.drv", ["out"]),
>   ("/gnu/store/bfirgq65ndhf63nn4q6vlkbha9zd931q-openssl-1.1.1l.drv", ["out"]),
>   ("/gnu/store/gjwpqzvfhz13shix6a6cs2hjc18pj7wy-module-import-compiled.drv", 
> ["out"]),
>   ("/gnu/store/ij8651x4yh53hhcn6qw2644nhh2s8kcn-glib-2.70.2.drv", ["out"]),
>   ("/gnu/store/jg2vv6yc2yqzi3qzs82dxvqmi5k21lhy-irssi-1.4.3.drv", ["out"]),
>   ("/gnu/store/qggpjl9g6ic3cq09qrwkm0dfsdjf7pyr-glibc-utf8-locales-2.33.drv", 
> ["out"]),
>   ("/gnu/store/zafabw13yyhz93jwrcz7axak1kn1f2cx-openssl-1.1.1s.drv", ["out"])
> ]
> ```
>
> Here, each tuple specifies a derivation that needs to be built before this
> derivation can be built, and the outputs of the derivation that the build
> process of this derivation uses.  Let's grab us the Scheme equivalent:
>
> ```scheme
> (define irssi-inputs
>   (pk (derivation-inputs irssi-drv)))
> ;;; [a fairly large amount of output]
>
> (pk (car irssi-inputs))
> ;;; (#<<derivation-input> drv: #<derivation 
> /gnu/store/9mv9xg4kyj4h1cvsgrw7b9x34y8yppph-glib-2.70.2.drv => 
> /gnu/store/2jj2mxn6wfrcw7i85nywk71mmqbnhzps-glib-2.70.2 7fe1902b6640> 
> sub-derivations: ("out")>)
> ```
>
> Unlike `derivation-outputs`, `derivation-inputs` maps 1:1 to the `.drv`
> form; the `drv` field is a `<derivation>` 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

Here you write "pretty simple". Later you also write "self-explanatory" and 
"obviously". I suggest to let the reader decide what's simple.

> records. 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.
>
> This list usually just contains the path to the Guile _build script_ that
> 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
> 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
> `%load-compiled-path` to include the `module-import` and 
> `module-import-compiled`
> directories:
>
> ```scheme
> (pk (derivation-system irssi-drv))
> ;;; ("x86_64-linux")
>
> (pk (derivation-builder irrsi-drv))
> ;;; ("/gnu/store/hnr4r2d0h0xarx52i6jq9gvsrlc3q81a-guile-2.0.14/bin/guile")
>
> (pk (derivation-builder-arguments irrsi-drv))
> ;;; (("--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
> we start the build process:
>
> ```scheme
> (pk (derivation-builder-environment-vars irssi-drv))
> ;;; ((("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

Before this point, the record fields have been called '"argument"'s all the 
time. I think it's not nice style to carry on a quoted term through many 
paragraphs like this. Let's simply write "record field" all the time, instead.

> 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 `.drv` text format and the Scheme `<derivation>`
> record, you can use `write-derivation`, `read-derivation`, and
> `read-derivation-from-file`.

I think an example for invoking read-derivation-from-file would round up this 
tutorial really nicely because it'd close the circle between .drv-files and 
<derivation>-objects.

> # Conclusion
>
> Derivations are one of Guix's most important concepts, but are fairly easy to
> understand once you get past the obtuse `.drv` file format.  They provide the
> Guix daemon with the initial instructions that it uses to build store items
> like packages, origins, and other file-likes such as `computed-file` and
> `local-file`, which will be discussed in a future post!

Here, in the conclusion, IMHO, there could be another brief listing of all 
fields of a derivation.

> #### About GNU Guix
>
> [GNU Guix](https://guix.gnu.org) is a transactional package manager and
> an advanced distribution of the GNU system that [respects user
> freedom](https://www.gnu.org/distros/free-system-distribution-guidelines.html).
> Guix can be used on top of any system running the Hurd or the Linux
> kernel, or it can be used as a standalone operating system distribution
> for i686, x86_64, ARMv7, AArch64 and POWER9 machines.
>
> In addition to standard package management features, Guix supports
> transactional upgrades and roll-backs, unprivileged package management,
> per-user profiles, and garbage collection.  When used as a standalone
> GNU/Linux distribution, Guix offers a declarative, stateless approach to
> operating system configuration management.  Guix is highly customizable
> and hackable through [Guile](https://www.gnu.org/software/guile)
> programming interfaces and extensions to the
> [Scheme](http://schemers.org) language.

Attachment: 0001-many-different-rather-small-changes.patch
Description: Text Data

Attachment: 0000-initialize-markdown.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]