From: "(" <paren@disroot.org>
To: guix-devel@gnu.org
Cc: mekeor@posteo.de, "(" <paren@disroot.org>
Subject: [PATCH guix-artwork v2] website: posts: Add Dissecting Guix, Part 1: Derivations.
Date: Mon, 12 Dec 2022 19:31:37 +0000 [thread overview]
Message-ID: <20221212193137.1264-1-paren@disroot.org> (raw)
In-Reply-To: <COWNA40KXMCL.2DHU56XCHVBOA@guix-framework>
* website/posts/dissecting-guix-1-derivations.md: New blog post.
---
Heya,
This patch adds an updated blog post, taking the critiques on this thread into
account.
* Changed post name to just "Derivations"
* Removed subjective "simple" language
* Added subheadings to "Exploring `<derivation>`"
* Added field recap to "Conclusion"
* Added "Utilising `<derivation>`", with examples for READ-DERIVATION,
READ-DERIVATION-FROM-FILE, WRITE-DERIVATION, and BUILD-DERIVATION
* Wrapped lines to 80 columns
.../posts/dissecting-guix-1-derivations.md | 426 ++++++++++++++++++
1 file changed, 426 insertions(+)
create mode 100644 website/posts/dissecting-guix-1-derivations.md
diff --git a/website/posts/dissecting-guix-1-derivations.md b/website/posts/dissecting-guix-1-derivations.md
new file mode 100644
index 0000000..18cdc3a
--- /dev/null
+++ b/website/posts/dissecting-guix-1-derivations.md
@@ -0,0 +1,426 @@
+title: Dissecting Guix, Part 1: Derivations
+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 fields 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.
+
+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 a field
+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>`
+
+## `<derivation-output>`
+
+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). The
+serialisation of `recursive?` is done by adding the prefix `r:` to the
+`hash-algo` field, though its actual purpose is difficult to explain, and is out
+of scope for this post.
+
+## `<derivation-input>`
+
+The next field is `inputs`, which corresponds to the second field 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.
+
+## Builder Configuration
+
+The other fields are simpler; none of them involve new 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 field is `derivation-system`, which specifies the Nix system we're
+building for. Then we have `derivation-builder`, pointing to the `guile`
+executable that runs the build script; and the second-to-last is
+`derivation-builder-arguments`, 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 field 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")))
+```
+
+The last record field, `derivation-file-name` contains the path to the `.drv`
+file, and so isn't represented in a serialised derivation.
+
+# Utilising `<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`:
+
+```scheme
+(define manual-drv
+ (with-store %store
+ (derivation %store "manual"
+ "/bin/sh" '())))
+
+(write-derivation drv (current-output-port))
+;;; -| Derive([("out","/gnu/store/kh7fais2zab22fd8ar0ywa4767y6xyak-example","","")],[],[],"x86_64-linux","/bin/sh",[],[("out","/gnu/store/kh7fais2zab22fd8ar0ywa4767y6xyak-example")])
+
+(pk (read-derivation-from-file (derivation-file-name irssi-drv)))
+;;; (#<derivation /gnu/store/zcgmhac8r4kdj2s6bcvcmhh4k35qvihx-irssi-1.4.3.drv => /gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3 7fb3798788c0>)
+
+(call-with-input-file (derivation-file-name irssi-drv)
+ read-derivation)
+;;; (#<derivation /gnu/store/zcgmhac8r4kdj2s6bcvcmhh4k35qvihx-irssi-1.4.3.drv => /gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3 7fb37ad19e10>)
+```
+
+You can realise `<derivation>`s as store items using the `build-derivations`
+procedure:
+
+```scheme
+(use-modules (ice-9 ftw))
+
+(define irssi-drv-out
+ (pk (derivation-output-path
+ (assoc-ref (derivation-outputs irssi-drv) "out"))))
+;;; ("/gnu/store/v5pd69j3hjs1fck4b5p9hd91wc8yf5qx-irssi-1.4.3")
+
+(pk (scandir irssi-drv-out))
+;;; (#f)
+
+(pk (with-store %store (build-derivations %store (list irssi-drv))))
+;;; (#t)
+
+(pk (scandir irssi-drv-out))
+;;; (("." ".." "bin" "etc" "include" "lib" "share"))
+```
+
+# 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!
+
+To recap, a derivation contains the following fields:
+
+1. `derivation-outputs`, describing the various output paths that the derivation
+ builds
+2. `derivation-inputs`, describing the other derivations that need to be built
+ before this one is
+3. `derivation-sources`, listing the non-derivation store items that the
+ derivation depends on
+4. `derivation-system`, specifying the Nix system a derivation will be compiled
+ for
+5. `derivation-builder`, the executable to run the build script with
+6. `derivation-builder-arguments`, arguments to pass to the builder
+7. `derivation-builder-environment-vars`, variables to set in the builder's
+ environment
+
+#### 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.
--
2.38.1
next prev parent reply other threads:[~2022-12-12 19:32 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-08 18:24 Dissecting Guix -- blog post series (
2022-12-09 7:31 ` 宋文武
2022-12-09 7:33 ` (
2022-12-09 9:32 ` bokr
2022-12-09 17:25 ` (
2022-12-12 13:46 ` Bengt Richter
2022-12-10 21:25 ` Mekeor Melire
2022-12-11 10:08 ` (
2022-12-12 1:43 ` Mekeor Melire
2022-12-12 17:26 ` (
2022-12-12 19:31 ` ( [this message]
2022-12-12 20:59 ` [PATCH guix-artwork v2] website: posts: Add Dissecting Guix, Part 1: Derivations Mekeor Melire
2022-12-12 21:06 ` Mekeor Melire
2022-12-12 21:24 ` (
2022-12-15 14:26 ` Ludovic Courtès
2022-12-12 22:53 ` [PATCH guix-artwork v3] " (
2022-12-17 22:06 ` [PATCH guix-artwork v4] " (
2023-01-04 12:00 ` Ludovic Courtès
2023-01-05 12:00 ` (
2023-01-06 1:12 ` 宋文武
2023-01-09 11:13 ` Ludovic Courtès
2023-01-10 6:59 ` (
2023-01-11 21:59 ` zimoun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221212193137.1264-1-paren@disroot.org \
--to=paren@disroot.org \
--cc=guix-devel@gnu.org \
--cc=mekeor@posteo.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.