unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Reworking the cookbook layout
@ 2019-11-26 22:11 Julien Lepiller
  2019-11-27 10:21 ` Pierre Neidhardt
  2019-11-27 11:08 ` zimoun
  0 siblings, 2 replies; 8+ messages in thread
From: Julien Lepiller @ 2019-11-26 22:11 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 3019 bytes --]

Hi Guix!

Today I have been reading https://www.divio.com/blog/documentation/
which makes some good points on how to write good documentation. They
suggest to divide documentation into four categories, depending on
their purpose:

- tutorials, written for newcomers. They should be to the point and
  guide a new user through every step of using the new system.
- how-tos. They should be "goal-oriented" and allow
  a user who knows what they want to do, to learn how to do it.
- explanations. They are more theoretical and should give more
  knowledge on how it all works.
- reference. It should contain all the technical details of the code.

Following these principles, I propose the attached patch, that changes
the layout a bit. Instead of grouping articles by topic, I suggest
grouping them by one of the first three categories above (the guix
manual is the reference, and it's excellent, so we don't need a
reference documentation in the cookbook).

First, we have tutorials.  We are missing a few things, but I imagine
the following structure: start with a tutorial on guix, the package
manager (helping a newcomer installing guix on a foreign distribution
and taking their first steps with guix: install, remove, pull, upgrade).
Then, we would propose the user to continue reading the tutorial on
installing the guix system, or the guides on more advanced topics in
package management. Then, a tutorial on the guix system will help the
user install and understand the basic concepts of the system, for
instance by installing it first in a virtual machine, then guiding them
through their first install using the graphical installer. At the end,
we would recommend them to continue with the scheme tutorial, because
their configuration is actually a scheme file, and they could get more
power by learning scheme. Or they could continue on to the guides on
how to configure specific things. Then the scheme tutorial and the
packaging tutorial we already have.

The second part of the cookbook would be a bunch of how-tos, this time
grouped by target audience (almost topics): package manager users,
system users and packagers. That's where we would have things like "how
to reproduce a scientific paper", "how to develop a software using
guix", "how to configure my locales", "how to install on Android", "how
to install the system on an ARM board", etc. I think this will be the
biggest part of the cookbook, so I propose to directly have three
chapters for it instead of one with three parts.

The last part would be some discussions on how Guix works, what it is.
This is currently empty, but I think it would make sense to discuss
what a profile is, show how profile generations are symlinks, how the
gc works, why the store is read-only, what is the relation between Guix
and Docker (a recent discussion on the list), why does "guix pull"
create a separate profile, and so on.

I think having such a plan will also help us see what is missing and
how to improve the cookbook concretely. Does it make sense?

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-doc-cookbook-Rework-layout.patch --]
[-- Type: text/x-patch, Size: 38470 bytes --]

From 270c835af7ca3cb214c990048f3f73f049cb80da Mon Sep 17 00:00:00 2001
From: Julien Lepiller <julien@lepiller.eu>
Date: Tue, 26 Nov 2019 22:45:59 +0100
Subject: [PATCH] doc: cookbook: Rework layout.

* doc/guix-cookbook.texi: Rework layout of articles.
---
 doc/guix-cookbook.texi | 784 ++++++++++++++++++++++-------------------
 1 file changed, 414 insertions(+), 370 deletions(-)

diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi
index 869b9666df..4e6418b67d 100644
--- a/doc/guix-cookbook.texi
+++ b/doc/guix-cookbook.texi
@@ -43,9 +43,24 @@ Documentation License''.
 @top GNU Guix Cookbook
 
 This document presents tutorials and detailed examples for GNU@tie{}Guix, a
-functional package management tool written for the GNU system.  Please
-@pxref{Top,,, guix, GNU Guix reference manual} for details about the system,
-its API, and related concepts.
+functional package management tool written for the GNU system.  It is divided
+into three main parts: a section on tutorials that will guide you through your
+first experience with the package manager and many of its basic concepts.
+
+If you are a more experienced user, the second section of this document is for
+you: it contains a list of how-to guides that will guide you through more
+advanced and detailed examples of how to use Guix.  This section is further
+divided into more parts, depending on your profile: whether you are a user of
+the package manager, the distribution or a developper, you will find information
+on what you want to achieve here.
+
+If you are more interested in the concepts behind Guix, how it works internally,
+we recommend that you read the third section of this document.  It contains various
+explanations on Guix, and more theoretical concepts are discussed in this section.
+
+If you are an advanced user of Guix and you want to learn everything that Guix
+can offer you, please @pxref{Top,,, guix, GNU Guix reference manual} for details
+about the system, its API, and related concepts.
 
 @c TRANSLATORS: You can replace the following paragraph with information on
 @c how to join your own translation team and how to report issues with the
@@ -54,11 +69,17 @@ If you would like to translate this document in your native language, consider
 joining the @uref{https://translationproject.org/domain/guix-cookbook.html,
 Translation Project}.
 
+We hope that this document will help you in your journey learning about Guix
+and its concepts.  If you spot any inaccuracy, error or misspelling in this
+document, please report them so we can fix them quickly!  Preferably, send an
+email to help-guix@@gnu.org.
+
 @menu
-* Scheme tutorials::            Meet your new favorite language!
-* Packaging::                   Packaging tutorials
-* System Configuration::        Customizing the GNU System
+* Tutorials::                   Your journey starts here!
 * Advanced package management:: Power to the users!
+* Advanced System Configuration::  Customizing the GNU System
+* Advanced Packaging::          Guides for packagers
+* Theory and Practice::         How it all works
 
 * Acknowledgments::             Thanks!
 * GNU Free Documentation License::  The license of this document.
@@ -67,40 +88,54 @@ Translation Project}.
 @detailmenu
  --- The Detailed Node Listing ---
 
-Scheme tutorials
+Tutorials
 
 * A Scheme Crash Course::       Learn the basics of Scheme
-
-Packaging
-
 * Packaging Tutorial::          Let's add a package to Guix!
 
-System Configuration
+Advanced System Configuration
 
-* Customizing the Kernel::      Creating and using a custom Linux kernel
+* How to Customize the Kernel::  Creating and using a custom Linux kernel
 
+Advanced Packaging
+
+* Guix Profiles in Practice::   Strategies for multiple profiles and manifests.
 
 @end detailmenu
 @end menu
 
 @c *********************************************************************
-@node Scheme tutorials
-@chapter Scheme tutorials
-
-GNU@tie{}Guix is written in the general purpose programming language Scheme,
-and many of its features can be accessed and manipulated programmatically.
-You can use Scheme to generate package definitions, to modify them, to build
-them, to deploy whole operating systems, etc.
+@node Tutorials
+@chapter Tutorials
+
+Welcome to the tutorial section of this document!  These tutorials will guide
+you in your first steps with Guix and its various facets.  You do not need
+to follow these tutorials in any particular order, and you can skip those you
+don't want to learn about.
+
+GNU@tie{}Guix is a package manager designed to respect user freedom.  Guix can
+be used on top of any system running the kernel Linux, or it can be used as a
+standalone operating system distribution.  GNU@tie{}Guix is written in the
+general purpose programming language Scheme, and many of its features can be
+accessed and manipulated programmatically.  You can use Scheme to generate
+package definitions, to modify them, to build them, to deploy whole operating
+systems, etc.
 
 Knowing the basics of how to program in Scheme will unlock many of the
 advanced features Guix provides --- and you don't even need to be an
-experienced programmer to use them!
+experienced programmer to use them!  Start with @ref{A Scheme Crash Course}
+if you are new to Guile.
+
+Guix wouldn't exist without its volunteer packagers, dedicated at maintaining
+and augmenting a package set of more than 10,000 packages!  You can also learn
+how to package your own packages with the @ref{Packaging Tutorial}.  Who knows?
+You might even enjoy contributing some of these to Guix itself!
 
 Let's get started!
 
+@c *********************************************************************
 @node A Scheme Crash Course
 @section A Scheme Crash Course
-
 @cindex Scheme, crash course
 
 Guix uses the Guile implementation of Scheme.  To start playing with the
@@ -278,22 +313,9 @@ You'll find more books, tutorials and other resources at
 
 
 @c *********************************************************************
-@node Packaging
-@chapter Packaging
-
-@cindex packaging
-
-This chapter is dedicated to teaching you how to add packages to the
-collection of packages that come with GNU Guix.  This involves writing package
-definitions in Guile Scheme, organizing them in package modules, and building
-them.
-
-@menu
-* Packaging Tutorial::         A tutorial on how to add packages to Guix.
-@end menu
-
 @node Packaging Tutorial
 @section Packaging Tutorial
+@cindex packaging
 
 GNU Guix stands out as the @emph{hackable} package manager, mostly because it
 uses @uref{https://www.gnu.org/software/guile/, GNU Guile}, a powerful
@@ -1303,372 +1325,117 @@ The @uref{https://www.gnu.org/software/guix/manual/en/html_node/Defining-Package
 @end itemize
 
 @c *********************************************************************
-@node System Configuration
-@chapter System Configuration
+@node Advanced package management
+@chapter Advanced package management
 
-Guix offers a flexible language for declaratively configuring your Guix
-System.  This flexibility can at times be overwhelming.  The purpose of this
-chapter is to demonstrate some advanced configuration concepts.
+Guix is a functional package manager that offers many features beyond
+what more traditional package managers can do.  To the uninitiated,
+those features might not have obvious use cases at first.  The purpose
+of this chapter is to demonstrate some advanced package management
+concepts.
 
-@pxref{System Configuration,,, guix, GNU Guix Reference Manual} for a complete
+@pxref{Package Management,,, guix, GNU Guix Reference Manual} for a complete
 reference.
 
 @menu
-* Customizing the Kernel::     Creating and using a custom Linux kernel on Guix System.
+* Guix Profiles in Practice::     Strategies for multiple profiles and manifests.
 @end menu
 
-@node Customizing the Kernel
-@section Customizing the Kernel
-
-Guix is, at its core, a source based distribution with substitutes
-(@pxref{Substitutes,,, guix, GNU Guix Reference Manual}), and as such building
-packages from their source code is an expected part of regular package
-installations and upgrades.  Given this starting point, it makes sense that
-efforts are made to reduce the amount of time spent compiling packages, and
-recent changes and upgrades to the building and distribution of substitutes
-continues to be a topic of discussion within Guix.
+@node Guix Profiles in Practice
+@section Guix Profiles in Practice
 
-The kernel, while not requiring an overabundance of RAM to build, does take a
-rather long time on an average machine.  The official kernel configuration, as
-is the case with many GNU/Linux distributions, errs on the side of
-inclusiveness, and this is really what causes the build to take such a long
-time when the kernel is built from source.
+Guix provides a very useful feature that may be quite foreign to newcomers:
+@emph{profiles}.  They are a way to group package installations together and all users
+on the same system are free to use as many profiles as they want.
 
-The Linux kernel, however, can also just be described as a regular old
-package, and as such can be customized just like any other package.  The
-procedure is a little bit different, although this is primarily due to the
-nature of how the package definition is written.
+Whether you're a developer or not, you may find that multiple profiles bring you
+great power and flexibility.  While they shift the paradigm somewhat compared to
+@emph{traditional package managers}, they are very convenient to use once you've
+understood how to set them up.
 
-The @code{linux-libre} kernel package definition is actually a procedure which
-creates a package.
+If you are familiar with Python's @samp{virtualenv}, you can think of a profile as a
+kind of universal @samp{virtualenv} that can hold any kind of software whatsoever, not
+just Python software.  Furthermore, profiles are self-sufficient: they capture
+all the runtime dependencies which guarantees that all programs within a profile
+will always work at any point in time.
 
-@lisp
-(define* (make-linux-libre version hash supported-systems
-                           #:key
-                           ;; A function that takes an arch and a variant.
-                           ;; See kernel-config for an example.
-                           (extra-version #f)
-                           (configuration-file #f)
-                           (defconfig "defconfig")
-                           (extra-options %default-extra-linux-options)
-                           (patches (list %boot-logo-patch)))
-  ...)
-@end lisp
+Multiple profiles have many benefits:
 
-The current @code{linux-libre} package is for the 5.1.x series, and is
-declared like this:
+@itemize
+@item
+Clean semantic separation of the various packages a user needs for different contexts.
 
-@lisp
-(define-public linux-libre
-  (make-linux-libre %linux-libre-version
-                    %linux-libre-hash
-                    '("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux")
-                    #:patches %linux-libre-5.1-patches
-                    #:configuration-file kernel-config))
-@end lisp
+@item
+Multiple profiles can be made available into the environment either on login
+or within a dedicated shell.
 
-Any keys which are not assigned values inherit their default value from the
-@code{make-linux-libre} definition.  When comparing the two snippets above,
-you may notice that the code comment in the first doesn't actually refer to
-the @code{#:extra-version} keyword; it is actually for
-@code{#:configuration-file}.  Because of this, it is not actually easy to
-include a custom kernel configuration from the definition, but don't worry,
-there are other ways to work with what we do have.
+@item
+Profiles can be loaded on demand.  For instance, the user can use multiple
+shells, each of them running different profiles.
 
-There are two ways to create a kernel with a custom kernel configuration.  The
-first is to provide a standard @file{.config} file during the build process by
-including an actual @file{.config} file as a native input to our custom
-kernel.  The following is a snippet from the custom @code{'configure} phase of
-the @code{make-linux-libre} package definition:
+@item
+Isolation: Programs from one profile will not use programs from the other, and
+the user can even install different versions of the same programs to the two
+profiles without conflict.
 
-@lisp
-(let ((build  (assoc-ref %standard-phases 'build))
-      (config (assoc-ref (or native-inputs inputs) "kconfig")))
+@item
+Deduplication: Profiles share dependencies that happens to be the exact same.
+This makes multiple profiles storage-efficient.
 
-  ;; Use a custom kernel configuration file or a default
-  ;; configuration file.
-  (if config
-      (begin
-        (copy-file config ".config")
-        (chmod ".config" #o666))
-      (invoke "make" ,defconfig))
-@end lisp
+@item
+Reproducible: when used with declarative manifests, a profile can be fully
+specified by the Guix commit that was active when it was set up.  This means
+that the exact same profile can be
+@uref{https://guix.gnu.org/blog/2018/multi-dimensional-transactions-and-rollbacks-oh-my/,
+set up anywhere and anytime}, with just the commit information.  See the
+section on @ref{Reproducible profiles}.
 
-Below is a sample kernel package.  The @code{linux-libre} package is nothing
-special and can be inherited from and have its fields overridden like any
-other package:
+@item
+Easier upgrades and maintenance: Multiple profiles make it easy to keep
+package listings at hand and make upgrades completely friction-less.
+@end itemize
 
-@lisp
-(define-public linux-libre/E2140
-  (package
-    (inherit linux-libre)
-    (native-inputs
-     `(("kconfig" ,(local-file "E2140.config"))
-      ,@@(alist-delete "kconfig"
-                      (package-native-inputs linux-libre))))))
-@end lisp
+Concretely, here follows some typical profiles:
 
-In the same directory as the file defining @code{linux-libre-E2140} is a file
-named @file{E2140.config}, which is an actual kernel configuration file.  The
-@code{defconfig} keyword of @code{make-linux-libre} is left blank here, so the
-only kernel configuration in the package is the one which was included in the
-@code{native-inputs} field.
+@itemize
+@item
+The dependencies of a project you are working on.
 
-The second way to create a custom kernel is to pass a new value to the
-@code{extra-options} keyword of the @code{make-linux-libre} procedure.  The
-@code{extra-options} keyword works with another function defined right below
-it:
+@item
+Your favourite programming language libraries.
 
-@lisp
-(define %default-extra-linux-options
-  `(;; https://lists.gnu.org/archive/html/guix-devel/2014-04/msg00039.html
-   ("CONFIG_DEVPTS_MULTIPLE_INSTANCES" . #t)
-   ;; Modules required for initrd:
-   ("CONFIG_NET_9P" . m)
-   ("CONFIG_NET_9P_VIRTIO" . m)
-   ("CONFIG_VIRTIO_BLK" . m)
-   ("CONFIG_VIRTIO_NET" . m)
-   ("CONFIG_VIRTIO_PCI" . m)
-   ("CONFIG_VIRTIO_BALLOON" . m)
-   ("CONFIG_VIRTIO_MMIO" . m)
-   ("CONFIG_FUSE_FS" . m)
-   ("CONFIG_CIFS" . m)
-   ("CONFIG_9P_FS" . m)))
+@item
+Laptop-specific programs (like @samp{powertop}) that you don't need on a desktop.
 
-(define (config->string options)
-  (string-join (map (match-lambda
-                      ((option . 'm)
-                       (string-append option "=m"))
-                      ((option . #t)
-                       (string-append option "=y"))
-                      ((option . #f)
-                       (string-append option "=n")))
-                    options)
-               "\n"))
-@end lisp
+@item
+@TeX{}live (this one can be really useful when you need to install just one
+package for this one document you've just received over email).
 
-And in the custom configure script from the `make-linux-libre` package:
+@item
+Games.
+@end itemize
 
-@lisp
-;; Appending works even when the option wasn't in the
-;; file.  The last one prevails if duplicated.
-(let ((port (open-file ".config" "a"))
-      (extra-configuration ,(config->string extra-options)))
-  (display extra-configuration port)
-  (close-port port))
+Let's dive in the set up!
 
-(invoke "make" "oldconfig"))))
-@end lisp
+@node Basic setup with manifests
+@subsection Basic setup with manifests
 
-So by not providing a configuration-file the @file{.config} starts blank, and
-then we write into it the collection of flags that we want.  Here's another
-custom kernel:
+A Guix profile can be set up @emph{via} a so-called @emph{manifest specification} that looks like
+this:
 
 @lisp
-(define %macbook41-full-config
-  (append %macbook41-config-options
-          %filesystems
-          %efi-support
-          %emulation
-          (@@@@ (gnu packages linux) %default-extra-linux-options)))
-
-(define-public linux-libre-macbook41
-  ;; XXX: Access the internal 'make-linux-libre' procedure, which is
-  ;; private and unexported, and is liable to change in the future.
-  ((@@@@ (gnu packages linux) make-linux-libre) (@@@@ (gnu packages linux) %linux-libre-version)
-                      (@@@@ (gnu packages linux) %linux-libre-hash)
-                      '("x86_64-linux")
-                      #:extra-version "macbook41"
-                      #:patches (@@@@ (gnu packages linux) %linux-libre-5.1-patches)
-                      #:extra-options %macbook41-config-options))
+(specifications->manifest
+  '("package-1"
+    ;; Version 1.3 of package-2.
+    "package-2@@1.3"
+    ;; The "lib" output of package-3.
+    "package-3:lib"
+    ; ...
+    "package-N"))
 @end lisp
 
-In the above example @code{%filesystems} is a collection of flags enabling
-different filesystem support, @code{%efi-support} enables EFI support and
-@code{%emulation} enables a x86_64-linux machine to act in 32-bit mode also.
-@code{%default-extra-linux-options} are the ones quoted above, which had to be
-added in since they were replaced in the @code{extra-options} keyword.
-
-This all sounds like it should be doable, but how does one even know which
-modules are required for a particular system?  Two places that can be helpful
-in trying to answer this question is the
-@uref{https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel, Gentoo
-Handbook} and the
-@uref{https://www.kernel.org/doc/html/latest/admin-guide/README.html?highlight=localmodconfig,
-documentation from the kernel itself}.  From the kernel documentation, it
-seems that @code{make localmodconfig} is the command we want.
-
-In order to actually run @code{make localmodconfig} we first need to get and
-unpack the kernel source code:
-
-@example shell
-tar xf $(guix build linux-libre --source)
-@end example
-
-Once inside the directory containing the source code run @code{touch .config}
-to create an initial, empty @file{.config} to start with.  @code{make
-localmodconfig} works by seeing what you already have in @file{.config} and
-letting you know what you're missing.  If the file is blank then you're
-missing everything.  The next step is to run:
-
-@example shell
-guix environment linux-libre -- make localmodconfig
-@end example
-
-and note the output.  Do note that the @file{.config} file is still empty.
-The output generally contains two types of warnings.  The first start with
-"WARNING" and can actually be ignored in our case.  The second read:
-
-@example shell
-module pcspkr did not have configs CONFIG_INPUT_PCSPKR
-@end example
-
-For each of these lines, copy the @code{CONFIG_XXXX_XXXX} portion into the
-@file{.config} in the directory, and append @code{=m}, so in the end it looks
-like this:
-
-@example shell
-CONFIG_INPUT_PCSPKR=m
-CONFIG_VIRTIO=m
-@end example
-
-After copying all the configuration options, run @code{make localmodconfig}
-again to make sure that you don't have any output starting with "module".
-After all of these machine specific modules there are a couple more left that
-are also needed.  @code{CONFIG_MODULES} is necessary so that you can build and
-load modules separately and not have everything built into the kernel.
-@code{CONFIG_BLK_DEV_SD} is required for reading from hard drives.  It is
-possible that there are other modules which you will need.
-
-This post does not aim to be a guide to configuring your own kernel however,
-so if you do decide to build a custom kernel you'll have to seek out other
-guides to create a kernel which is just right for your needs.
-
-The second way to setup the kernel configuration makes more use of Guix's
-features and allows you to share configuration segments between different
-kernels.  For example, all machines using EFI to boot have a number of EFI
-configuration flags that they need.  It is likely that all the kernels will
-share a list of filesystems to support.  By using variables it is easier to
-see at a glance what features are enabled and to make sure you don't have
-features in one kernel but missing in another.
-
-Left undiscussed however, is Guix's initrd and its customization.  It is
-likely that you'll need to modify the initrd on a machine using a custom
-kernel, since certain modules which are expected to be built may not be
-available for inclusion into the initrd.
-
-@c *********************************************************************
-@node Advanced package management
-@chapter Advanced package management
-
-Guix is a functional package manager that offers many features beyond
-what more traditional package managers can do.  To the uninitiated,
-those features might not have obvious use cases at first.  The purpose
-of this chapter is to demonstrate some advanced package management
-concepts.
-
-@pxref{Package Management,,, guix, GNU Guix Reference Manual} for a complete
-reference.
-
-@menu
-* Guix Profiles in Practice::     Strategies for multiple profiles and manifests.
-@end menu
-
-@node Guix Profiles in Practice
-@section Guix Profiles in Practice
-
-Guix provides a very useful feature that may be quite foreign to newcomers:
-@emph{profiles}.  They are a way to group package installations together and all users
-on the same system are free to use as many profiles as they want.
-
-Whether you're a developer or not, you may find that multiple profiles bring you
-great power and flexibility.  While they shift the paradigm somewhat compared to
-@emph{traditional package managers}, they are very convenient to use once you've
-understood how to set them up.
-
-If you are familiar with Python's @samp{virtualenv}, you can think of a profile as a
-kind of universal @samp{virtualenv} that can hold any kind of software whatsoever, not
-just Python software.  Furthermore, profiles are self-sufficient: they capture
-all the runtime dependencies which guarantees that all programs within a profile
-will always work at any point in time.
-
-Multiple profiles have many benefits:
-
-@itemize
-@item
-Clean semantic separation of the various packages a user needs for different contexts.
-
-@item
-Multiple profiles can be made available into the environment either on login
-or within a dedicated shell.
-
-@item
-Profiles can be loaded on demand.  For instance, the user can use multiple
-shells, each of them running different profiles.
-
-@item
-Isolation: Programs from one profile will not use programs from the other, and
-the user can even install different versions of the same programs to the two
-profiles without conflict.
-
-@item
-Deduplication: Profiles share dependencies that happens to be the exact same.
-This makes multiple profiles storage-efficient.
-
-@item
-Reproducible: when used with declarative manifests, a profile can be fully
-specified by the Guix commit that was active when it was set up.  This means
-that the exact same profile can be
-@uref{https://guix.gnu.org/blog/2018/multi-dimensional-transactions-and-rollbacks-oh-my/,
-set up anywhere and anytime}, with just the commit information.  See the
-section on @ref{Reproducible profiles}.
-
-@item
-Easier upgrades and maintenance: Multiple profiles make it easy to keep
-package listings at hand and make upgrades completely friction-less.
-@end itemize
-
-Concretely, here follows some typical profiles:
-
-@itemize
-@item
-The dependencies of a project you are working on.
-
-@item
-Your favourite programming language libraries.
-
-@item
-Laptop-specific programs (like @samp{powertop}) that you don't need on a desktop.
-
-@item
-@TeX{}live (this one can be really useful when you need to install just one
-package for this one document you've just received over email).
-
-@item
-Games.
-@end itemize
-
-Let's dive in the set up!
-
-@node Basic setup with manifests
-@subsection Basic setup with manifests
-
-A Guix profile can be set up @emph{via} a so-called @emph{manifest specification} that looks like
-this:
-
-@lisp
-(specifications->manifest
-  '("package-1"
-    ;; Version 1.3 of package-2.
-    "package-2@@1.3"
-    ;; The "lib" output of package-3.
-    "package-3:lib"
-    ; ...
-    "package-N"))
-@end lisp
-
-@pxref{Invoking guix package,,, guix, GNU Guix Reference Manual}, for
-the syntax details.
+@pxref{Invoking guix package,,, guix, GNU Guix Reference Manual}, for
+the syntax details.
 
 We can create a manifest specification per profile and install them this way:
 
@@ -1955,6 +1722,283 @@ mkdir -p "$GUIX_EXTRA_PROFILES/my-project"
 It's safe to delete the Guix channel profile you've just installed with the
 channel specification, the project profile does not depend on it.
 
+@node Advanced System Configuration
+@chapter Advanced System Configuration
+
+Guix offers a flexible language for declaratively configuring your Guix
+System.  This flexibility can at times be overwhelming.  The purpose of this
+chapter is to demonstrate some advanced configuration concepts.
+
+@pxref{System Configuration,,, guix, GNU Guix Reference Manual} for a complete
+reference.
+
+@menu
+* How to Customize the Kernel::  Creating and using a custom Linux kernel on Guix System.
+@end menu
+
+@node How to Customize the Kernel
+@section How to Customize the Kernel
+
+Guix is, at its core, a source based distribution with substitutes
+(@pxref{Substitutes,,, guix, GNU Guix Reference Manual}), and as such building
+packages from their source code is an expected part of regular package
+installations and upgrades.  Given this starting point, it makes sense that
+efforts are made to reduce the amount of time spent compiling packages, and
+recent changes and upgrades to the building and distribution of substitutes
+continues to be a topic of discussion within Guix.
+
+The kernel, while not requiring an overabundance of RAM to build, does take a
+rather long time on an average machine.  The official kernel configuration, as
+is the case with many GNU/Linux distributions, errs on the side of
+inclusiveness, and this is really what causes the build to take such a long
+time when the kernel is built from source.
+
+The Linux kernel, however, can also just be described as a regular old
+package, and as such can be customized just like any other package.  The
+procedure is a little bit different, although this is primarily due to the
+nature of how the package definition is written.
+
+The @code{linux-libre} kernel package definition is actually a procedure which
+creates a package.
+
+@lisp
+(define* (make-linux-libre version hash supported-systems
+                           #:key
+                           ;; A function that takes an arch and a variant.
+                           ;; See kernel-config for an example.
+                           (extra-version #f)
+                           (configuration-file #f)
+                           (defconfig "defconfig")
+                           (extra-options %default-extra-linux-options)
+                           (patches (list %boot-logo-patch)))
+  ...)
+@end lisp
+
+The current @code{linux-libre} package is for the 5.1.x series, and is
+declared like this:
+
+@lisp
+(define-public linux-libre
+  (make-linux-libre %linux-libre-version
+                    %linux-libre-hash
+                    '("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux")
+                    #:patches %linux-libre-5.1-patches
+                    #:configuration-file kernel-config))
+@end lisp
+
+Any keys which are not assigned values inherit their default value from the
+@code{make-linux-libre} definition.  When comparing the two snippets above,
+you may notice that the code comment in the first doesn't actually refer to
+the @code{#:extra-version} keyword; it is actually for
+@code{#:configuration-file}.  Because of this, it is not actually easy to
+include a custom kernel configuration from the definition, but don't worry,
+there are other ways to work with what we do have.
+
+There are two ways to create a kernel with a custom kernel configuration.  The
+first is to provide a standard @file{.config} file during the build process by
+including an actual @file{.config} file as a native input to our custom
+kernel.  The following is a snippet from the custom @code{'configure} phase of
+the @code{make-linux-libre} package definition:
+
+@lisp
+(let ((build  (assoc-ref %standard-phases 'build))
+      (config (assoc-ref (or native-inputs inputs) "kconfig")))
+
+  ;; Use a custom kernel configuration file or a default
+  ;; configuration file.
+  (if config
+      (begin
+        (copy-file config ".config")
+        (chmod ".config" #o666))
+      (invoke "make" ,defconfig))
+@end lisp
+
+Below is a sample kernel package.  The @code{linux-libre} package is nothing
+special and can be inherited from and have its fields overridden like any
+other package:
+
+@lisp
+(define-public linux-libre/E2140
+  (package
+    (inherit linux-libre)
+    (native-inputs
+     `(("kconfig" ,(local-file "E2140.config"))
+      ,@@(alist-delete "kconfig"
+                      (package-native-inputs linux-libre))))))
+@end lisp
+
+In the same directory as the file defining @code{linux-libre-E2140} is a file
+named @file{E2140.config}, which is an actual kernel configuration file.  The
+@code{defconfig} keyword of @code{make-linux-libre} is left blank here, so the
+only kernel configuration in the package is the one which was included in the
+@code{native-inputs} field.
+
+The second way to create a custom kernel is to pass a new value to the
+@code{extra-options} keyword of the @code{make-linux-libre} procedure.  The
+@code{extra-options} keyword works with another function defined right below
+it:
+
+@lisp
+(define %default-extra-linux-options
+  `(;; https://lists.gnu.org/archive/html/guix-devel/2014-04/msg00039.html
+   ("CONFIG_DEVPTS_MULTIPLE_INSTANCES" . #t)
+   ;; Modules required for initrd:
+   ("CONFIG_NET_9P" . m)
+   ("CONFIG_NET_9P_VIRTIO" . m)
+   ("CONFIG_VIRTIO_BLK" . m)
+   ("CONFIG_VIRTIO_NET" . m)
+   ("CONFIG_VIRTIO_PCI" . m)
+   ("CONFIG_VIRTIO_BALLOON" . m)
+   ("CONFIG_VIRTIO_MMIO" . m)
+   ("CONFIG_FUSE_FS" . m)
+   ("CONFIG_CIFS" . m)
+   ("CONFIG_9P_FS" . m)))
+
+(define (config->string options)
+  (string-join (map (match-lambda
+                      ((option . 'm)
+                       (string-append option "=m"))
+                      ((option . #t)
+                       (string-append option "=y"))
+                      ((option . #f)
+                       (string-append option "=n")))
+                    options)
+               "\n"))
+@end lisp
+
+And in the custom configure script from the `make-linux-libre` package:
+
+@lisp
+;; Appending works even when the option wasn't in the
+;; file.  The last one prevails if duplicated.
+(let ((port (open-file ".config" "a"))
+      (extra-configuration ,(config->string extra-options)))
+  (display extra-configuration port)
+  (close-port port))
+
+(invoke "make" "oldconfig"))))
+@end lisp
+
+So by not providing a configuration-file the @file{.config} starts blank, and
+then we write into it the collection of flags that we want.  Here's another
+custom kernel:
+
+@lisp
+(define %macbook41-full-config
+  (append %macbook41-config-options
+          %filesystems
+          %efi-support
+          %emulation
+          (@@@@ (gnu packages linux) %default-extra-linux-options)))
+
+(define-public linux-libre-macbook41
+  ;; XXX: Access the internal 'make-linux-libre' procedure, which is
+  ;; private and unexported, and is liable to change in the future.
+  ((@@@@ (gnu packages linux) make-linux-libre) (@@@@ (gnu packages linux) %linux-libre-version)
+                      (@@@@ (gnu packages linux) %linux-libre-hash)
+                      '("x86_64-linux")
+                      #:extra-version "macbook41"
+                      #:patches (@@@@ (gnu packages linux) %linux-libre-5.1-patches)
+                      #:extra-options %macbook41-config-options))
+@end lisp
+
+In the above example @code{%filesystems} is a collection of flags enabling
+different filesystem support, @code{%efi-support} enables EFI support and
+@code{%emulation} enables a x86_64-linux machine to act in 32-bit mode also.
+@code{%default-extra-linux-options} are the ones quoted above, which had to be
+added in since they were replaced in the @code{extra-options} keyword.
+
+This all sounds like it should be doable, but how does one even know which
+modules are required for a particular system?  Two places that can be helpful
+in trying to answer this question is the
+@uref{https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel, Gentoo
+Handbook} and the
+@uref{https://www.kernel.org/doc/html/latest/admin-guide/README.html?highlight=localmodconfig,
+documentation from the kernel itself}.  From the kernel documentation, it
+seems that @code{make localmodconfig} is the command we want.
+
+In order to actually run @code{make localmodconfig} we first need to get and
+unpack the kernel source code:
+
+@example shell
+tar xf $(guix build linux-libre --source)
+@end example
+
+Once inside the directory containing the source code run @code{touch .config}
+to create an initial, empty @file{.config} to start with.  @code{make
+localmodconfig} works by seeing what you already have in @file{.config} and
+letting you know what you're missing.  If the file is blank then you're
+missing everything.  The next step is to run:
+
+@example shell
+guix environment linux-libre -- make localmodconfig
+@end example
+
+and note the output.  Do note that the @file{.config} file is still empty.
+The output generally contains two types of warnings.  The first start with
+"WARNING" and can actually be ignored in our case.  The second read:
+
+@example shell
+module pcspkr did not have configs CONFIG_INPUT_PCSPKR
+@end example
+
+For each of these lines, copy the @code{CONFIG_XXXX_XXXX} portion into the
+@file{.config} in the directory, and append @code{=m}, so in the end it looks
+like this:
+
+@example shell
+CONFIG_INPUT_PCSPKR=m
+CONFIG_VIRTIO=m
+@end example
+
+After copying all the configuration options, run @code{make localmodconfig}
+again to make sure that you don't have any output starting with "module".
+After all of these machine specific modules there are a couple more left that
+are also needed.  @code{CONFIG_MODULES} is necessary so that you can build and
+load modules separately and not have everything built into the kernel.
+@code{CONFIG_BLK_DEV_SD} is required for reading from hard drives.  It is
+possible that there are other modules which you will need.
+
+This post does not aim to be a guide to configuring your own kernel however,
+so if you do decide to build a custom kernel you'll have to seek out other
+guides to create a kernel which is just right for your needs.
+
+The second way to setup the kernel configuration makes more use of Guix's
+features and allows you to share configuration segments between different
+kernels.  For example, all machines using EFI to boot have a number of EFI
+configuration flags that they need.  It is likely that all the kernels will
+share a list of filesystems to support.  By using variables it is easier to
+see at a glance what features are enabled and to make sure you don't have
+features in one kernel but missing in another.
+
+Left undiscussed however, is Guix's initrd and its customization.  It is
+likely that you'll need to modify the initrd on a machine using a custom
+kernel, since certain modules which are expected to be built may not be
+available for inclusion into the initrd.
+
+@c *********************************************************************
+@node Advanced Packaging
+@chapter Advanced Packaging
+
+One of the goals of GNU@tie{}Guix as a package manager is to provide users with
+facilities to create their own packages.  This section is dedicated to guides
+on how to perform some packaging tasks that are not covered by the packaging
+tutorial.
+
+This section is currently empty.  We appreciate any help you can provide!
+
+@c *********************************************************************
+@node Theory and Practice
+@chapter Theory and Practice
+
+GNU@tie{}Guix uses many theoretical concepts and has a very unique way of
+working that can be very puzzling to people used to more traditional forms
+of package management.  This section will teach you all the theoretical
+knowledge, implementation choices and inner workings of Guix that you need
+to fully grasp it.
+
+This section is currently empty.  We appreciate any help you can provide!
+
 @c *********************************************************************
 @node Acknowledgments
 @chapter Acknowledgments
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-11-28  0:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-26 22:11 Reworking the cookbook layout Julien Lepiller
2019-11-27 10:21 ` Pierre Neidhardt
2019-11-27 14:21   ` sirgazil
2019-11-27 11:08 ` zimoun
2019-11-27 12:14   ` Julien Lepiller
2019-11-27 15:26     ` zimoun
2019-11-27 17:47       ` Julien Lepiller
2019-11-28  0:43   ` Bengt Richter

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).