diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/build.scm | 59 | ||||
-rw-r--r-- | doc/guix-cookbook.texi | 821 | ||||
-rw-r--r-- | doc/guix.texi | 364 | ||||
-rw-r--r-- | doc/local.mk | 9 |
4 files changed, 1190 insertions, 63 deletions
diff --git a/doc/build.scm b/doc/build.scm index 5bc95d2517..b6a921c421 100644 --- a/doc/build.scm +++ b/doc/build.scm @@ -215,6 +215,58 @@ its <pre class=\"lisp\"> blocks (as produced by 'makeinfo --html')." (ice-9 match) (ice-9 threads)) + (define (pair-open/close lst) + ;; Pair 'open' and 'close' tags produced by 'highlights' and + ;; produce nested 'paren' tags instead. + (let loop ((lst lst) + (level 0) + (result '())) + (match lst + ((('open open) rest ...) + (call-with-values + (lambda () + (loop rest (+ 1 level) '())) + (lambda (inner close rest) + (loop rest level + (cons `(paren ,level ,open ,inner ,close) + result))))) + ((('close str) rest ...) + (if (> level 0) + (values (reverse result) str rest) + (begin + (format (current-error-port) + "warning: extra closing paren; context:~% ~y~%" + (reverse result)) + (loop rest 0 (cons `(close ,str) result))))) + ((item rest ...) + (loop rest level (cons item result))) + (() + (when (> level 0) + (format (current-error-port) + "warning: missing ~a closing parens; context:~% ~y%" + level (reverse result))) + (values (reverse result) "" '()))))) + + (define (highlights->sxml* highlights) + ;; Like 'highlights->sxml', but handle nested 'paren tags. This + ;; allows for paren matching highlights via appropriate CSS + ;; "hover" properties. + (define (tag->class tag) + (string-append "syntax-" (symbol->string tag))) + + (map (match-lambda + ((? string? str) str) + (('paren level open (body ...) close) + `(span (@ (class ,(string-append "syntax-paren" + (number->string level)))) + ,open + (span (@ (class "syntax-symbol")) + ,@(highlights->sxml* body)) + ,close)) + ((tag text) + `(span (@ (class ,(tag->class tag))) ,text))) + highlights)) + (define entity->string (match-lambda ("rArr" "⇒") @@ -252,9 +304,10 @@ its <pre class=\"lisp\"> blocks (as produced by 'makeinfo --html')." (href #$syntax-css-url))))) (('pre ('@ ('class "lisp")) code-snippet ...) `(pre (@ (class "lisp")) - ,(highlights->sxml - (highlight lex-scheme - (concatenate-snippets code-snippet))))) + ,@(highlights->sxml* + (pair-open/close + (highlight lex-scheme + (concatenate-snippets code-snippet)))))) ((tag ('@ attributes ...) body ...) `(,tag (@ ,@attributes) ,@(map syntax-highlight body))) ((tag body ...) diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi new file mode 100644 index 0000000000..66f94a0fe7 --- /dev/null +++ b/doc/guix-cookbook.texi @@ -0,0 +1,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: diff --git a/doc/guix.texi b/doc/guix.texi index aff9aed06b..97d797c13f 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -513,6 +513,7 @@ ready to use it. * Setting Up the Daemon:: Preparing the build daemon's environment. * Invoking guix-daemon:: Running the build daemon. * Application Setup:: Application-specific setup. +* Upgrading Guix:: Upgrading Guix and its build daemon. @end menu @node Binary Installation @@ -794,22 +795,6 @@ GNU Coding Standards}). The @command{configure} script protects against unintended misconfiguration of @var{localstatedir} so you do not inadvertently corrupt your store (@pxref{The Store}). -@cindex Nix, compatibility -When a working installation of @url{https://nixos.org/nix/, the Nix package -manager} is available, you -can instead configure Guix with @code{--disable-daemon}. In that case, -Nix replaces the three dependencies above. - -Guix is compatible with Nix, so it is possible to share the same store -between both. To do so, you must pass @command{configure} not only the -same @code{--with-store-dir} value, but also the same -@code{--localstatedir} value. The latter is essential because it -specifies where the database that stores metadata about the store is -located, among other things. The default values for Nix are -@code{--with-store-dir=/nix/store} and @code{--localstatedir=/nix/var}. -Note that @code{--disable-daemon} is not required if -your goal is to share the store with Nix. - @node Running the Test Suite @section Running the Test Suite @@ -1777,6 +1762,40 @@ invoke the actual linker with this new set of arguments. You can instruct the wrapper to refuse to link against libraries not in the store by setting the @code{GUIX_LD_WRAPPER_ALLOW_IMPURITIES} environment variable to @code{no}. +@node Upgrading Guix +@section Upgrading Guix + +@cindex Upgrading Guix, on a foreign distro + +To upgrade Guix, run: + +@example +guix pull +@end example + +@xref{Invoking guix pull}, for more information. + +@cindex upgrading Guix for the root user, on a foreign distro +@cindex upgrading the Guix daemon, on a foreign distro +@cindex @command{guix pull} for the root user, on a foreign distro + +On a foreign distro, you can upgrade the build daemon by running: + +@example +sudo -i guix pull +@end example + +@noindent +followed by (assuming your distro uses the systemd service management +tool): + +@example +systemctl restart guix-daemon.service +@end example + +On Guix System, upgrading the daemon is achieved by reconfiguring the +system (@pxref{Invoking guix system, @code{guix system reconfigure}}). + @c TODO What else? @c ********************************************************************* @@ -2431,7 +2450,7 @@ Create a disk image that will hold the installed system. To make a qcow2-formatted disk image, use the @command{qemu-img} command: @example -qemu-img create -f qcow2 guixsd.img 50G +qemu-img create -f qcow2 guix-system.img 50G @end example The resulting file will be much smaller than 50 GB (typically less than @@ -2442,17 +2461,13 @@ Boot the USB installation image in an VM: @example qemu-system-x86_64 -m 1024 -smp 1 -enable-kvm \ - -net user -net nic,model=virtio -boot menu=on \ - -drive file=guix-system-install-@value{VERSION}.@var{system}.iso \ - -drive file=guixsd.img + -net user -net nic,model=virtio -boot menu=on,order=d \ + -drive file=guix-system.img \ + -drive media=cdrom,file=guix-system-install-@value{VERSION}.@var{system}.iso @end example -The ordering of the drives matters. @code{-enable-kvm} is optional, but -significantly improves performance, @pxref{Running Guix in a VM}. - -In the VM console, quickly press the @kbd{F12} key to enter the boot -menu. Then press the @kbd{2} key and the @kbd{RET} key to validate your -selection. +@code{-enable-kvm} is optional, but significantly improves performance, +@pxref{Running Guix in a VM}. @item You're now root in the VM, proceed with the installation process. @@ -2460,7 +2475,7 @@ You're now root in the VM, proceed with the installation process. @end enumerate Once installation is complete, you can boot the system that's on your -@file{guixsd.img} image. @xref{Running Guix in a VM}, for how to do +@file{guix-system.img} image. @xref{Running Guix in a VM}, for how to do that. @node Building the Installation Image @@ -2657,7 +2672,9 @@ For your convenience, we also provide the following aliases: @item @command{guix remove} is an alias for @command{guix package -r}, @item -and @command{guix upgrade} is an alias for @command{guix package -u}. +@command{guix upgrade} is an alias for @command{guix package -u}, +@item +and @command{guix show} is an alias for @command{guix package --show=}. @end itemize These aliases are less expressive than @command{guix package} and provide @@ -2757,7 +2774,7 @@ As an example, @var{file} might contain a definition like this (@pxref{Defining Packages}): @lisp -@verbatiminclude package-hello.scm +@include package-hello.scm @end lisp Developers may find it useful to include such a @file{guix.scm} file @@ -2916,6 +2933,38 @@ variable, even though, taken individually, neither @file{foo} nor @itemx -p @var{profile} Use @var{profile} instead of the user's default profile. +@var{profile} must be the name of a file that will be created upon +completion. Concretely, @var{profile} will be a mere symbolic link +(``symlink'') pointing to the actual profile where packages are +installed: + +@example +$ guix install hello -p ~/code/my-profile +@dots{} +$ ~/code/my-profile/bin/hello +Hello, world! +@end example + +All it takes to get rid of the profile is to remove this symlink and its +siblings that point to specific generations: + +@example +$ rm ~/code/my-profile ~/code/my-profile-*-link +@end example + +@item --list-profiles +List all the user's profiles: + +@example +$ guix package --list-profiles +/home/charlie/.guix-profile +/home/charlie/code/my-profile +/home/charlie/code/devel-profile +/home/charlie/tmp/test +@end example + +When running as root, list all the profiles of all the users. + @cindex collisions, in a profile @cindex colliding packages in profiles @cindex profile collisions @@ -3020,9 +3069,9 @@ version: 3.3.5 @end example You may also specify the full name of a package to only get details about a -specific version of it: +specific version of it (this time using the @command{guix show} alias): @example -$ guix package --show=python@@3.4 | recsel -p name,version +$ guix show python@@3.4 | recsel -p name,version name: python version: 3.4.3 @end example @@ -3673,12 +3722,21 @@ Generation 3 Jun 13 2018 23:31:07 (current) @xref{Invoking guix describe, @command{guix describe}}, for other ways to describe the current status of Guix. -This @code{~/.config/guix/current} profile works like any other profile -created by @command{guix package} (@pxref{Invoking guix package}). That +This @code{~/.config/guix/current} profile works exactly like the profiles +created by @command{guix package} (@pxref{Invoking guix package}). That is, you can list generations, roll back to the previous generation---i.e., the previous Guix---and so on: @example +$ guix pull --roll-back +switched from generation 3 to 2 +$ guix pull --delete-generations=1 +deleting /var/guix/profiles/per-user/charlie/current-guix-1-link +@end example + +You can also use @command{guix package} (@pxref{Invoking guix package}) +to manage the profile by naming it explicitly: +@example $ guix package -p ~/.config/guix/current --roll-back switched from generation 3 to 2 $ guix package -p ~/.config/guix/current --delete-generations=1 @@ -3709,13 +3767,16 @@ Read the list of channels from @var{file} instead of evaluates to a list of channel objects. @xref{Channels}, for more information. +@cindex channel news @item --news @itemx -N -Display the list of packages added or upgraded since the previous generation. +Display the list of packages added or upgraded since the previous +generation, as well as, occasionally, news written by channel authors +for their users (@pxref{Channels, Writing Channel News}). -This is the same information as displayed upon @command{guix pull} completion, -but without ellipses; it is also similar to the output of @command{guix pull --l} for the last generation (see below). +The package information is the same as displayed upon @command{guix +pull} completion, but without ellipses; it is also similar to the output +of @command{guix pull -l} for the last generation (see below). @item --list-generations[=@var{pattern}] @itemx -l [@var{pattern}] @@ -3724,6 +3785,40 @@ is provided, the subset of generations that match @var{pattern}. The syntax of @var{pattern} is the same as with @code{guix package --list-generations} (@pxref{Invoking guix package}). +@item --roll-back +@cindex rolling back +@cindex undoing transactions +@cindex transactions, undoing +Roll back to the previous @dfn{generation} of @file{~/.config/guix/current}---i.e., +undo the last transaction. + +@item --switch-generation=@var{pattern} +@itemx -S @var{pattern} +@cindex generations +Switch to a particular generation defined by @var{pattern}. + +@var{pattern} may be either a generation number or a number prefixed +with ``+'' or ``-''. The latter means: move forward/backward by a +specified number of generations. For example, if you want to return to +the latest generation after @code{--roll-back}, use +@code{--switch-generation=+1}. + +@item --delete-generations[=@var{pattern}] +@itemx -d [@var{pattern}] +When @var{pattern} is omitted, delete all generations except the current +one. + +This command accepts the same patterns as @option{--list-generations}. +When @var{pattern} is specified, delete the matching generations. When +@var{pattern} specifies a duration, generations @emph{older} than the +specified duration match. For instance, @code{--delete-generations=1m} +deletes generations that are more than one month old. + +If the current generation matches, it is @emph{not} deleted. + +Note that deleting generations prevents rolling back to them. +Consequently, this command must be used with care. + @xref{Invoking guix describe}, for a way to display information about the current generation only. @@ -3946,6 +4041,68 @@ add a meta-data file @file{.guix-channel} that contains: (directory "guix")) @end lisp +@cindex news, for channels +@subsection Writing Channel News + +Channel authors may occasionally want to communicate to their users +information about important changes in the channel. You'd send them all +an email, but that's not convenient. + +Instead, channels can provide a @dfn{news file}; when the channel users +run @command{guix pull}, that news file is automatically read and +@command{guix pull --news} can display the announcements that correspond +to the new commits that have been pulled, if any. + +To do that, channel authors must first declare the name of the news file +in their @file{.guix-channel} file: + +@lisp +(channel + (version 0) + (news-file "etc/news.txt")) +@end lisp + +The news file itself, @file{etc/news.txt} in this example, must look +something like this: + +@lisp +(channel-news + (version 0) + (entry (tag "the-bug-fix") + (title (en "Fixed terrible bug") + (fr "Oh la la")) + (body (en "@@emph@{Good news@}! It's fixed!") + (eo "Certe ĝi pli bone funkcias nun!"))) + (entry (commit "bdcabe815cd28144a2d2b4bc3c5057b051fa9906") + (title (en "Added a great package") + (ca "Què vol dir guix?")) + (body (en "Don't miss the @@code@{hello@} package!")))) +@end lisp + +The file consists of a list of @dfn{news entries}. Each entry is +associated with a commit or tag: it describes changes made in this +commit, possibly in preceding commits as well. Users see entries only +the first time they obtain the commit the entry refers to. + +The @code{title} field should be a one-line summary while @code{body} +can be arbitrarily long, and both can contain Texinfo markup +(@pxref{Overview,,, texinfo, GNU Texinfo}). Both the title and body are +a list of language tag/message tuples, which allows @command{guix pull} +to display news in the language that corresponds to the user's locale. + +If you want to translate news using a gettext-based workflow, you can +extract translatable strings with @command{xgettext} (@pxref{xgettext +Invocation,,, gettext, GNU Gettext Utilities}). For example, assuming +you write news entries in English first, the command below creates a PO +file containing the strings to translate: + +@example +xgettext -o news.po -l scheme -ken etc/news.scm +@end example + +To sum up, yes, you could use your channel as a blog. But beware, this +is @emph{not quite} what your users might expect. + @subsection Replicating Guix @cindex pinning, channels @@ -4835,7 +4992,9 @@ specified binaries and symlinks. @item docker This produces a tarball that follows the @uref{https://github.com/docker/docker/blob/master/image/spec/v1.2.md, -Docker Image Specification}. +Docker Image Specification}. The ``repository name'' as it appears in +the output of the @command{docker images} command is computed from +package names passed on the command line or in the manifest file. @item squashfs This produces a SquashFS image containing all the specified binaries and @@ -6050,7 +6209,7 @@ package, correctly capitalized. For packages requiring shared library dependencies, you may need to write the @file{/deps/deps.jl} file manually. It's usually a line of @code{const -variable = /gnu/store/libary.so} for each dependency, plus a void function +variable = /gnu/store/library.so} for each dependency, plus a void function @code{check_deps() = nothing}. Some older packages that aren't using @file{Package.toml} yet, will require @@ -8104,7 +8263,7 @@ As an example, @var{file} might contain a package definition like this (@pxref{Defining Packages}): @lisp -@verbatiminclude package-hello.scm +@include package-hello.scm @end lisp @item --expression=@var{expr} @@ -8924,6 +9083,16 @@ The crate importer also allows you to specify a version string: guix import crate constant-time-eq@@0.1.0 @end example +Additional options include: + +@table @code +@item --recursive +@itemx -r +Traverse the dependency graph of the given upstream package recursively +and generate package expressions for all those packages that are not yet +in Guix. +@end table + @item opam @cindex OPAM @cindex OCaml @@ -9343,7 +9512,7 @@ that Guix uses, as in this example: ;; @dots{} ;; CPE calls this package "grub2". (properties '((cpe-name . "grub2") - (cpe-version . "2.3"))) + (cpe-version . "2.3")))) @end lisp @c See <https://www.openwall.com/lists/oss-security/2017/03/15/3>. @@ -11657,6 +11826,7 @@ declaration. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. * Game Services:: Game servers. +* Guix Services:: Services relating specifically to Guix. * Miscellaneous Services:: Other services. @end menu @@ -12261,7 +12431,7 @@ The following example showcases how we can use an existing rule file. @lisp (use-modules (guix download) ;for url-fetch (guix packages) ;for origin - ;; @dots{}) + @dots{}) (define %android-udev-rules (file->udev-rule @@ -12295,7 +12465,7 @@ well as in the @var{groups} field of the @var{operating-system} record. @lisp (use-modules (gnu packages android) ;for android-udev-rules (gnu system shadow) ;for user-group - ;; @dots{}) + @dots{}) (operating-system ;; @dots{} @@ -12303,8 +12473,7 @@ well as in the @var{groups} field of the @var{operating-system} record. ;; @dots{} (supplementary-groups '("adbusers" ;for adb - "wheel" "netdev" "audio" "video")) - ;; @dots{}))) + "wheel" "netdev" "audio" "video"))))) (groups (cons (user-group (system? #t) (name "adbusers")) %base-groups)) @@ -13041,6 +13210,33 @@ objects}). @end table @end deftp +@cindex nftables +@defvr {Scheme Variable} nftables-service-type +This is the service type to set up a nftables configuration. nftables is a +netfilter project that aims to replace the existing iptables, ip6tables, +arptables and ebtables framework. It provides a new packet filtering +framework, a new user-space utility @command{nft}, and a compatibility layer +for iptables. This service comes with a default ruleset +@code{%default-nftables-ruleset} that rejecting all incomming connections +except those to the ssh port 22. To use it, simply write: + +@lisp +(service nftables-service-type) +@end lisp +@end defvr + +@deftp {Data Type} nftables-configuration +The data type representing the configuration of nftables. + +@table @asis +@item @code{package} (default: @code{nftables}) +The nftables package that provides @command{nft}. +@item @code{ruleset} (default: @code{%default-nftables-ruleset}) +The nftables ruleset to use. This may be any ``file-like'' object +(@pxref{G-Expressions, file-like objects}). +@end table +@end deftp + @cindex NTP (Network Time Protocol), service @cindex ntpd, service for the Network Time Protocol daemon @cindex real time clock @@ -13194,7 +13390,7 @@ gateway @code{hostname}: (program (file-append openssh "/bin/ssh")) (arguments '("ssh" "-qT" "-i" "/path/to/ssh_key" - "-W" "smtp-server:25" "user@@hostname"))))) + "-W" "smtp-server:25" "user@@hostname"))))))) @end lisp See below for more details about @code{inetd-configuration}. @@ -19223,13 +19419,13 @@ Other services can also extend the @code{httpd-service-type} to add to the configuration. @lisp -(simple-service 'my-extra-server httpd-service-type +(simple-service 'www.example.com-server httpd-service-type (list (httpd-virtualhost "*:80" - (list (string-append - "ServerName "www.example.com - DocumentRoot \"/srv/http/www.example.com\""))))) + (list (string-join '("ServerName www.example.com" + "DocumentRoot /srv/http/www.example.com") + "\n"))))) @end lisp @end deffn @@ -19363,13 +19559,13 @@ This data type represents a virtualhost configuration block for the httpd servic These should be added to the extra-config for the httpd-service. @lisp -(simple-service 'my-extra-server httpd-service-type +(simple-service 'www.example.com-server httpd-service-type (list (httpd-virtualhost "*:80" - (list (string-append - "ServerName "www.example.com - DocumentRoot \"/srv/http/www.example.com\""))))) + (list (string-join '("ServerName www.example.com" + "DocumentRoot /srv/http/www.example.com") + "\n"))))) @end lisp @table @asis @@ -19664,13 +19860,12 @@ can do something along these lines: @lisp (define %gnu-mirror - (plain-file - "gnu.vcl" - "vcl 4.1; -backend gnu @{ .host = "www.gnu.org"; @}")) + (plain-file "gnu.vcl" + "vcl 4.1; +backend gnu @{ .host = \"www.gnu.org\"; @}")) (operating-system - ... + ;; @dots{} (services (cons (service varnish-service-type (varnish-configuration (listen '(":80")) @@ -24169,6 +24364,57 @@ The port to bind the server to. @end table @end deftp + +@node Guix Services +@subsection Guix Services + +@subsubheading Guix Data Service +The @uref{http://data.guix.gnu.org,Guix Data Service} processes, stores +and provides data about GNU Guix. This includes information about +packages, derivations and lint warnings. + +The data is stored in a PostgreSQL database, and available through a web +interface. + +@defvar {Scheme Variable} guix-data-service-type +Service type for the Guix Data Service. Its value must be a +@code{guix-data-service-configuration} object. The service optionally +extends the getmail service, as the guix-commits mailing list is used to +find out about changes in the Guix git repository. +@end defvar + +@deftp {Data Type} guix-data-service-configuration +Data type representing the configuration of the Guix Data Service. + +@table @asis +@item @code{package} (default: @code{guix-data-service}) +The Guix Data Service package to use. + +@item @code{user} (default: @code{"guix-data-service"}) +The system user to run the service as. + +@item @code{group} (default: @code{"guix-data-service"}) +The system group to run the service as. + +@item @code{port} (default: @code{8765}) +The port to bind the web service to. + +@item @code{host} (default: @code{"127.0.0.1"}) +The host to bind the web service to. + +@item @code{getmail-idle-mailboxes} (default: @code{#f}) +If set, this is the list of mailboxes that the getmail service will be +configured to listen to. + +@item @code{commits-getmail-retriever-configuration} (default: @code{#f}) +If set, this is the @code{getmail-retriever-configuration} object with +which to configure getmail to fetch mail from the guix-commits mailing +list. + +@end table +@end deftp + + @node Miscellaneous Services @subsection Miscellaneous Services diff --git a/doc/local.mk b/doc/local.mk index 42dd09f089..a361f2388e 100644 --- a/doc/local.mk +++ b/doc/local.mk @@ -26,7 +26,8 @@ info_TEXINFOS = %D%/guix.texi \ %D%/guix.es.texi \ %D%/guix.fr.texi \ %D%/guix.ru.texi \ - %D%/guix.zh_CN.texi + %D%/guix.zh_CN.texi \ + %D%/guix-cookbook.texi %C%_guix_TEXINFOS = \ %D%/contributing.texi \ @@ -109,6 +110,12 @@ $(srcdir)/%D%/guix.%.texi: po/doc/guix-manual.%.po $(srcdir)/%D%/contributing.%. -$(AM_V_POXREF)$(xref_command) -mv "$@.tmp" "$@" +$(srcdir)/%D%/guix-cookbook.%.texi: po/doc/guix-cookbook.%.po + -$(AM_V_PO4A)$(PO4A_TRANSLATE) $(PO4A_PARAMS) -m "%D%/guix-cookbook.texi" -p "$<" -l "$@.tmp" + -sed -i "s|guix-cookbook\.info|$$(basename "$@" | sed 's|texi$$|info|')|" "$@.tmp" + -$(AM_V_POXREF)$(xref_command) + -mv "$@.tmp" "$@" + $(srcdir)/%D%/contributing.%.texi: po/doc/guix-manual.%.po -$(AM_V_PO4A)$(PO4A_TRANSLATE) $(PO4A_PARAMS) -m "%D%/contributing.texi" -p "$<" -l "$@.tmp" -$(AM_V_POXREF)$(xref_command) |