From 270c835af7ca3cb214c990048f3f73f049cb80da Mon Sep 17 00:00:00 2001 From: Julien Lepiller 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