Commit | Line | Data |
---|---|---|
7bc46ecc RW |
1 | \input texinfo |
2 | @c -*-texinfo-*- | |
3 | ||
4 | @c %**start of header | |
5 | @setfilename guix-cookbook.info | |
6 | @documentencoding UTF-8 | |
7 | @settitle GNU Guix Cookbook | |
8 | @c %**end of header | |
9 | ||
10 | @copying | |
11 | Copyright @copyright{} 2019 Ricardo Wurmus@* | |
12 | Copyright @copyright{} 2019 Efraim Flashner@* | |
13 | Copyright @copyright{} 2019 Pierre Neidhardt@* | |
14 | ||
15 | Permission is granted to copy, distribute and/or modify this document | |
16 | under the terms of the GNU Free Documentation License, Version 1.3 or | |
17 | any later version published by the Free Software Foundation; with no | |
18 | Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A | |
19 | copy of the license is included in the section entitled ``GNU Free | |
20 | Documentation License''. | |
21 | @end copying | |
22 | ||
23 | @dircategory System administration | |
24 | @direntry | |
25 | * Guix cookbook: (guix-cookbook). Tutorials and examples for GNU Guix. | |
26 | @end direntry | |
27 | ||
28 | @titlepage | |
29 | @title GNU Guix Cookbook | |
30 | @subtitle Tutorials and examples for using the GNU Guix Functional Package Manager | |
31 | @author The GNU Guix Developers | |
32 | ||
33 | @page | |
34 | @vskip 0pt plus 1filll | |
35 | ||
36 | @insertcopying | |
37 | @end titlepage | |
38 | ||
39 | @contents | |
40 | ||
41 | @c ********************************************************************* | |
42 | @node Top | |
43 | @top GNU Guix Cookbook | |
44 | ||
45 | This document presents tutorials and detailed examples for GNU@tie{}Guix, a | |
46 | functional package management tool written for the GNU system. Please | |
47 | @pxref{Top,,, guix, GNU Guix reference manual} for details about the system, | |
48 | its API, and related concepts. | |
49 | ||
50 | @c TRANSLATORS: You can replace the following paragraph with information on | |
51 | @c how to join your own translation team and how to report issues with the | |
52 | @c translation. | |
53 | If you would like to translate this document in your native language, consider | |
54 | joining the @uref{https://translationproject.org/domain/guix-cookbook.html, | |
55 | Translation Project}. | |
56 | ||
57 | @menu | |
58 | * Scheme tutorials:: Meet your new favorite language! | |
59 | * Packaging:: Packaging tutorials | |
60 | * System Configuration:: Customizing the GNU System | |
61 | ||
62 | * Acknowledgments:: Thanks! | |
63 | * GNU Free Documentation License:: The license of this document. | |
64 | * Concept Index:: Concepts. | |
65 | ||
66 | @detailmenu | |
67 | --- The Detailed Node Listing --- | |
68 | ||
69 | Scheme tutorials | |
70 | ||
71 | * A Scheme Crash Course:: Learn the basics of Scheme | |
72 | ||
73 | Packaging | |
74 | ||
75 | * Packaging Tutorial:: Let's add a package to Guix! | |
76 | ||
77 | System Configuration | |
78 | ||
79 | * Customizing the Kernel:: Creating and using a custom Linux kernel | |
80 | ||
81 | ||
82 | @end detailmenu | |
83 | @end menu | |
84 | ||
85 | @c ********************************************************************* | |
86 | @node Scheme tutorials | |
87 | @chapter Scheme tutorials | |
88 | ||
89 | GNU@tie{}Guix is written in the general purpose programming language Scheme, | |
90 | and many of its features can be accessed and manipulated programmatically. | |
91 | You can use Scheme to generate package definitions, to modify them, to build | |
92 | them, to deploy whole operating systems, etc. | |
93 | ||
94 | Knowing the basics of how to program in Scheme will unlock many of the | |
95 | advanced features Guix provides --- and you don't even need to be an | |
96 | experienced programmer to use them! | |
97 | ||
98 | Let's get started! | |
99 | ||
100 | @node A Scheme Crash Course | |
101 | @section A Scheme Crash Course | |
102 | ||
103 | @cindex Scheme, crash course | |
104 | ||
105 | Guix uses the Guile implementation of Scheme. To start playing with the | |
106 | language, install it with @code{guix install guile} and start a | |
107 | @uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop, | |
108 | REPL} by running @code{guile} from the command line. | |
109 | ||
110 | Alternatively you can also run @code{guix environment --ad-hoc guile -- guile} | |
111 | if you'd rather not have Guile installed in your user profile. | |
112 | ||
113 | In the following examples we use the @code{>} symbol to denote the REPL | |
114 | prompt, that is, the line reserved for user input. @xref{Using Guile | |
115 | Interactively,,, guile, GNU Guile Reference Manual}) for more details on the | |
116 | REPL. | |
117 | ||
118 | @itemize | |
119 | @item | |
120 | Scheme syntax boils down to a tree of expressions (or @emph{s-expression} in | |
121 | Lisp lingo). An expression can be a literal such as numbers and strings, or a | |
122 | compound which is a parenthesized list of compounds and literals. @code{#t} | |
123 | and @code{#f} stand for the booleans "true" and "false", respectively. | |
124 | ||
125 | Examples of valid expressions: | |
126 | ||
127 | @example scheme | |
128 | > "Hello World!" | |
129 | "Hello World!" | |
130 | > 17 | |
131 | 17 | |
132 | > (display (string-append "Hello " "Guix" "\n")) | |
133 | "Hello Guix!" | |
134 | @end example | |
135 | ||
136 | @item | |
137 | This last example is a function call nested in another function call. When a | |
138 | parenthesized expression is evaluated, the first term is the function and the | |
139 | rest are the arguments passed to the function. Every function returns the | |
140 | last evaluated expression as its return value. | |
141 | ||
142 | @item | |
143 | Anonymous functions are declared with the @code{lambda} term: | |
144 | ||
145 | @example scheme | |
146 | > (lambda (x) (* x x)) | |
147 | #<procedure 120e348 at <unknown port>:24:0 (x)> | |
148 | @end example | |
149 | ||
150 | The above procedure returns the square of its argument. Since everything is | |
151 | an expression, the @code{lambda} expression returns an anonymous procedure, | |
152 | which can in turn be applied to an argument: | |
153 | ||
154 | @example scheme | |
155 | > ((lambda (x) (* x x)) 3) | |
156 | 9 | |
157 | @end example | |
158 | ||
159 | @item | |
160 | Anything can be assigned a global name with @code{define}: | |
161 | ||
162 | @example scheme | |
163 | > (define a 3) | |
164 | > (define square (lambda (x) (* x x))) | |
165 | > (square a) | |
166 | 9 | |
167 | @end example | |
168 | ||
169 | @item | |
170 | Procedures can be defined more concisely with the following syntax: | |
171 | ||
172 | @example scheme | |
173 | (define (square x) (* x x)) | |
174 | @end example | |
175 | ||
176 | @item | |
177 | A list structure can be created with the @code{list} procedure: | |
178 | ||
179 | @example scheme | |
180 | > (list 2 a 5 7) | |
181 | (2 3 5 7) | |
182 | @end example | |
183 | ||
184 | @item | |
185 | The @emph{quote} disables evaluation of a parenthesized expression: the first | |
186 | term is not called over the other terms. Thus it effectively returns a list | |
187 | of terms. | |
188 | ||
189 | @example scheme | |
190 | > '(display (string-append "Hello " "Guix" "\n")) | |
191 | (display (string-append "Hello " "Guix" "\n")) | |
192 | > '(2 a 5 7) | |
193 | (2 a 5 7) | |
194 | @end example | |
195 | ||
196 | @item | |
197 | The @emph{quasiquote} disables evaluation of a parenthesized expression until | |
198 | a comma re-enables it. Thus it provides us with fine-grained control over | |
199 | what is evaluated and what is not. | |
200 | ||
201 | @example scheme | |
202 | > `(2 a 5 7 (2 ,a 5 ,(+ a 4))) | |
203 | (2 a 5 7 (2 3 5 7)) | |
204 | @end example | |
205 | ||
206 | Note that the above result is a list of mixed elements: numbers, symbols (here | |
207 | @code{a}) and the last element is a list itself. | |
208 | ||
209 | @item | |
210 | Multiple variables can be named locally with @code{let}: | |
211 | ||
212 | @example scheme | |
213 | > (define x 10) | |
214 | > (let ((x 2) | |
215 | (y 3)) | |
216 | (list x y)) | |
217 | (2 3) | |
218 | > x | |
219 | 10 | |
220 | > y | |
221 | ERROR: In procedure module-lookup: Unbound variable: y | |
222 | @end example | |
223 | ||
224 | Use @code{let*} to allow later variable declarations to refer to earlier | |
225 | definitions. | |
226 | ||
227 | @example scheme | |
228 | > (let* ((x 2) | |
229 | (y (* x 3))) | |
230 | (list x y)) | |
231 | (2 6) | |
232 | @end example | |
233 | ||
234 | @item | |
235 | The keyword syntax is @code{#:}; it is used to create unique identifiers. | |
236 | @pxref{Keywords,,, guile, GNU Guile Reference Manual}. | |
237 | ||
238 | @item | |
239 | The percentage @code{%} is typically used for read-only global variables in | |
240 | the build stage. Note that it is merely a convention, like @code{_} in C. | |
241 | Scheme treats @code{%} exactly the same as any other letter. | |
242 | ||
243 | @item | |
244 | Modules are created with @code{define-module}. For instance | |
245 | ||
246 | @example scheme | |
247 | (define-module (guix build-system ruby) | |
248 | #:use-module (guix store) | |
249 | #:export (ruby-build | |
250 | ruby-build-system)) | |
251 | @end example | |
252 | ||
253 | defines the module @code{guix build-system ruby} which must be located in | |
254 | @file{guix/build-system/ruby.scm} somewhere in the Guile load path. It | |
255 | depends on the @code{(guix store)} module and it exports two variables, | |
256 | @code{ruby-build} and @code{ruby-build-system}. | |
257 | @end itemize | |
258 | ||
259 | For a more detailed introduction, check out | |
260 | @uref{http://www.troubleshooters.com/codecorn/scheme_guile/hello.htm, Scheme | |
261 | at a Glance}, by Steve Litt. | |
262 | ||
263 | One of the reference Scheme books is the seminal ``Structure and | |
264 | Interpretation of Computer Programs'', by Harold Abelson and Gerald Jay | |
265 | Sussman, with Julie Sussman. You'll find a | |
266 | @uref{https://mitpress.mit.edu/sites/default/files/sicp/index.html, free copy | |
267 | online}, together with | |
268 | @uref{https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/, | |
269 | videos of the lectures by the authors}. The book is available in Texinfo | |
270 | format as the @code{sicp} Guix package. Go ahead, run @code{guix install | |
271 | sicp} and start reading with @code{info sicp} (or with the Emacs Info reader). | |
272 | An @uref{https://sarabander.github.io/sicp/, unofficial ebook is also | |
273 | available}. | |
274 | ||
275 | You'll find more books, tutorials and other resources at | |
276 | @url{https://schemers.org/}. | |
277 | ||
278 | ||
279 | @c ********************************************************************* | |
280 | @node Packaging | |
281 | @chapter Packaging | |
282 | ||
283 | @cindex packaging | |
284 | ||
285 | This chapter is dedicated to teaching you how to add packages to the | |
286 | collection of packages that come with GNU Guix. This involves writing package | |
287 | definitions in Guile Scheme, organizing them in package modules, and building | |
288 | them. | |
289 | ||
290 | @menu | |
291 | * Packaging Tutorial:: A tutorial on how to add packages to Guix. | |
292 | @end menu | |
293 | ||
294 | @node Packaging Tutorial | |
295 | @section Packaging Tutorial | |
296 | ||
297 | GNU Guix stands out as the @emph{hackable} package manager, mostly because it | |
298 | uses @uref{https://www.gnu.org/software/guile/, GNU Guile}, a powerful | |
299 | high-level programming language, one of the | |
300 | @uref{https://en.wikipedia.org/wiki/Scheme_%28programming_language%29, Scheme} | |
301 | dialects from the | |
302 | @uref{https://en.wikipedia.org/wiki/Lisp_%28programming_language%29, Lisp family}. | |
303 | ||
304 | Package definitions are also written in Scheme, which empowers Guix in some | |
305 | very unique ways, unlike most other package managers that use shell scripts or | |
306 | simple languages. | |
307 | ||
308 | @itemize | |
309 | @item | |
310 | Use functions, structures, macros and all of Scheme expressiveness for your | |
311 | package definitions. | |
312 | ||
313 | @item | |
314 | Inheritance makes it easy to customize a package by inheriting from it and | |
315 | modifying only what is needed. | |
316 | ||
317 | @item | |
318 | Batch processing: the whole package collection can be parsed, filtered and | |
319 | processed. Building a headless server with all graphical interfaces stripped | |
320 | out? It's possible. Want to rebuild everything from source using specific | |
321 | compiler optimization flags? Pass the @code{#:make-flags "..."} argument to | |
322 | the list of packages. It wouldn't be a stretch to think | |
323 | @uref{https://wiki.gentoo.org/wiki/USE_flag, Gentoo USE flags} here, but this | |
324 | goes even further: the changes don't have to be thought out beforehand by the | |
325 | packager, they can be @emph{programmed} by the user! | |
326 | @end itemize | |
327 | ||
328 | The following tutorial covers all the basics around package creation with Guix. | |
329 | It does not assume much knowledge of the Guix system nor of the Lisp language. | |
330 | The reader is only expected to be familiar with the command line and to have some | |
331 | basic programming knowledge. | |
332 | ||
333 | @subsection A "Hello World" package | |
334 | ||
335 | The “Defining Packages” section of the manual introduces the basics of Guix | |
336 | packaging (@pxref{Defining Packages,,, guix, GNU Guix Reference Manual}). In | |
337 | the following section, we will partly go over those basics again. | |
338 | ||
339 | ``GNU hello'' is a dummy project that serves as an idiomatic example for | |
340 | packaging. It uses the GNU build system (@code{./configure && make && make | |
341 | install}). Guix already provides a package definition which is a perfect | |
342 | example to start with. You can look up its declaration with @code{guix edit | |
343 | hello} from the command line. Let's see how it looks: | |
344 | ||
345 | @example scheme | |
346 | (define-public hello | |
347 | (package | |
348 | (name "hello") | |
349 | (version "2.10") | |
350 | (source (origin | |
351 | (method url-fetch) | |
352 | (uri (string-append "mirror://gnu/hello/hello-" version | |
353 | ".tar.gz")) | |
354 | (sha256 | |
355 | (base32 | |
356 | "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) | |
357 | (build-system gnu-build-system) | |
358 | (synopsis "Hello, GNU world: An example GNU package") | |
359 | (description | |
360 | "GNU Hello prints the message \"Hello, world!\" and then exits. It | |
361 | serves as an example of standard GNU coding practices. As such, it supports | |
362 | command-line arguments, multiple languages, and so on.") | |
363 | (home-page "https://www.gnu.org/software/hello/") | |
364 | (license gpl3+))) | |
365 | @end example | |
366 | ||
367 | As you can see, most of it is rather straightforward. But let's review the | |
368 | fields together: | |
369 | ||
370 | @table @samp | |
371 | @item name | |
372 | The project name. Using Scheme conventions, we prefer to keep it | |
373 | lower case, without underscore and using dash-separated words. | |
374 | ||
375 | @item source | |
376 | This field contains a description of the source code origin. The | |
377 | @code{origin} record contains these fields: | |
378 | ||
379 | @enumerate | |
380 | @item The method, here @code{url-fetch} to download via HTTP/FTP, but other methods | |
381 | exist, such as @code{git-fetch} for Git repositories. | |
382 | @item The URI, which is typically some @code{https://} location for @code{url-fetch}. Here | |
383 | the special `mirror://gnu` refers to a set of well known locations, all of | |
384 | which can be used by Guix to fetch the source, should some of them fail. | |
385 | @item The @code{sha256} checksum of the requested file. This is essential to ensure | |
386 | the source is not corrupted. Note that Guix works with base32 strings, | |
387 | hence the call to the @code{base32} function. | |
388 | @end enumerate | |
389 | ||
390 | @item build-system | |
391 | ||
392 | This is where the power of abstraction provided by the Scheme language really | |
393 | shines: in this case, the @code{gnu-build-system} abstracts away the famous | |
394 | @code{./configure && make && make install} shell invocations. Other build | |
395 | systems include the @code{trivial-build-system} which does not do anything and | |
396 | requires from the packager to program all the build steps, the | |
397 | @code{python-build-system}, the @code{emacs-build-system}, and many more | |
398 | (@pxref{Build Systems,,, guix, GNU Guix Reference Manual}). | |
399 | ||
400 | @item synopsis | |
401 | It should be a concise summary of what the package does. For many packages a | |
402 | tagline from the project's home page can be used as the synopsis. | |
403 | ||
404 | @item description | |
405 | Same as for the synopsis, it's fine to re-use the project description from the | |
406 | homepage. Note that Guix uses Texinfo syntax. | |
407 | ||
408 | @item home-page | |
409 | Use HTTPS if available. | |
410 | ||
411 | @item license | |
412 | See @code{guix/licenses.scm} in the project source for a full list of | |
413 | available licenses. | |
414 | @end table | |
415 | ||
416 | Time to build our first package! Nothing fancy here for now: we will stick to a | |
417 | dummy "my-hello", a copy of the above declaration. | |
418 | ||
419 | As with the ritualistic "Hello World" taught with most programming languages, | |
420 | this will possibly be the most "manual" approach. We will work out an ideal | |
421 | setup later; for now we will go the simplest route. | |
422 | ||
423 | Save the following to a file @file{my-hello.scm}. | |
424 | ||
425 | @example scheme | |
426 | (use-modules (guix packages) | |
427 | (guix download) | |
428 | (guix build-system gnu) | |
429 | (guix licenses)) | |
430 | ||
431 | (package | |
432 | (name "my-hello") | |
433 | (version "2.10") | |
434 | (source (origin | |
435 | (method url-fetch) | |
436 | (uri (string-append "mirror://gnu/hello/hello-" version | |
437 | ".tar.gz")) | |
438 | (sha256 | |
439 | (base32 | |
440 | "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) | |
441 | (build-system gnu-build-system) | |
442 | (synopsis "Hello, Guix world: An example custom Guix package") | |
443 | (description | |
444 | "GNU Hello prints the message \"Hello, world!\" and then exits. It | |
445 | serves as an example of standard GNU coding practices. As such, it supports | |
446 | command-line arguments, multiple languages, and so on.") | |
447 | (home-page "https://www.gnu.org/software/hello/") | |
448 | (license gpl3+)) | |
449 | @end example | |
450 | ||
451 | We will explain the extra code in a moment. | |
452 | ||
453 | Feel free to play with the different values of the various fields. If you | |
454 | change the source, you'll need to update the checksum. Indeed, Guix refuses to | |
455 | build anything if the given checksum does not match the computed checksum of the | |
456 | source code. To obtain the correct checksum of the package declaration, we | |
457 | need to download the source, compute the sha256 checksum and convert it to | |
458 | base32. | |
459 | ||
460 | Thankfully, Guix can automate this task for us; all we need is to provide the | |
461 | URI: | |
462 | ||
463 | @c TRANSLATORS: This is example shell output. | |
464 | @example sh | |
465 | $ guix download mirror://gnu/hello/hello-2.10.tar.gz | |
466 | ||
467 | Starting download of /tmp/guix-file.JLYgL7 | |
468 | From https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz... | |
469 | following redirection to `https://mirror.ibcp.fr/pub/gnu/hello/hello-2.10.tar.gz'... | |
470 | …10.tar.gz 709KiB 2.5MiB/s 00:00 [##################] 100.0% | |
471 | /gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz | |
472 | 0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i | |
473 | @end example | |
474 | ||
475 | In this specific case the output tells us which mirror was chosen. | |
476 | If the result of the above command is not the same as in the above snippet, | |
477 | update your @code{my-hello} declaration accordingly. | |
478 | ||
479 | Note that GNU package tarballs come with an OpenPGP signature, so you | |
480 | should definitely check the signature of this tarball with `gpg` to | |
481 | authenticate it before going further: | |
482 | ||
483 | @c TRANSLATORS: This is example shell output. | |
484 | @example sh | |
485 | $ guix download mirror://gnu/hello/hello-2.10.tar.gz.sig | |
486 | ||
487 | Starting download of /tmp/guix-file.03tFfb | |
488 | From https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz.sig... | |
489 | following redirection to `https://ftp.igh.cnrs.fr/pub/gnu/hello/hello-2.10.tar.gz.sig'... | |
490 | ….tar.gz.sig 819B 1.2MiB/s 00:00 [##################] 100.0% | |
491 | /gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig | |
492 | 0q0v86n3y38z17rl146gdakw9xc4mcscpk8dscs412j22glrv9jf | |
493 | $ gpg --verify /gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig /gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz | |
494 | gpg: Signature made Sun 16 Nov 2014 01:08:37 PM CET | |
495 | gpg: using RSA key A9553245FDE9B739 | |
496 | gpg: Good signature from "Sami Kerola <kerolasa@@iki.fi>" [unknown] | |
497 | gpg: aka "Sami Kerola (http://www.iki.fi/kerolasa/) <kerolasa@@iki.fi>" [unknown] | |
498 | gpg: WARNING: This key is not certified with a trusted signature! | |
499 | gpg: There is no indication that the signature belongs to the owner. | |
500 | Primary key fingerprint: 8ED3 96E3 7E38 D471 A005 30D3 A955 3245 FDE9 B739 | |
501 | @end example | |
502 | ||
503 | You can then happily run | |
504 | ||
505 | @c TRANSLATORS: Do not translate this command | |
506 | @example sh | |
507 | $ guix package --install-from-file=my-hello.scm | |
508 | @end example | |
509 | ||
510 | You should now have @code{my-hello} in your profile! | |
511 | ||
512 | @c TRANSLATORS: Do not translate this command | |
513 | @example sh | |
514 | $ guix package --list-installed=my-hello | |
515 | my-hello 2.10 out | |
516 | /gnu/store/f1db2mfm8syb8qvc357c53slbvf1g9m9-my-hello-2.10 | |
517 | @end example | |
518 | ||
519 | We've gone as far as we could without any knowledge of Scheme. Before moving | |
520 | on to more complex packages, now is the right time to brush up on your Scheme | |
521 | knowledge. @pxref{A Scheme Crash Course} to get up to speed. | |
522 | ||
523 | @c TODO: Continue the tutorial | |
524 | ||
525 | ||
526 | @c ********************************************************************* | |
527 | @node System Configuration | |
528 | @chapter System Configuration | |
529 | ||
530 | Guix offers a flexible language for declaratively configuring your Guix | |
531 | System. This flexibility can at times be overwhelming. The purpose of this | |
532 | chapter is to demonstrate some advanced configuration concepts. | |
533 | ||
534 | @pxref{System Configuration,,, guix, GNU Guix Reference Manual} for a complete | |
535 | reference. | |
536 | ||
537 | @menu | |
538 | * Customizing the Kernel:: Creating and using a custom Linux kernel on Guix System. | |
539 | @end menu | |
540 | ||
541 | @node Customizing the Kernel | |
542 | @section Customizing the Kernel | |
543 | ||
544 | Guix is, at its core, a source based distribution with substitutes | |
545 | (@pxref{Substitutes,,, guix, GNU Guix Reference Manual}), and as such building | |
546 | packages from their source code is an expected part of regular package | |
547 | installations and upgrades. Given this starting point, it makes sense that | |
548 | efforts are made to reduce the amount of time spent compiling packages, and | |
549 | recent changes and upgrades to the building and distribution of substitutes | |
550 | continues to be a topic of discussion within Guix. | |
551 | ||
552 | The kernel, while not requiring an overabundance of RAM to build, does take a | |
553 | rather long time on an average machine. The official kernel configuration, as | |
554 | is the case with many GNU/Linux distributions, errs on the side of | |
555 | inclusiveness, and this is really what causes the build to take such a long | |
556 | time when the kernel is built from source. | |
557 | ||
558 | The Linux kernel, however, can also just be described as a regular old | |
559 | package, and as such can be customized just like any other package. The | |
560 | procedure is a little bit different, although this is primarily due to the | |
561 | nature of how the package definition is written. | |
562 | ||
563 | The @code{linux-libre} kernel package definition is actually a procedure which | |
564 | creates a package. | |
565 | ||
566 | @example scheme | |
567 | (define* (make-linux-libre version hash supported-systems | |
568 | #:key | |
569 | ;; A function that takes an arch and a variant. | |
570 | ;; See kernel-config for an example. | |
571 | (extra-version #f) | |
572 | (configuration-file #f) | |
573 | (defconfig "defconfig") | |
574 | (extra-options %default-extra-linux-options) | |
575 | (patches (list %boot-logo-patch))) | |
576 | ...) | |
577 | @end example | |
578 | ||
579 | The current @code{linux-libre} package is for the 5.1.x series, and is | |
580 | declared like this: | |
581 | ||
582 | @example scheme | |
583 | (define-public linux-libre | |
584 | (make-linux-libre %linux-libre-version | |
585 | %linux-libre-hash | |
586 | '("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux") | |
587 | #:patches %linux-libre-5.1-patches | |
588 | #:configuration-file kernel-config)) | |
589 | @end example | |
590 | ||
591 | Any keys which are not assigned values inherit their default value from the | |
592 | @code{make-linux-libre} definition. When comparing the two snippets above, | |
593 | you may notice that the code comment in the first doesn't actually refer to | |
594 | the @code{#:extra-version} keyword; it is actually for | |
595 | @code{#:configuration-file}. Because of this, it is not actually easy to | |
596 | include a custom kernel configuration from the definition, but don't worry, | |
597 | there are other ways to work with what we do have. | |
598 | ||
599 | There are two ways to create a kernel with a custom kernel configuration. The | |
600 | first is to provide a standard @file{.config} file during the build process by | |
601 | including an actual @file{.config} file as a native input to our custom | |
602 | kernel. The following is a snippet from the custom @code{'configure} phase of | |
603 | the @code{make-linux-libre} package definition: | |
604 | ||
605 | @example scheme | |
606 | (let ((build (assoc-ref %standard-phases 'build)) | |
607 | (config (assoc-ref (or native-inputs inputs) "kconfig"))) | |
608 | ||
609 | ;; Use a custom kernel configuration file or a default | |
610 | ;; configuration file. | |
611 | (if config | |
612 | (begin | |
613 | (copy-file config ".config") | |
614 | (chmod ".config" #o666)) | |
615 | (invoke "make" ,defconfig)) | |
616 | @end example | |
617 | ||
618 | Below is a sample kernel package. The @code{linux-libre} package is nothing | |
619 | special and can be inherited from and have its fields overridden like any | |
620 | other package: | |
621 | ||
622 | @example scheme | |
623 | (define-public linux-libre/E2140 | |
624 | (package | |
625 | (inherit linux-libre) | |
626 | (native-inputs | |
627 | `(("kconfig" ,(local-file "E2140.config")) | |
628 | ,@@(alist-delete "kconfig" | |
629 | (package-native-inputs linux-libre)))))) | |
630 | @end example | |
631 | ||
632 | In the same directory as the file defining @code{linux-libre-E2140} is a file | |
633 | named @file{E2140.config}, which is an actual kernel configuration file. The | |
634 | @code{defconfig} keyword of @code{make-linux-libre} is left blank here, so the | |
635 | only kernel configuration in the package is the one which was included in the | |
636 | @code{native-inputs} field. | |
637 | ||
638 | The second way to create a custom kernel is to pass a new value to the | |
639 | @code{extra-options} keyword of the @code{make-linux-libre} procedure. The | |
640 | @code{extra-options} keyword works with another function defined right below | |
641 | it: | |
642 | ||
643 | @example scheme | |
644 | (define %default-extra-linux-options | |
645 | `(;; https://lists.gnu.org/archive/html/guix-devel/2014-04/msg00039.html | |
646 | ("CONFIG_DEVPTS_MULTIPLE_INSTANCES" . #t) | |
647 | ;; Modules required for initrd: | |
648 | ("CONFIG_NET_9P" . m) | |
649 | ("CONFIG_NET_9P_VIRTIO" . m) | |
650 | ("CONFIG_VIRTIO_BLK" . m) | |
651 | ("CONFIG_VIRTIO_NET" . m) | |
652 | ("CONFIG_VIRTIO_PCI" . m) | |
653 | ("CONFIG_VIRTIO_BALLOON" . m) | |
654 | ("CONFIG_VIRTIO_MMIO" . m) | |
655 | ("CONFIG_FUSE_FS" . m) | |
656 | ("CONFIG_CIFS" . m) | |
657 | ("CONFIG_9P_FS" . m))) | |
658 | ||
659 | (define (config->string options) | |
660 | (string-join (map (match-lambda | |
661 | ((option . 'm) | |
662 | (string-append option "=m")) | |
663 | ((option . #t) | |
664 | (string-append option "=y")) | |
665 | ((option . #f) | |
666 | (string-append option "=n"))) | |
667 | options) | |
668 | "\n")) | |
669 | @end example | |
670 | ||
671 | And in the custom configure script from the `make-linux-libre` package: | |
672 | ||
673 | @example scheme | |
674 | ;; Appending works even when the option wasn't in the | |
675 | ;; file. The last one prevails if duplicated. | |
676 | (let ((port (open-file ".config" "a")) | |
677 | (extra-configuration ,(config->string extra-options))) | |
678 | (display extra-configuration port) | |
679 | (close-port port)) | |
680 | ||
681 | (invoke "make" "oldconfig")))) | |
682 | @end example | |
683 | ||
684 | So by not providing a configuration-file the @file{.config} starts blank, and | |
685 | then we write into it the collection of flags that we want. Here's another | |
686 | custom kernel: | |
687 | ||
688 | @example scheme | |
689 | (define %macbook41-full-config | |
690 | (append %macbook41-config-options | |
691 | %filesystems | |
692 | %efi-support | |
693 | %emulation | |
694 | (@@@@ (gnu packages linux) %default-extra-linux-options))) | |
695 | ||
696 | (define-public linux-libre-macbook41 | |
697 | ;; XXX: Access the internal 'make-linux-libre' procedure, which is | |
698 | ;; private and unexported, and is liable to change in the future. | |
699 | ((@@@@ (gnu packages linux) make-linux-libre) (@@@@ (gnu packages linux) %linux-libre-version) | |
700 | (@@@@ (gnu packages linux) %linux-libre-hash) | |
701 | '("x86_64-linux") | |
702 | #:extra-version "macbook41" | |
703 | #:patches (@@@@ (gnu packages linux) %linux-libre-5.1-patches) | |
704 | #:extra-options %macbook41-config-options)) | |
705 | @end example | |
706 | ||
707 | In the above example @code{%filesystems} is a collection of flags enabling | |
708 | different filesystem support, @code{%efi-support} enables EFI support and | |
709 | @code{%emulation} enables a x86_64-linux machine to act in 32-bit mode also. | |
710 | @code{%default-extra-linux-options} are the ones quoted above, which had to be | |
711 | added in since they were replaced in the @code{extra-options} keyword. | |
712 | ||
713 | This all sounds like it should be doable, but how does one even know which | |
714 | modules are required for a particular system? Two places that can be helpful | |
715 | in trying to answer this question is the | |
716 | @uref{https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel, Gentoo | |
717 | Handbook} and the | |
718 | @uref{https://www.kernel.org/doc/html/latest/admin-guide/README.html?highlight=localmodconfig, | |
719 | documentation from the kernel itself}. From the kernel documentation, it | |
720 | seems that @code{make localmodconfig} is the command we want. | |
721 | ||
722 | In order to actually run @code{make localmodconfig} we first need to get and | |
723 | unpack the kernel source code: | |
724 | ||
725 | @example shell | |
726 | tar xf $(guix build linux-libre --source) | |
727 | @end example | |
728 | ||
729 | Once inside the directory containing the source code run @code{touch .config} | |
730 | to create an initial, empty @file{.config} to start with. @code{make | |
731 | localmodconfig} works by seeing what you already have in @file{.config} and | |
732 | letting you know what you're missing. If the file is blank then you're | |
733 | missing everything. The next step is to run: | |
734 | ||
735 | @example shell | |
736 | guix environment linux-libre -- make localmodconfig | |
737 | @end example | |
738 | ||
739 | and note the output. Do note that the @file{.config} file is still empty. | |
740 | The output generally contains two types of warnings. The first start with | |
741 | "WARNING" and can actually be ignored in our case. The second read: | |
742 | ||
743 | @example shell | |
744 | module pcspkr did not have configs CONFIG_INPUT_PCSPKR | |
745 | @end example | |
746 | ||
747 | For each of these lines, copy the @code{CONFIG_XXXX_XXXX} portion into the | |
748 | @file{.config} in the directory, and append @code{=m}, so in the end it looks | |
749 | like this: | |
750 | ||
751 | @example shell | |
752 | CONFIG_INPUT_PCSPKR=m | |
753 | CONFIG_VIRTIO=m | |
754 | @end example | |
755 | ||
756 | After copying all the configuration options, run @code{make localmodconfig} | |
757 | again to make sure that you don't have any output starting with "module". | |
758 | After all of these machine specific modules there are a couple more left that | |
759 | are also needed. @code{CONFIG_MODULES} is necessary so that you can build and | |
760 | load modules separately and not have everything built into the kernel. | |
761 | @code{CONFIG_BLK_DEV_SD} is required for reading from hard drives. It is | |
762 | possible that there are other modules which you will need. | |
763 | ||
764 | This post does not aim to be a guide to configuring your own kernel however, | |
765 | so if you do decide to build a custom kernel you'll have to seek out other | |
766 | guides to create a kernel which is just right for your needs. | |
767 | ||
768 | The second way to setup the kernel configuration makes more use of Guix's | |
769 | features and allows you to share configuration segments between different | |
770 | kernels. For example, all machines using EFI to boot have a number of EFI | |
771 | configuration flags that they need. It is likely that all the kernels will | |
772 | share a list of filesystems to support. By using variables it is easier to | |
773 | see at a glance what features are enabled and to make sure you don't have | |
774 | features in one kernel but missing in another. | |
775 | ||
776 | Left undiscussed however, is Guix's initrd and its customization. It is | |
777 | likely that you'll need to modify the initrd on a machine using a custom | |
778 | kernel, since certain modules which are expected to be built may not be | |
779 | available for inclusion into the initrd. | |
780 | ||
781 | @c ********************************************************************* | |
782 | @node Acknowledgments | |
783 | @chapter Acknowledgments | |
784 | ||
785 | Guix is based on the @uref{https://nixos.org/nix/, Nix package manager}, | |
786 | which was designed and | |
787 | implemented by Eelco Dolstra, with contributions from other people (see | |
788 | the @file{nix/AUTHORS} file in Guix.) Nix pioneered functional package | |
789 | management, and promoted unprecedented features, such as transactional | |
790 | package upgrades and rollbacks, per-user profiles, and referentially | |
791 | transparent build processes. Without this work, Guix would not exist. | |
792 | ||
793 | The Nix-based software distributions, Nixpkgs and NixOS, have also been | |
794 | an inspiration for Guix. | |
795 | ||
796 | GNU@tie{}Guix itself is a collective work with contributions from a | |
797 | number of people. See the @file{AUTHORS} file in Guix for more | |
798 | information on these fine people. The @file{THANKS} file lists people | |
799 | who have helped by reporting bugs, taking care of the infrastructure, | |
800 | providing artwork and themes, making suggestions, and more---thank you! | |
801 | ||
802 | This document includes adapted sections from articles that have previously | |
803 | been published on the Guix blog at @uref{https://guix.gnu.org/blog}. | |
804 | ||
805 | ||
806 | @c ********************************************************************* | |
807 | @node GNU Free Documentation License | |
808 | @appendix GNU Free Documentation License | |
809 | @cindex license, GNU Free Documentation License | |
810 | @include fdl-1.3.texi | |
811 | ||
812 | @c ********************************************************************* | |
813 | @node Concept Index | |
814 | @unnumbered Concept Index | |
815 | @printindex cp | |
816 | ||
817 | @bye | |
818 | ||
819 | @c Local Variables: | |
820 | @c ispell-local-dictionary: "american"; | |
821 | @c End: |