summaryrefslogtreecommitdiff
path: root/doc/guix-cookbook.texi
blob: 66f94a0fe7c912267bb42251d7c6b561a872664c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
\input texinfo
@c -*-texinfo-*-

@c %**start of header
@setfilename guix-cookbook.info
@documentencoding UTF-8
@settitle GNU Guix Cookbook
@c %**end of header

@copying
Copyright @copyright{} 2019 Ricardo Wurmus@*
Copyright @copyright{} 2019 Efraim Flashner@*
Copyright @copyright{} 2019 Pierre Neidhardt@*

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
copy of the license is included in the section entitled ``GNU Free
Documentation License''.
@end copying

@dircategory System administration
@direntry
* Guix cookbook: (guix-cookbook).    Tutorials and examples for GNU Guix.
@end direntry

@titlepage
@title GNU Guix Cookbook
@subtitle Tutorials and examples for using the GNU Guix Functional Package Manager
@author The GNU Guix Developers

@page
@vskip 0pt plus 1filll

@insertcopying
@end titlepage

@contents

@c *********************************************************************
@node Top
@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.

@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
@c translation.
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}.

@menu
* Scheme tutorials::            Meet your new favorite language!
* Packaging::                   Packaging tutorials
* System Configuration::        Customizing the GNU System

* Acknowledgments::             Thanks!
* GNU Free Documentation License::  The license of this document.
* Concept Index::               Concepts.

@detailmenu
 --- The Detailed Node Listing ---

Scheme tutorials

* A Scheme Crash Course::       Learn the basics of Scheme

Packaging

* Packaging Tutorial::          Let's add a package to Guix!

System Configuration

* Customizing the Kernel::      Creating and using a custom Linux kernel


@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.

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!

Let's get started!

@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
language, install it with @code{guix install guile} and start a
@uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,
REPL} by running @code{guile} from the command line.

Alternatively you can also run @code{guix environment --ad-hoc guile -- guile}
if you'd rather not have Guile installed in your user profile.

In the following examples we use the @code{>} symbol to denote the REPL
prompt, that is, the line reserved for user input.  @xref{Using Guile
Interactively,,, guile, GNU Guile Reference Manual}) for more details on the
REPL.

@itemize
@item
Scheme syntax boils down to a tree of expressions (or @emph{s-expression} in
Lisp lingo).  An expression can be a literal such as numbers and strings, or a
compound which is a parenthesized list of compounds and literals.  @code{#t}
and @code{#f} stand for the booleans "true" and "false", respectively.

Examples of valid expressions:

@example scheme
> "Hello World!"
"Hello World!"
> 17
17
> (display (string-append "Hello " "Guix" "\n"))
"Hello Guix!"
@end example

@item
This last example is a function call nested in another function call.  When a
parenthesized expression is evaluated, the first term is the function and the
rest are the arguments passed to the function.  Every function returns the
last evaluated expression as its return value.

@item
Anonymous functions are declared with the @code{lambda} term:

@example scheme
> (lambda (x) (* x x))
#<procedure 120e348 at <unknown port>:24:0 (x)>
@end example

The above procedure returns the square of its argument.  Since everything is
an expression, the @code{lambda} expression returns an anonymous procedure,
which can in turn be applied to an argument:

@example scheme
> ((lambda (x) (* x x)) 3)
9
@end example

@item
Anything can be assigned a global name with @code{define}:

@example scheme
> (define a 3)
> (define square (lambda (x) (* x x)))
> (square a)
9
@end example

@item
Procedures can be defined more concisely with the following syntax:

@example scheme
(define (square x) (* x x))
@end example

@item
A list structure can be created with the @code{list} procedure:

@example scheme
> (list 2 a 5 7)
(2 3 5 7)
@end example

@item
The @emph{quote} disables evaluation of a parenthesized expression: the first
term is not called over the other terms.  Thus it effectively returns a list
of terms.

@example scheme
> '(display (string-append "Hello " "Guix" "\n"))
(display (string-append "Hello " "Guix" "\n"))
> '(2 a 5 7)
(2 a 5 7)
@end example

@item
The @emph{quasiquote} disables evaluation of a parenthesized expression until
a comma re-enables it.  Thus it provides us with fine-grained control over
what is evaluated and what is not.

@example scheme
> `(2 a 5 7 (2 ,a 5 ,(+ a 4)))
(2 a 5 7 (2 3 5 7))
@end example

Note that the above result is a list of mixed elements: numbers, symbols (here
@code{a}) and the last element is a list itself.

@item
Multiple variables can be named locally with @code{let}:

@example scheme
> (define x 10)
> (let ((x 2)
        (y 3))
    (list x y))
(2 3)
> x
10
> y
ERROR: In procedure module-lookup: Unbound variable: y
@end example

Use @code{let*} to allow later variable declarations to refer to earlier
definitions.

@example scheme
> (let* ((x 2)
         (y (* x 3)))
    (list x y))
(2 6)
@end example

@item
The keyword syntax is @code{#:}; it is used to create unique identifiers.
@pxref{Keywords,,, guile, GNU Guile Reference Manual}.

@item
The percentage @code{%} is typically used for read-only global variables in
the build stage.  Note that it is merely a convention, like @code{_} in C.
Scheme treats @code{%} exactly the same as any other letter.

@item
Modules are created with @code{define-module}.  For instance

@example scheme
(define-module (guix build-system ruby)
  #:use-module (guix store)
  #:export (ruby-build
            ruby-build-system))
@end example

defines the module @code{guix build-system ruby} which must be located in
@file{guix/build-system/ruby.scm} somewhere in the Guile load path.  It
depends on the @code{(guix store)} module and it exports two variables,
@code{ruby-build} and @code{ruby-build-system}.
@end itemize

For a more detailed introduction, check out
@uref{http://www.troubleshooters.com/codecorn/scheme_guile/hello.htm, Scheme
at a Glance}, by Steve Litt.

One of the reference Scheme books is the seminal ``Structure and
Interpretation of Computer Programs'', by Harold Abelson and Gerald Jay
Sussman, with Julie Sussman.  You'll find a
@uref{https://mitpress.mit.edu/sites/default/files/sicp/index.html, free copy
online}, together with
@uref{https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/,
videos of the lectures by the authors}.  The book is available in Texinfo
format as the @code{sicp} Guix package.  Go ahead, run @code{guix install
sicp} and start reading with @code{info sicp} (or with the Emacs Info reader).
An @uref{https://sarabander.github.io/sicp/, unofficial ebook is also
available}.

You'll find more books, tutorials and other resources at
@url{https://schemers.org/}.


@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

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
high-level programming language, one of the
@uref{https://en.wikipedia.org/wiki/Scheme_%28programming_language%29, Scheme}
dialects from the
@uref{https://en.wikipedia.org/wiki/Lisp_%28programming_language%29, Lisp family}.

Package definitions are also written in Scheme, which empowers Guix in some
very unique ways, unlike most other package managers that use shell scripts or
simple languages.

@itemize
@item
Use functions, structures, macros and all of Scheme expressiveness for your
package definitions.

@item
Inheritance makes it easy to customize a package by inheriting from it and
modifying only what is needed.
 
@item
Batch processing: the whole package collection can be parsed, filtered and
processed.  Building a headless server with all graphical interfaces stripped
out?  It's possible.  Want to rebuild everything from source using specific
compiler optimization flags?  Pass the @code{#:make-flags "..."} argument to
the list of packages.  It wouldn't be a stretch to think
@uref{https://wiki.gentoo.org/wiki/USE_flag, Gentoo USE flags} here, but this
goes even further: the changes don't have to be thought out beforehand by the
packager, they can be @emph{programmed} by the user!
@end itemize

The following tutorial covers all the basics around package creation with Guix.
It does not assume much knowledge of the Guix system nor of the Lisp language.
The reader is only expected to be familiar with the command line and to have some
basic programming knowledge.

@subsection A "Hello World" package

The “Defining Packages” section of the manual introduces the basics of Guix
packaging (@pxref{Defining Packages,,, guix, GNU Guix Reference Manual}).  In
the following section, we will partly go over those basics again.

``GNU hello'' is a dummy project that serves as an idiomatic example for
packaging.  It uses the GNU build system (@code{./configure && make && make
install}).  Guix already provides a package definition which is a perfect
example to start with.  You can look up its declaration with @code{guix edit
hello} from the command line.  Let's see how it looks:

@example scheme
(define-public hello
  (package
    (name "hello")
    (version "2.10")
    (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/hello/hello-" version
                                  ".tar.gz"))
              (sha256
               (base32
                "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
    (build-system gnu-build-system)
    (synopsis "Hello, GNU world: An example GNU package")
    (description
     "GNU Hello prints the message \"Hello, world!\" and then exits.  It
serves as an example of standard GNU coding practices.  As such, it supports
command-line arguments, multiple languages, and so on.")
    (home-page "https://www.gnu.org/software/hello/")
    (license gpl3+)))
@end example

As you can see, most of it is rather straightforward.  But let's review the
fields together:

@table @samp
@item name
The project name.  Using Scheme conventions, we prefer to keep it
lower case, without underscore and using dash-separated words.

@item source
This field contains a description of the source code origin.  The
@code{origin} record contains these fields:

@enumerate
@item  The method, here @code{url-fetch} to download via HTTP/FTP, but other methods
    exist, such as @code{git-fetch} for Git repositories.
@item  The URI, which is typically some @code{https://} location for @code{url-fetch}.  Here
    the special `mirror://gnu` refers to a set of well known locations, all of
    which can be used by Guix to fetch the source, should some of them fail.
@item  The @code{sha256} checksum of the requested file.  This is essential to ensure
    the source is not corrupted.  Note that Guix works with base32 strings,
    hence the call to the @code{base32} function.
@end enumerate

@item build-system

This is where the power of abstraction provided by the Scheme language really
shines: in this case, the @code{gnu-build-system} abstracts away the famous
@code{./configure && make && make install} shell invocations.  Other build
systems include the @code{trivial-build-system} which does not do anything and
requires from the packager to program all the build steps, the
@code{python-build-system}, the @code{emacs-build-system}, and many more
(@pxref{Build Systems,,, guix, GNU Guix Reference Manual}).

@item synopsis
It should be a concise summary of what the package does.  For many packages a
tagline from the project's home page can be used as the synopsis.

@item description
Same as for the synopsis, it's fine to re-use the project description from the
homepage.  Note that Guix uses Texinfo syntax.

@item home-page
Use HTTPS if available.

@item license
See @code{guix/licenses.scm} in the project source for a full list of
available licenses.
@end table

Time to build our first package!  Nothing fancy here for now: we will stick to a
dummy "my-hello", a copy of the above declaration.

As with the ritualistic "Hello World" taught with most programming languages,
this will possibly be the most "manual" approach.  We will work out an ideal
setup later; for now we will go the simplest route.

Save the following to a file @file{my-hello.scm}.

@example scheme
(use-modules (guix packages)
             (guix download)
             (guix build-system gnu)
             (guix licenses))

(package
  (name "my-hello")
  (version "2.10")
  (source (origin
            (method url-fetch)
            (uri (string-append "mirror://gnu/hello/hello-" version
                                ".tar.gz"))
            (sha256
             (base32
              "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
  (build-system gnu-build-system)
  (synopsis "Hello, Guix world: An example custom Guix package")
  (description
   "GNU Hello prints the message \"Hello, world!\" and then exits.  It
serves as an example of standard GNU coding practices.  As such, it supports
command-line arguments, multiple languages, and so on.")
  (home-page "https://www.gnu.org/software/hello/")
  (license gpl3+))
@end example

We will explain the extra code in a moment.

Feel free to play with the different values of the various fields.  If you
change the source, you'll need to update the checksum.  Indeed, Guix refuses to
build anything if the given checksum does not match the computed checksum of the
source code.  To obtain the correct checksum of the package declaration, we
need to download the source, compute the sha256 checksum and convert it to
base32.

Thankfully, Guix can automate this task for us; all we need is to provide the
URI:

@c TRANSLATORS: This is example shell output.
@example sh
$ guix download mirror://gnu/hello/hello-2.10.tar.gz

Starting download of /tmp/guix-file.JLYgL7
From https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz...
following redirection to `https://mirror.ibcp.fr/pub/gnu/hello/hello-2.10.tar.gz'...
 …10.tar.gz  709KiB                                 2.5MiB/s 00:00 [##################] 100.0%
/gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i
@end example

In this specific case the output tells us which mirror was chosen.
If the result of the above command is not the same as in the above snippet,
update your @code{my-hello} declaration accordingly.

Note that GNU package tarballs come with an OpenPGP signature, so you
should definitely check the signature of this tarball with `gpg` to
authenticate it before going further:

@c TRANSLATORS: This is example shell output.
@example sh
$ guix download mirror://gnu/hello/hello-2.10.tar.gz.sig

Starting download of /tmp/guix-file.03tFfb
From https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz.sig...
following redirection to `https://ftp.igh.cnrs.fr/pub/gnu/hello/hello-2.10.tar.gz.sig'...
 ….tar.gz.sig  819B                                                                                                                       1.2MiB/s 00:00 [##################] 100.0%
/gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig
0q0v86n3y38z17rl146gdakw9xc4mcscpk8dscs412j22glrv9jf
$ gpg --verify /gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig /gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz
gpg: Signature made Sun 16 Nov 2014 01:08:37 PM CET
gpg:                using RSA key A9553245FDE9B739
gpg: Good signature from "Sami Kerola <kerolasa@@iki.fi>" [unknown]
gpg:                 aka "Sami Kerola (http://www.iki.fi/kerolasa/) <kerolasa@@iki.fi>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 8ED3 96E3 7E38 D471 A005  30D3 A955 3245 FDE9 B739
@end example

You can then happily run

@c TRANSLATORS: Do not translate this command
@example sh
$ guix package --install-from-file=my-hello.scm
@end example

You should now have @code{my-hello} in your profile!

@c TRANSLATORS: Do not translate this command
@example sh
$ guix package --list-installed=my-hello
my-hello	2.10	out
/gnu/store/f1db2mfm8syb8qvc357c53slbvf1g9m9-my-hello-2.10
@end example

We've gone as far as we could without any knowledge of Scheme.  Before moving
on to more complex packages, now is the right time to brush up on your Scheme
knowledge.  @pxref{A Scheme Crash Course} to get up to speed.

@c TODO: Continue the tutorial


@c *********************************************************************
@node System Configuration
@chapter 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
* Customizing the Kernel::     Creating and using a custom Linux kernel on Guix System.
@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.

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.

@example scheme
(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 example

The current @code{linux-libre} package is for the 5.1.x series, and is
declared like this:

@example scheme
(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 example

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:

@example scheme
(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 example

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:

@example scheme
(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 example

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:

@example scheme
(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 example

And in the custom configure script from the `make-linux-libre` package:

@example scheme
;; 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 example

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:

@example scheme
(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 example

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 Acknowledgments
@chapter Acknowledgments

Guix is based on the @uref{https://nixos.org/nix/, Nix package manager},
which was designed and
implemented by Eelco Dolstra, with contributions from other people (see
the @file{nix/AUTHORS} file in Guix.)  Nix pioneered functional package
management, and promoted unprecedented features, such as transactional
package upgrades and rollbacks, per-user profiles, and referentially
transparent build processes.  Without this work, Guix would not exist.

The Nix-based software distributions, Nixpkgs and NixOS, have also been
an inspiration for Guix.

GNU@tie{}Guix itself is a collective work with contributions from a
number of people.  See the @file{AUTHORS} file in Guix for more
information on these fine people.  The @file{THANKS} file lists people
who have helped by reporting bugs, taking care of the infrastructure,
providing artwork and themes, making suggestions, and more---thank you!

This document includes adapted sections from articles that have previously
been published on the Guix blog at @uref{https://guix.gnu.org/blog}.


@c *********************************************************************
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@cindex license, GNU Free Documentation License
@include fdl-1.3.texi

@c *********************************************************************
@node Concept Index
@unnumbered Concept Index
@printindex cp

@bye

@c Local Variables:
@c ispell-local-dictionary: "american";
@c End: