summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim.cournoyer@gmail.com>2022-01-25 23:36:11 -0500
committerMaxim Cournoyer <maxim.cournoyer@gmail.com>2022-01-25 23:48:37 -0500
commit0d41fe4855588fb659b8adafe215d5573517a79b (patch)
tree38b274bd03375f4fa5b7d3a9fb3f64a19786bef2 /doc
parent7c57821c68d199ad56a8ed750b36eccc7ef238dd (diff)
parent1a5302435ff0d2822b823f5a6fe01faa7a85c629 (diff)
Merge branch 'staging' into core-updates.
With "conflicts" resolved in (mostly in favor of master/staging): gnu/packages/admin.scm gnu/packages/gnuzilla.scm gnu/packages/gtk.scm gnu/packages/kerberos.scm gnu/packages/linux.scm guix/lint.scm
Diffstat (limited to 'doc')
-rw-r--r--doc/build.scm606
-rw-r--r--doc/contributing.texi20
-rw-r--r--doc/environment-gdb.scm9
-rw-r--r--doc/guix-cookbook.texi62
-rw-r--r--doc/guix.texi1143
-rw-r--r--doc/local.mk6
6 files changed, 1434 insertions, 412 deletions
diff --git a/doc/build.scm b/doc/build.scm
index eebb493a2e..47cff15985 100644
--- a/doc/build.scm
+++ b/doc/build.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2019-2022 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
;;;
;;; This file is part of GNU Guix.
@@ -51,17 +51,7 @@
(@@ (guix self) file-append*))
(define translated-texi-manuals
- (let ((translated (@@ (guix self) translate-texi-manuals)))
- (lambda (source)
- (let ((result (translated source)))
- ;; Build with 'guile-3.0-latest', which is linked against
- ;; 'libgc/disable-munmap', to avoid the dreaded "mmap(PROT_NONE)
- ;; failed" crash: <https://bugs.gnu.org/47428>.
- (computed-file (computed-file-name result)
- (computed-file-gexp result)
- #:local-build? #f
- #:options (computed-file-options result)
- #:guile guile-3.0-latest)))))
+ (@@ (guix self) translate-texi-manuals))
(define info-manual
(@@ (guix self) info-manual))
@@ -610,6 +600,175 @@ its <pre class=\"lisp\"> blocks (as produced by 'makeinfo --html')."
(computed-file name build))
+(define* (stylized-html source input
+ #:key
+ (languages %languages)
+ (manual %manual)
+ (manual-css-url "/static/base/css/manual.css"))
+ "Process all the HTML files in INPUT; add them MANUAL-CSS-URL as a <style>
+link, and add a menu to choose among LANGUAGES. Use the Guix PO files found
+in SOURCE."
+ (define build
+ (with-extensions (list guile-lib)
+ (with-imported-modules `((guix build utils)
+ ((localization)
+ => ,(localization-helper-module
+ source languages)))
+ #~(begin
+ (use-modules (htmlprag)
+ (localization)
+ (guix build utils)
+ (srfi srfi-1)
+ (ice-9 match)
+ (ice-9 threads))
+
+ (define* (menu-dropdown #:key (label "Item") (url "#") (items '()))
+ ;; Return an SHTML <li> element representing a dropdown for the
+ ;; navbar. LABEL is the text of the dropdown menu, and ITEMS is
+ ;; the list of items in this menu.
+ (define id "visible-dropdown")
+
+ `(li
+ (@ (class "navbar-menu-item dropdown dropdown-btn"))
+ (input (@ (class "navbar-menu-hidden-input")
+ (type "radio")
+ (name "dropdown")
+ (id ,id)))
+ (label (@ (for ,id)) ,label)
+ (label (@ (for "all-dropdowns-hidden")) ,label)
+ (div
+ (@ (class "navbar-submenu")
+ (id "navbar-submenu"))
+ (div (@ (class "navbar-submenu-triangle"))
+ " ")
+ (ul ,@items))))
+
+ (define (menu-item label url)
+ ;; Return an SHTML <li> element for a menu item with the given
+ ;; LABEL and URL.
+ `(li (a (@ (class "navbar-menu-item")
+ (href ,url))
+ ,label)))
+
+ (define* (navigation-bar menus #:key split-node?)
+ ;; Return the navigation bar showing all of MENUS.
+ `(header (@ (class "navbar"))
+ (h1 (a (@ (class "branding")
+ (href ,(if split-node? ".." "#")))))
+ (nav (@ (class "navbar-menu"))
+ (input (@ (class "navbar-menu-hidden-input")
+ (type "radio")
+ (name "dropdown")
+ (id "all-dropdowns-hidden")))
+ (ul ,@menus))
+
+ ;; This is the button that shows up on small screen in
+ ;; lieu of the drop-down button.
+ (a (@ (class "navbar-menu-btn")
+ (href ,(if split-node? "../.." ".."))))))
+
+ (define* (base-language-url code manual
+ #:key split-node?)
+ ;; Return the base URL of MANUAL for language CODE.
+ (if split-node?
+ (string-append "../../" (normalize code) "/html_node")
+ (string-append "../" (normalize code) "/" manual
+ (if (string=? code "en")
+ ""
+ (string-append "." code))
+ ".html")))
+
+ (define (language-menu-items file)
+ ;; Return the language menu items to be inserted in FILE.
+ (define split-node?
+ (string-contains file "/html_node/"))
+
+ (append
+ (map (lambda (code)
+ (menu-item (language-code->native-name code)
+ (base-language-url code #$manual
+ #:split-node?
+ split-node?)))
+ '#$%languages)
+ (list
+ (menu-item "⊕"
+ (if (string=? #$manual "guix-cookbook")
+ "https://translate.fedoraproject.org/projects/guix/documentation-cookbook/"
+ "https://translate.fedoraproject.org/projects/guix/documentation-manual/")))))
+
+ (define (stylized-html sxml file)
+ ;; Return SXML, which was read from FILE, with additional
+ ;; styling.
+ (define split-node?
+ (string-contains file "/html_node/"))
+
+ (let loop ((sxml sxml))
+ (match sxml
+ (('*TOP* decl body ...)
+ `(*TOP* ,decl ,@(map loop body)))
+ (('head elements ...)
+ ;; Add reference to our own manual CSS, which provides
+ ;; support for the language menu.
+ `(head ,@elements
+ (link (@ (rel "stylesheet")
+ (type "text/css")
+ (href #$manual-css-url)))))
+ (('body ('@ attributes ...) elements ...)
+ `(body (@ ,@attributes)
+ ,(navigation-bar
+ ;; TODO: Add "Contribute" menu, to report
+ ;; errors, etc.
+ (list (menu-dropdown
+ #:label
+ `(img (@ (alt "Language")
+ (src "/static/base/img/language-picker.svg")))
+ #:items
+ (language-menu-items file)))
+ #:split-node? split-node?)
+ ,@elements))
+ ((tag ('@ attributes ...) body ...)
+ `(,tag (@ ,@attributes) ,@(map loop body)))
+ ((tag body ...)
+ `(,tag ,@(map loop body)))
+ ((? string? str)
+ str))))
+
+ (define (process-html file)
+ ;; Parse FILE and add links to translations. Install the result
+ ;; to #$output.
+ (format (current-error-port) "processing ~a...~%" file)
+ (let* ((shtml (parameterize ((%strict-tokenizer? #t))
+ (call-with-input-file file html->shtml)))
+ (processed (stylized-html shtml file))
+ (base (string-drop file (string-length #$input)))
+ (target (string-append #$output base)))
+ (mkdir-p (dirname target))
+ (call-with-output-file target
+ (lambda (port)
+ (write-shtml-as-html processed port)))))
+
+ ;; Install a UTF-8 locale so we can process UTF-8 files.
+ (setenv "GUIX_LOCPATH"
+ #+(file-append glibc-utf8-locales "/lib/locale"))
+ (setlocale LC_ALL "en_US.utf8")
+ (setenv "LC_ALL" "en_US.utf8")
+ (setvbuf (current-error-port) 'line)
+
+ (n-par-for-each (parallel-job-count)
+ (lambda (file)
+ (if (string-suffix? ".html" file)
+ (process-html file)
+ ;; Copy FILE as is to #$output.
+ (let* ((base (string-drop file (string-length #$input)))
+ (target (string-append #$output base)))
+ (mkdir-p (dirname target))
+ (if (eq? 'symlink (stat:type (lstat file)))
+ (symlink (readlink file) target)
+ (copy-file file target)))))
+ (find-files #$input))))))
+
+ (computed-file "stylized-html-manual" build))
+
(define* (html-manual source #:key (languages %languages)
(version "0.0")
(manual %manual)
@@ -700,9 +859,11 @@ makeinfo OPTIONS."
(filter (compose file-exists? language->texi-file-name)
'#$languages)))))
- (let* ((name (string-append manual "-html-manual"))
- (manual (computed-file name build #:local-build? #f)))
- (syntax-highlighted-html manual
+ (let* ((name (string-append manual "-html-manual"))
+ (manual* (computed-file name build #:local-build? #f)))
+ (syntax-highlighted-html (stylized-html source manual*
+ #:languages languages
+ #:manual manual)
#:mono-node-indexes mono-node-indexes
#:split-node-indexes split-node-indexes
#:name (string-append name "-highlighted"))))
@@ -835,6 +996,104 @@ from SOURCE."
(computed-file "guix-manual-po" build))
+(define* (localization-helper-module source
+ #:optional (languages %languages))
+ "Return a file-like object for use as the (localization) module. SOURCE
+must be the Guix top-level source directory, from which PO files are taken."
+ (define content
+ (with-extensions (list guile-json-3)
+ #~(begin
+ (define-module (localization)
+ #:use-module (json)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-19)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 popen)
+ #:export (normalize
+ with-language
+ translate
+ language-code->name
+ language-code->native-name
+ seconds->string))
+
+ (define (normalize language) ;XXX: deduplicate
+ ;; Normalize LANGUAGE. For instance, "zh_CN" becomes "zh-cn".
+ (string-map (match-lambda
+ (#\_ #\-)
+ (chr chr))
+ (string-downcase language)))
+
+ (define-syntax-rule (with-language language exp ...)
+ (let ((lang (getenv "LANGUAGE")))
+ (dynamic-wind
+ (lambda ()
+ (setenv "LANGUAGE" language)
+ (setlocale LC_MESSAGES))
+ (lambda () exp ...)
+ (lambda ()
+ (if lang
+ (setenv "LANGUAGE" lang)
+ (unsetenv "LANGUAGE"))
+ (setlocale LC_MESSAGES)))))
+
+ ;; (put 'with-language 'scheme-indent-function 1)
+ (define* (translate str language
+ #:key (domain "guix-manual"))
+ (define exp
+ `(begin
+ (bindtextdomain "guix-manual"
+ #+(guix-manual-text-domain
+ source
+ languages))
+ (bindtextdomain "iso_639-3" ;language names
+ #+(file-append iso-codes
+ "/share/locale"))
+ (setenv "LANGUAGE" ,language)
+ (write (gettext ,str ,domain))))
+
+ ;; Since the 'gettext' function caches msgid translations,
+ ;; regardless of $LANGUAGE, we have to spawn a new process each
+ ;; time we want to translate to a different language. Bah!
+ (let* ((pipe (open-pipe* OPEN_READ
+ #+(file-append guile-3.0
+ "/bin/guile")
+ "-c" (object->string exp)))
+ (str (read pipe)))
+ (close-pipe pipe)
+ str))
+
+ (define %iso639-languages
+ (vector->list
+ (assoc-ref (call-with-input-file
+ #+(file-append iso-codes
+ "/share/iso-codes/json/iso_639-3.json")
+ json->scm)
+ "639-3")))
+
+ (define (language-code->name code)
+ "Return the full name of a language from its ISO-639-3 code."
+ (let ((code (match (string-index code #\_)
+ (#f code)
+ (index (string-take code index)))))
+ (any (lambda (language)
+ (and (string=? (or (assoc-ref language "alpha_2")
+ (assoc-ref language "alpha_3"))
+ code)
+ (assoc-ref language "name")))
+ %iso639-languages)))
+
+ (define (language-code->native-name code)
+ "Return the name of language CODE in that language."
+ (translate (language-code->name code) code
+ #:domain "iso_639-3"))
+
+ (define (seconds->string seconds language)
+ (let* ((time (make-time time-utc 0 seconds))
+ (date (time-utc->date time)))
+ (with-language language (date->string date "~e ~B ~Y")))))))
+
+ (scheme-file "localization.scm" content))
+
(define* (html-manual-indexes source
#:key (languages %languages)
(version "0.0")
@@ -844,207 +1103,132 @@ from SOURCE."
"GNU Guix Cookbook"))
(date 1))
(define build
- (with-extensions (list guile-json-3)
- (with-imported-modules '((guix build utils))
- #~(begin
- (use-modules (guix build utils)
- (json)
- (ice-9 match)
- (ice-9 popen)
- (sxml simple)
- (srfi srfi-1)
- (srfi srfi-19))
-
- (define (normalize language) ;XXX: deduplicate
- ;; Normalize LANGUAGE. For instance, "zh_CN" becomes "zh-cn".
- (string-map (match-lambda
- (#\_ #\-)
- (chr chr))
- (string-downcase language)))
-
- (define-syntax-rule (with-language language exp ...)
- (let ((lang (getenv "LANGUAGE")))
- (dynamic-wind
- (lambda ()
- (setenv "LANGUAGE" language)
- (setlocale LC_MESSAGES))
- (lambda () exp ...)
- (lambda ()
- (if lang
- (setenv "LANGUAGE" lang)
- (unsetenv "LANGUAGE"))
- (setlocale LC_MESSAGES)))))
-
- ;; (put 'with-language 'scheme-indent-function 1)
- (define* (translate str language
- #:key (domain "guix-manual"))
- (define exp
- `(begin
- (bindtextdomain "guix-manual"
- #+(guix-manual-text-domain
- source
- languages))
- (bindtextdomain "iso_639-3" ;language names
- #+(file-append iso-codes
- "/share/locale"))
- (write (gettext ,str ,domain))))
-
- (with-language language
- ;; Since the 'gettext' function caches msgid translations,
- ;; regardless of $LANGUAGE, we have to spawn a new process each
- ;; time we want to translate to a different language. Bah!
- (let* ((pipe (open-pipe* OPEN_READ
- #+(file-append guile-2.2
- "/bin/guile")
- "-c" (object->string exp)))
- (str (read pipe)))
- (close-pipe pipe)
- str)))
-
- (define (seconds->string seconds language)
- (let* ((time (make-time time-utc 0 seconds))
- (date (time-utc->date time)))
- (with-language language (date->string date "~e ~B ~Y"))))
-
- (define (guix-url path)
- (string-append #$%web-site-url path))
-
- (define (sxml-index language title body)
- ;; FIXME: Avoid duplicating styling info from guix-artwork.git.
- `(html (@ (lang ,language))
- (head
- (title ,(string-append title " — GNU Guix"))
- (meta (@ (charset "UTF-8")))
- (meta (@ (name "viewport") (content "width=device-width, initial-scale=1.0")))
- ;; Menu prefetch.
- (link (@ (rel "prefetch") (href ,(guix-url "menu/index.html"))))
- ;; Base CSS.
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/elements.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/common.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/messages.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/navbar.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/breadcrumbs.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/buttons.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/footer.css"))))
-
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/page.css"))))
- (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/post.css")))))
- (body
- (header (@ (class "navbar"))
- (h1 (a (@ (class "branding")
- (href #$%web-site-url)))
- (span (@ (class "a11y-offset"))
- "Guix"))
- (nav (@ (class "menu"))))
- (nav (@ (class "breadcrumbs"))
- (a (@ (class "crumb")
- (href #$%web-site-url))
- "Home"))
- ,body
- (footer))))
-
- (define (language-index language)
- (define title
- (translate #$title language))
-
- (sxml-index
- language title
- `(main
- (article
- (@ (class "page centered-block limit-width"))
- (h2 ,title)
- (p (@ (class "post-metadata centered-text"))
- #$version " — "
- ,(seconds->string #$date language))
-
- (div
- (ul
- (li (a (@ (href "html_node"))
- "HTML, with a separate page per node"))
- (li (a (@ (href
- ,(string-append
- #$manual
- (if (string=? language
- "en")
- ""
- (string-append "."
- language))
- ".html")))
- "HTML, entirely on one page"))
- ,@(if (member language '("ru" "zh_CN"))
- '()
- `((li (a (@ (href ,(string-append
- #$manual
- (if (string=? language "en")
- ""
- (string-append "."
- language))
- ".pdf"))))
- "PDF")))))))))
-
- (define %iso639-languages
- (vector->list
- (assoc-ref (call-with-input-file
- #+(file-append iso-codes
- "/share/iso-codes/json/iso_639-3.json")
- json->scm)
- "639-3")))
-
- (define (language-code->name code)
- "Return the full name of a language from its ISO-639-3 code."
- (let ((code (match (string-index code #\_)
- (#f code)
- (index (string-take code index)))))
- (any (lambda (language)
- (and (string=? (or (assoc-ref language "alpha_2")
- (assoc-ref language "alpha_3"))
- code)
- (assoc-ref language "name")))
- %iso639-languages)))
-
- (define (top-level-index languages)
- (define title #$title)
- (sxml-index
- "en" title
- `(main
- (article
- (@ (class "page centered-block limit-width"))
- (h2 ,title)
- (div
- "This document is available in the following
+ (with-imported-modules `((guix build utils)
+ ((localization)
+ => ,(localization-helper-module
+ source languages)))
+ #~(begin
+ (use-modules (guix build utils)
+ (localization)
+ (sxml simple)
+ (srfi srfi-1))
+
+ (define (guix-url path)
+ (string-append #$%web-site-url path))
+
+ (define (sxml-index language title body)
+ ;; FIXME: Avoid duplicating styling info from guix-artwork.git.
+ `(html (@ (lang ,language))
+ (head
+ (title ,(string-append title " — GNU Guix"))
+ (meta (@ (charset "UTF-8")))
+ (meta (@ (name "viewport") (content "width=device-width, initial-scale=1.0")))
+ ;; Menu prefetch.
+ (link (@ (rel "prefetch") (href ,(guix-url "menu/index.html"))))
+ ;; Base CSS.
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/elements.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/common.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/messages.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/navbar.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/breadcrumbs.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/buttons.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/footer.css"))))
+
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/page.css"))))
+ (link (@ (rel "stylesheet") (href ,(guix-url "static/base/css/post.css")))))
+ (body
+ (header (@ (class "navbar"))
+ (h1 (a (@ (class "branding")
+ (href #$%web-site-url)))
+ (span (@ (class "a11y-offset"))
+ "Guix"))
+ (nav (@ (class "menu"))))
+ (nav (@ (class "breadcrumbs"))
+ (a (@ (class "crumb")
+ (href #$%web-site-url))
+ "Home"))
+ ,body
+ (footer))))
+
+ (define (language-index language)
+ (define title
+ (translate #$title language))
+
+ (sxml-index
+ language title
+ `(main
+ (article
+ (@ (class "page centered-block limit-width"))
+ (h2 ,title)
+ (p (@ (class "post-metadata centered-text"))
+ #$version " — "
+ ,(seconds->string #$date language))
+
+ (div
+ (ul
+ (li (a (@ (href "html_node"))
+ "HTML, with a separate page per node"))
+ (li (a (@ (href
+ ,(string-append
+ #$manual
+ (if (string=? language
+ "en")
+ ""
+ (string-append "."
+ language))
+ ".html")))
+ "HTML, entirely on one page"))
+ ,@(if (member language '("ru" "zh_CN"))
+ '()
+ `((li (a (@ (href ,(string-append
+ #$manual
+ (if (string=? language "en")
+ ""
+ (string-append "."
+ language))
+ ".pdf"))))
+ "PDF")))))))))
+
+ (define (top-level-index languages)
+ (define title #$title)
+ (sxml-index
+ "en" title
+ `(main
+ (article
+ (@ (class "page centered-block limit-width"))
+ (h2 ,title)
+ (div
+ "This document is available in the following
languages:\n"
- (ul
- ,@(map (lambda (language)
- `(li (a (@ (href ,(normalize language)))
- ,(translate
- (language-code->name language)
- language
- #:domain "iso_639-3"))))
- languages)))))))
-
- (define (write-html file sxml)
- (call-with-output-file file
- (lambda (port)
- (display "<!DOCTYPE html>\n" port)
- (sxml->xml sxml port))))
+ (ul
+ ,@(map (lambda (language)
+ `(li (a (@ (href ,(normalize language)))
+ ,(language-code->native-name language))))
+ languages)))))))
+
+ (define (write-html file sxml)
+ (call-with-output-file file
+ (lambda (port)
+ (display "<!DOCTYPE html>\n" port)
+ (sxml->xml sxml port))))
- (setenv "GUIX_LOCPATH"
- #+(file-append glibc-utf8-locales "/lib/locale"))
- (setenv "LC_ALL" "en_US.utf8")
- (setlocale LC_ALL "en_US.utf8")
+ (setenv "GUIX_LOCPATH"
+ #+(file-append glibc-utf8-locales "/lib/locale"))
+ (setenv "LC_ALL" "en_US.utf8")
+ (setlocale LC_ALL "en_US.utf8")
- (for-each (lambda (language)
- (define directory
- (string-append #$output "/"
- (normalize language)))
+ (for-each (lambda (language)
+ (define directory
+ (string-append #$output "/"
+ (normalize language)))
- (mkdir-p directory)
- (write-html (string-append directory "/index.html")
- (language-index language)))
- '#$languages)
+ (mkdir-p directory)
+ (write-html (string-append directory "/index.html")
+ (language-index language)))
+ '#$languages)
- (write-html (string-append #$output "/index.html")
- (top-level-index '#$languages))))))
+ (write-html (string-append #$output "/index.html")
+ (top-level-index '#$languages)))))
(computed-file "html-indexes" build))
diff --git a/doc/contributing.texi b/doc/contributing.texi
index db1c4c6921..9f97788c0b 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -695,7 +695,7 @@ package typically include a @file{snippets} directory, which could be
copied to the installation directory using:
@lisp
-#:include (cons "^snippets/" %default-include))
+#:include (cons "^snippets/" %default-include)
@end lisp
When encountering problems, it is wise to check for the presence of the
@@ -959,17 +959,11 @@ If you do not use Emacs, please make sure to let your editor knows these
rules. To automatically indent a package definition, you can also run:
@example
-./etc/indent-code.el gnu/packages/@var{file}.scm @var{package}
+./pre-inst-env guix style @var{package}
@end example
@noindent
-This automatically indents the definition of @var{package} in
-@file{gnu/packages/@var{file}.scm} by running Emacs in batch mode. To
-indent a whole file, omit the second argument:
-
-@example
-./etc/indent-code.el gnu/services/@var{file}.scm
-@end example
+@xref{Invoking guix style}, for more information.
@cindex Vim, Scheme code editing
If you are editing code with Vim, we recommend that you run @code{:set
@@ -1039,6 +1033,10 @@ name of the new or modified package, and fix any errors it reports
(@pxref{Invoking guix lint}).
@item
+Run @code{guix style @var{package}} to format the new package definition
+according to the project's conventions (@pxref{Invoking guix style}).
+
+@item
Make sure the package builds on your platform, using @code{guix build
@var{package}}.
@@ -1175,8 +1173,8 @@ Examples of unrelated changes include the addition of several packages,
or a package update along with fixes to that package.
@item
-Please follow our code formatting rules, possibly running the
-@command{etc/indent-code.el} script to do that automatically for you
+Please follow our code formatting rules, possibly running
+@command{guix style} script to do that automatically for you
(@pxref{Formatting Code}).
@item
diff --git a/doc/environment-gdb.scm b/doc/environment-gdb.scm
index 040a8637f8..0534e594de 100644
--- a/doc/environment-gdb.scm
+++ b/doc/environment-gdb.scm
@@ -6,8 +6,7 @@
;; Augment the package definition of GDB with the build tools
;; needed when developing GDB (and which are not needed when
;; simply installing it.)
-(package (inherit gdb)
- (native-inputs `(("autoconf" ,autoconf-2.64)
- ("automake" ,automake)
- ("texinfo" ,texinfo)
- ,@(package-native-inputs gdb))))
+(package
+ (inherit gdb)
+ (native-inputs (modify-inputs (package-native-inputs gdb)
+ (prepend autoconf-2.64 automake texinfo))))
diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi
index 88d3b98394..d2ce525998 100644
--- a/doc/guix-cookbook.texi
+++ b/doc/guix-cookbook.texi
@@ -1222,10 +1222,7 @@ $ guix import cran --recursive walrus
"1nk2glcvy4hyksl5ipq2mz8jy4fss90hx6cq98m3w96kzjni6jjj"))))
(build-system r-build-system)
(propagated-inputs
- `(("r-ggplot2" ,r-ggplot2)
- ("r-jmvcore" ,r-jmvcore)
- ("r-r6" ,r-r6)
- ("r-wrs2" ,r-wrs2)))
+ (list r-ggplot2 r-jmvcore r-r6 r-wrs2))
(home-page "https://github.com/jamovi/walrus")
(synopsis "Robust Statistical Methods")
(description
@@ -1284,8 +1281,7 @@ noticed that a significant number of them have a @code{inherit} field:
(sha256
(base32
"17fpahgh5dyckgz7rwqvzgnhx53cx9kr2xw0szprc6bnqy977fi8"))))
- (native-inputs
- `(("gtk-encode-symbolic-svg" ,gtk+ "bin")))))
+ (native-inputs (list `(,gtk+ "bin")))))
@end lisp
All unspecified fields are inherited from the parent package. This is very
@@ -1434,37 +1430,34 @@ The @code{linux-libre} kernel package definition is actually a procedure which
creates a package.
@lisp
-(define* (make-linux-libre version hash supported-systems
- #:key
- ;; A function that takes an arch and a variant.
- ;; See kernel-config for an example.
- (extra-version #false)
- (configuration-file #false)
- (defconfig "defconfig")
- (extra-options %default-extra-linux-options)
- (patches (list %boot-logo-patch)))
+(define* (make-linux-libre* version gnu-revision source supported-systems
+ #:key
+ (extra-version #f)
+ ;; A function that takes an arch and a variant.
+ ;; See kernel-config for an example.
+ (configuration-file #f)
+ (defconfig "defconfig")
+ (extra-options %default-extra-linux-options))
...)
@end lisp
-The current @code{linux-libre} package is for the 5.1.x series, and is
+The current @code{linux-libre} package is for the 5.15.x series, and is
declared like this:
@lisp
-(define-public linux-libre
- (make-linux-libre %linux-libre-version
- %linux-libre-hash
- '("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux")
- #:patches %linux-libre-5.1-patches
- #:configuration-file kernel-config))
+(define-public linux-libre-5.15
+ (make-linux-libre* linux-libre-5.15-version
+ linux-libre-5.15-gnu-revision
+ linux-libre-5.15-source
+ '("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux" "riscv64-linux")
+ #:configuration-file kernel-config))
@end lisp
Any keys which are not assigned values inherit their default value from the
@code{make-linux-libre} definition. When comparing the two snippets above,
-you may notice that the code comment in the first doesn't actually refer to
-the @code{#:extra-version} keyword; it is actually for
-@code{#:configuration-file}. Because of this, it is not actually easy to
-include a custom kernel configuration from the definition, but don't worry,
-there are other ways to work with what we do have.
+notice the code comment that refers to @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
@@ -1564,14 +1557,15 @@ custom kernel:
(@@@@ (gnu packages linux) %default-extra-linux-options)))
(define-public linux-libre-macbook41
- ;; XXX: Access the internal 'make-linux-libre' procedure, which is
+ ;; 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))
+ ((@@@@ (gnu packages linux) make-linux-libre*)
+ (@@@@ (gnu packages linux) linux-libre-version)
+ (@@@@ (gnu packages linux) linux-libre-gnu-revision)
+ (@@@@ (gnu packages linux) linux-libre-source)
+ '("x86_64-linux")
+ #:extra-version "macbook41"
+ #:extra-options %macbook41-config-options))
@end lisp
In the above example @code{%file-systems} is a collection of flags enabling
diff --git a/doc/guix.texi b/doc/guix.texi
index db479605ee..8ab86b1181 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -22,7 +22,7 @@
@set SUBSTITUTE-URLS https://@value{SUBSTITUTE-SERVER-1} https://@value{SUBSTITUTE-SERVER-2}
@copying
-Copyright @copyright{} 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès@*
+Copyright @copyright{} 2012-2022 Ludovic Courtès@*
Copyright @copyright{} 2013, 2014, 2016 Andreas Enge@*
Copyright @copyright{} 2013 Nikita Karetnikov@*
Copyright @copyright{} 2014, 2015, 2016 Alex Kost@*
@@ -33,7 +33,7 @@ Copyright @copyright{} 2015, 2016, 2017, 2019, 2020, 2021 Leo Famulari@*
Copyright @copyright{} 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ricardo Wurmus@*
Copyright @copyright{} 2016 Ben Woodcroft@*
Copyright @copyright{} 2016, 2017, 2018, 2021 Chris Marusich@*
-Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021 Efraim Flashner@*
+Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021, 2022 Efraim Flashner@*
Copyright @copyright{} 2016 John Darrington@*
Copyright @copyright{} 2016, 2017 Nikita Gillmann@*
Copyright @copyright{} 2016, 2017, 2018, 2019, 2020 Jan Nieuwenhuizen@*
@@ -50,7 +50,7 @@ Copyright @copyright{} 2017, 2021 Christine Lemmer-Webber@*
Copyright @copyright{} 2017, 2018, 2019, 2020, 2021 Marius Bakke@*
Copyright @copyright{} 2017, 2019, 2020 Hartmut Goebel@*
Copyright @copyright{} 2017, 2019, 2020, 2021 Maxim Cournoyer@*
-Copyright @copyright{} 2017, 2018, 2019, 2020, 2021 Tobias Geerinckx-Rice@*
+Copyright @copyright{} 2017–2022 Tobias Geerinckx-Rice@*
Copyright @copyright{} 2017 George Clemmer@*
Copyright @copyright{} 2017 Andy Wingo@*
Copyright @copyright{} 2017, 2018, 2019, 2020 Arun Isaac@*
@@ -69,9 +69,9 @@ Copyright @copyright{} 2019 Ivan Petkov@*
Copyright @copyright{} 2019 Jakob L. Kreuze@*
Copyright @copyright{} 2019 Kyle Andrews@*
Copyright @copyright{} 2019 Alex Griffin@*
-Copyright @copyright{} 2019, 2020, 2021 Guillaume Le Vaillant@*
+Copyright @copyright{} 2019, 2020, 2021, 2022 Guillaume Le Vaillant@*
Copyright @copyright{} 2020 Liliana Marie Prikler@*
-Copyright @copyright{} 2019, 2020, 2021 Simon Tournier@*
+Copyright @copyright{} 2019, 2020, 2021, 2022 Simon Tournier@*
Copyright @copyright{} 2020 Wiktor Żelazny@*
Copyright @copyright{} 2020 Damien Cassou@*
Copyright @copyright{} 2020 Jakub Kądziołka@*
@@ -279,6 +279,7 @@ Programming Interface
* Build Systems:: Specifying how packages are built.
* Build Phases:: Phases of the build process of a package.
* Build Utilities:: Helpers for your package definitions and more.
+* Search Paths:: Declaring search path environment variables.
* The Store:: Manipulating the package store.
* Derivations:: Low-level interface to package derivations.
* The Store Monad:: Purely functional interface to the store.
@@ -383,6 +384,7 @@ Defining Services
* Service Types and Services:: Types and services.
* Service Reference:: API reference.
* Shepherd Services:: A particular type of service.
+* Complex Configurations:: Defining bindings for complex configurations.
Installing Debugging Files
@@ -563,6 +565,15 @@ build (@pxref{Tracking Bugs and Patches}). That said, the Guix
community is actively working on improving this support, and now is a
great time to try it and get involved!
+@item riscv64-linux
+little-endian 64-bit RISC-V processors, specifically RV64GC, and
+Linux-Libre kernel. This playform is available as a "technology preview":
+although it is supported, substitutes are not yet available from the
+build farm (@pxref{Substitutes}), and some packages may fail to build
+(@pxref{Tracking Bugs and Patches}). That said, the Guix community is
+actively working on improving this support, and now is a great time to
+try it and get involved!
+
@end table
With Guix@tie{}System, you @emph{declare} all aspects of the operating system
@@ -574,7 +585,8 @@ Manual}), the well-known GNU utilities and tool chain, as well as the
graphical environment or system services of your choice.
Guix System is available on all the above platforms except
-@code{mips64el-linux} and @code{powerpc64le-linux}.
+@code{mips64el-linux}, @code{powerpc-linux}, @code{powerpc64le-linux} and
+@code{riscv64-linux}.
@noindent
For information on porting to other architectures or kernels,
@@ -882,7 +894,8 @@ GNU Guix is available for download from its website at
GNU Guix depends on the following packages:
@itemize
-@item @url{https://gnu.org/software/guile/, GNU Guile}, version 3.0.x;
+@item @url{https://gnu.org/software/guile/, GNU Guile}, version 3.0.x,
+version 3.0.3 or later;
@item @url{https://notabug.org/cwebber/guile-gcrypt, Guile-Gcrypt}, version
0.1.0 or later;
@item
@@ -1167,6 +1180,11 @@ user @file{nobody};
a writable @file{/tmp} directory.
@end itemize
+The chroot does not contain a @file{/home} directory, and the @env{HOME}
+environment variable is set to the non-existent
+@file{/homeless-shelter}. This helps to highlight inappropriate uses of
+@env{HOME} in the build scripts of packages.
+
You can influence the directory where the daemon stores build trees
@i{via} the @env{TMPDIR} environment variable. However, the build tree
within the chroot is always called @file{/tmp/guix-build-@var{name}.drv-0},
@@ -1249,9 +1267,10 @@ The @file{/etc/guix/machines.scm} file typically looks like this:
(systems (list "aarch64-linux"))
(host-key "ssh-rsa AAAAB3Nza@dots{}")
(user "alice")
- (private-key
- (string-append (getenv "HOME")
- "/.ssh/identity-for-guix"))))
+
+ ;; Remember 'guix offload' is spawned by
+ ;; 'guix-daemon' as root.
+ (private-key "/root/.ssh/identity-for-guix")))
@end lisp
@noindent
@@ -1688,7 +1707,7 @@ Compress build logs according to @var{type}, one of @code{gzip},
Unless @option{--lose-logs} is used, all the build logs are kept in the
@var{localstatedir}. To save space, the daemon automatically compresses
-them with Bzip2 by default.
+them with gzip by default.
@item --discover[=yes|no]
Whether to discover substitute servers on the local network using mDNS
@@ -3425,7 +3444,8 @@ libraries in the user's profile (@pxref{Environment Variables,,, gcc,
Using the GNU Compiler Collection (GCC)}). If GCC and, say, the C
library are installed in the profile, then @option{--search-paths} will
suggest setting these variables to @file{@var{profile}/include} and
-@file{@var{profile}/lib}, respectively.
+@file{@var{profile}/lib}, respectively (@pxref{Search Paths}, for info
+on search path specifications associated with packages.)
The typical use case is to define these environment variables in the
shell:
@@ -5804,17 +5824,6 @@ This is similar to the same-named option in @command{guix package}
(@pxref{profile-manifest, @option{--manifest}}) and uses the same
manifest files.
-@item --rebuild-cache
-When using @option{--manifest}, @option{--file}, or when invoked without
-arguments, @command{guix shell} caches the environment so that
-subsequent uses are instantaneous. The cache is invalidated anytime the
-file is modified.
-
-The @option{--rebuild-cache} forces the cached environment to be
-refreshed even if the file has not changed. This is useful if the
-@command{guix.scm} or @command{manifest.scm} has external dependencies,
-or if its behavior depends, say, on environment variables.
-
@item --pure
Unset existing environment variables when building the new environment, except
those specified with @option{--preserve} (see below). This has the effect of
@@ -5930,6 +5939,21 @@ directory:
guix shell --container --expose=$HOME=/exchange guile -- guile
@end example
+@item --rebuild-cache
+@cindex caching, of profiles
+@cindex caching, in @command{guix shell}
+In most cases, @command{guix shell} caches the environment so that
+subsequent uses are instantaneous. Least-recently used cache entries
+are periodically removed. The cache is also invalidated, when using
+@option{--file} or @option{--manifest}, anytime the corresponding file
+is modified.
+
+The @option{--rebuild-cache} forces the cached environment to be
+refreshed. This is useful when using @option{--file} or
+@option{--manifest} and the @command{guix.scm} or @command{manifest.scm}
+file has external dependencies, or if its behavior depends, say, on
+environment variables.
+
@item --root=@var{file}
@itemx -r @var{file}
@cindex persistent environment
@@ -5940,11 +5964,20 @@ register it as a garbage collector root.
This is useful if you want to protect your environment from garbage
collection, to make it ``persistent''.
-When this option is omitted, the environment is protected from garbage
-collection only for the duration of the @command{guix shell}
-session. This means that next time you recreate the same environment,
-you could have to rebuild or re-download packages. @xref{Invoking guix
-gc}, for more on GC roots.
+When this option is omitted, @command{guix shell} caches profiles so
+that subsequent uses of the same environment are instantaneous---this is
+comparable to using @option{--root} except that @command{guix shell}
+takes care of periodically removing the least-recently used garbage
+collector roots.
+
+In some cases, @command{guix shell} does not cache profiles---e.g., if
+transformation options such as @option{--with-latest} are used. In
+those cases, the environment is protected from garbage collection only
+for the duration of the @command{guix shell} session. This means that
+next time you recreate the same environment, you could have to rebuild
+or re-download packages.
+
+@xref{Invoking guix gc}, for more on GC roots.
@end table
@command{guix shell} also supports all of the common build options that
@@ -6829,6 +6862,7 @@ package definitions.
* Build Systems:: Specifying how packages are built.
* Build Phases:: Phases of the build process of a package.
* Build Utilities:: Helpers for your package definitions and more.
+* Search Paths:: Declaring search path environment variables.
* The Store:: Manipulating the package store.
* Derivations:: Low-level interface to package derivations.
* The Store Monad:: Purely functional interface to the store.
@@ -7209,7 +7243,21 @@ Outputs}, for typical uses of additional outputs.
@item @code{native-search-paths} (default: @code{'()})
@itemx @code{search-paths} (default: @code{'()})
A list of @code{search-path-specification} objects describing
-search-path environment variables honored by the package.
+search-path environment variables honored by the package. @xref{Search
+Paths}, for more on search path specifications.
+
+As for inputs, the distinction between @code{native-search-paths} and
+@code{search-paths} only matters when cross-compiling. In a
+cross-compilation context, @code{native-search-paths} applies
+exclusively to native inputs whereas @code{search-paths} applies only to
+host inputs.
+
+Packages such as cross-compilers care about target inputs---for
+instance, our (modified) GCC cross-compiler has
+@env{CROSS_C_INCLUDE_PATH} in @code{search-paths}, which allows it to
+pick @file{.h} files for the target system and @emph{not} those of
+native inputs. For the majority of packages though, only
+@code{native-search-paths} makes sense.
@item @code{replacement} (default: @code{#f})
This must be either @code{#f} or a package object that will be used as a
@@ -7624,8 +7672,22 @@ or replace package inputs.
@deffn {Scheme Syntax} modify-inputs @var{inputs} @var{clauses}
Modify the given package inputs, as returned by @code{package-inputs} & co.,
-according to the given clauses. The example below removes the GMP and ACL
-inputs of Coreutils and adds libcap to the back of the input list:
+according to the given clauses. Each clause must have one of the
+following forms:
+
+@table @code
+@item (delete @var{name}@dots{})
+Delete from the inputs packages with the given @var{name}s (strings).
+
+@item (append @var{package}@dots{})
+Add @var{package}s to the end of the input list.
+
+@item (prepend @var{package}@dots{})
+Add @var{package}s to the front of the input list.
+@end table
+
+The example below removes the GMP and ACL inputs of Coreutils and adds
+libcap to the back of the input list:
@lisp
(modify-inputs (package-inputs coreutils)
@@ -8347,9 +8409,10 @@ julia} packages, which essentially is similar to running @samp{julia -e
@env{JULIA_LOAD_PATH} contains the paths to all Julia package inputs.
Tests are run by calling @code{/test/runtests.jl}.
-The Julia package name is read from the file @file{Project.toml}. This
-value can be overridden by passing the argument @code{#:julia-package-name}
-(which must be correctly capitalized).
+The Julia package name and uuid is read from the file
+@file{Project.toml}. These values can be overridden by passing the
+argument @code{#:julia-package-name} (which must be correctly
+capitalized) or @code{#:julia-package-uuid}.
Julia packages usually manage their binary dependencies via
@code{JLLWrappers.jl}, a Julia package that creates a module (named
@@ -8377,12 +8440,10 @@ MbedTLS package:
(find-files "src/wrappers/" "\\.jl$"))))
@end lisp
-Some older packages that aren't using @file{Package.toml} yet, will require
-this file to be created, too. The function @code{julia-create-package-toml}
-helps creating the file. You need to pass the outputs and the source of the
-package, its name (the same as the @code{file-name} parameter), the package
-uuid, the package version, and a list of dependencies specified by their name
-and their uuid.
+Some older packages that aren't using @file{Project.toml} yet, will
+require this file to be created, too. It is internally done if the
+arguments @code{#:julia-package-name} and @code{#:julia-package-uuid}
+are provided.
@end defvr
@defvr {Scheme Variable} maven-build-system
@@ -8866,6 +8927,10 @@ standard list of phases. For @code{gnu-build-system}, the main build
phases are the following:
@table @code
+@item set-paths
+Define search path environment variables for all the input packages,
+including @env{PATH} (@pxref{Search Paths}).
+
@item unpack
Unpack the source tarball, and change the current directory to the
extracted source tree. If the source is actually a directory, copy it
@@ -9194,7 +9259,7 @@ the corresponding positional regexp sub-expression. For example:
(("hello")
"good morning\n")
(("foo([a-z]+)bar(.*)$" all letters end)
- (string-append "baz" letter end)))
+ (string-append "baz" letters end)))
@end lisp
Here, anytime a line of @var{file} contains @code{hello}, it is replaced
@@ -9282,6 +9347,80 @@ in a build phase of the @code{wireguard-tools} package:
`("PATH" ":" prefix ,(list coreutils))))))
@end lisp
+@subsection Program Invocation
+
+@cindex program invocation, from Scheme
+@cindex invoking programs, from Scheme
+You'll find handy procedures to spawn processes in this module,
+essentially convenient wrappers around Guile's @code{system*}
+(@pxref{Processes, @code{system*},, guile, GNU Guile Reference Manual}).
+
+@deffn {Scheme Procedure} invoke @var{program} @var{args}@dots{}
+Invoke @var{program} with the given @var{args}. Raise an
+@code{&invoke-error} exception if the exit code is non-zero; otherwise
+return @code{#t}.
+
+The advantage compared to @code{system*} is that you do not need to
+check the return value. This reduces boilerplate in shell-script-like
+snippets for instance in package build phases.
+@end deffn
+
+@deffn {Scheme Procedure} invoke-error? @var{c}
+Return true if @var{c} is an @code{&invoke-error} condition.
+@end deffn
+
+@deffn {Scheme Procedure} invoke-error-program @var{c}
+@deffnx {Scheme Procedure} invoke-error-arguments @var{c}
+@deffnx {Scheme Procedure} invoke-error-exit-status @var{c}
+@deffnx {Scheme Procedure} invoke-error-term-signal @var{c}
+@deffnx {Scheme Procedure} invoke-error-stop-signal @var{c}
+Access specific fields of @var{c}, an @code{&invoke-error} condition.
+@end deffn
+
+@deffn {Scheme Procedure} report-invoke-error @var{c} [@var{port}]
+Report to @var{port} (by default the current error port) about @var{c},
+an @code{&invoke-error} condition, in a human-friendly way.
+
+Typical usage would look like this:
+
+@lisp
+(use-modules (srfi srfi-34) ;for 'guard'
+ (guix build utils))
+
+(guard (c ((invoke-error? c)
+ (report-invoke-error c)))
+ (invoke "date" "--imaginary-option"))
+
+@print{} command "date" "--imaginary-option" failed with status 1
+@end lisp
+@end deffn
+
+@deffn {Scheme Procedure} invoke/quiet @var{program} @var{args}@dots{}
+Invoke @var{program} with @var{args} and capture @var{program}'s
+standard output and standard error. If @var{program} succeeds, print
+nothing and return the unspecified value; otherwise, raise a
+@code{&message} error condition that includes the status code and the
+output of @var{program}.
+
+Here's an example:
+
+@lisp
+(use-modules (srfi srfi-34) ;for 'guard'
+ (srfi srfi-35) ;for 'message-condition?'
+ (guix build utils))
+
+(guard (c ((message-condition? c)
+ (display (condition-message c))))
+ (invoke/quiet "date") ;all is fine
+ (invoke/quiet "date" "--imaginary-option"))
+
+@print{} 'date --imaginary-option' exited with status 1; output follows:
+
+ date: unrecognized option '--imaginary-option'
+ Try 'date --help' for more information.
+@end lisp
+@end deffn
+
@subsection Build Phases
@cindex build phases
@@ -9359,6 +9498,185 @@ executable files to be installed:
@c TODO: Add more examples.
+@node Search Paths
+@section Search Paths
+
+@cindex search path
+Many programs and libraries look for input data in a @dfn{search path},
+a list of directories: shells like Bash look for executables in the
+command search path, a C compiler looks for @file{.h} files in its
+header search path, the Python interpreter looks for @file{.py}
+files in its search path, the spell checker has a search path for
+dictionaries, and so on.
+
+Search paths can usually be defined or overridden @i{via} environment
+variables (@pxref{Environment Variables,,, libc, The GNU C Library
+Reference Manual}). For example, the search paths mentioned above can
+be changed by defining the @env{PATH}, @env{C_INCLUDE_PATH},
+@env{PYTHONPATH} (or @env{GUIX_PYTHONPATH}), and @env{DICPATH}
+environment variables---you know, all these something-PATH variables
+that you need to get right or things ``won't be found''.
+
+You may have noticed from the command line that Guix ``knows'' which
+search path environment variables should be defined, and how. When you
+install packages in your default profile, the file
+@file{~/.guix-profile/etc/profile} is created, which you can ``source''
+from the shell to set those variables. Likewise, if you ask
+@command{guix shell} to create an environment containing Python and
+NumPy, a Python library, and if you pass it the @option{--search-paths}
+option, it will tell you about @env{PATH} and @env{GUIX_PYTHONPATH}
+(@pxref{Invoking guix shell}):
+
+@example
+$ guix shell python python-numpy --pure --search-paths
+export PATH="/gnu/store/@dots{}-profile/bin"
+export GUIX_PYTHONPATH="/gnu/store/@dots{}-profile/lib/python3.9/site-packages"
+@end example
+
+When you omit @option{--search-paths}, it defines these environment
+variables right away, such that Python can readily find NumPy:
+
+@example
+$ guix shell python python-numpy -- python3
+Python 3.9.6 (default, Jan 1 1970, 00:00:01)
+[GCC 10.3.0] on linux
+Type "help", "copyright", "credits" or "license" for more information.
+>>> import numpy
+>>> numpy.version.version
+'1.20.3'
+@end example
+
+For this to work, the definition of the @code{python} package
+@emph{declares} the search path it cares about and its associated
+environment variable, @env{GUIX_PYTHONPATH}. It looks like this:
+
+@lisp
+(package
+ (name "python")
+ (version "3.9.9")
+ ;; some fields omitted...
+ (native-search-paths
+ (list (search-path-specification
+ (variable "GUIX_PYTHONPATH")
+ (files (list "lib/python/3.9/site-packages"))))))
+@end lisp
+
+What this @code{native-search-paths} field says is that, when the
+@code{python} package is used, the @env{GUIX_PYTHONPATH} environment
+variable must be defined to include all the
+@file{lib/python/3.9/site-packages} sub-directories encountered in its
+environment. (The @code{native-} bit means that, if we are in a
+cross-compilation environment, only native inputs may be added to the
+search path; @pxref{package Reference, @code{search-paths}}.)
+In the NumPy example above, the profile where
+@code{python} appears contains exactly one such sub-directory, and
+@env{GUIX_PYTHONPATH} is set to that. When there are several
+@file{lib/python/3.9/site-packages}---this is the case in package build
+environments---they are all added to @env{GUIX_PYTHONPATH}, separated by
+colons (@code{:}).
+
+@quotation Note
+Notice that @env{GUIX_PYTHONPATH} is specified as part of the definition
+of the @code{python} package, and @emph{not} as part of that of
+@code{python-numpy}. This is because this environment variable
+``belongs'' to Python, not NumPy: Python actually reads the value of
+that variable and honors it.
+
+Corollary: if you create a profile that does not contain @code{python},
+@code{GUIX_PYTHONPATH} will @emph{not} be defined, even if it contains
+packages that provide @file{.py} files:
+
+@example
+$ guix shell python-numpy --search-paths --pure
+export PATH="/gnu/store/@dots{}-profile/bin"
+@end example
+
+This makes a lot of sense if we look at this profile in isolation: no
+software in this profile would read @env{GUIX_PYTHONPATH}.
+@end quotation
+
+Of course, there are many variations on that theme: some packages honor
+more than one search path, some use separators other than colon, some
+accumulate several directories in their search path, and so on. A more
+complex example is the search path of libxml2: the value of the
+@env{XML_CATALOG_FILES} environment variable is space-separated, it must
+contain a list of @file{catalog.xml} files (not directories), which are
+to be found in @file{xml} sub-directories---nothing less. The search
+path specification looks like this:
+
+@lisp
+(package
+ (name "libxml2")
+ ;; some fields omitted
+ (native-search-paths
+ (list (search-path-specification
+ (variable "XML_CATALOG_FILES")
+ (separator " ")
+ (files '("xml"))
+ (file-pattern "^catalog\\.xml$")
+ (file-type 'regular)))))
+@end lisp
+
+Worry not, search path specifications are usually not this tricky.
+
+The @code{(guix search-paths)} module defines the data type of search
+path specifications and a number of helper procedures. Below is the
+reference of search path specifications.
+
+@deftp {Data Type} search-path-specification
+The data type for search path specifications.
+
+@table @asis
+@item @code{variable}
+The name of the environment variable for this search path (a string).
+
+@item @code{files}
+The list of sub-directories (strings) that should be added to the search
+path.
+
+@item @code{separator} (default: @code{":"})
+The string used to separate search path components.
+
+As a special case, a @code{separator} value of @code{#f} specifies a
+``single-component search path''---in other words, a search path that
+cannot contain more than one element. This is useful in some cases,
+such as the @code{SSL_CERT_DIR} variable (honored by OpenSSL, cURL, and
+a few other packages) or the @code{ASPELL_DICT_DIR} variable (honored by
+the GNU Aspell spell checker), both of which must point to a single
+directory.
+
+@item @code{file-type} (default: @code{'directory})
+The type of file being matched---@code{'directory} or @code{'regular},
+though it can be any symbol returned by @code{stat:type} (@pxref{File
+System, @code{stat},, guile, GNU Guile Reference Manual}).
+
+In the libxml2 example above, we would match regular files; in the
+Python example, we would match directories.
+
+@item @code{file-pattern} (default: @code{#f})
+This must be either @code{#f} or a regular expression specifying
+files to be matched @emph{within} the sub-directories specified by the
+@code{files} field.
+
+Again, the libxml2 example shows a situation where this is needed.
+@end table
+@end deftp
+
+How do you turn search path specifications on one hand and a bunch of
+directories on the other hand in a set of environment variable
+definitions? That's the job of @code{evaluate-search-paths}.
+
+@deffn {Scheme Procedure} evaluate-search-paths @var{search-paths} @
+ @var{directories} [@var{getenv}]
+Evaluate @var{search-paths}, a list of search-path specifications, for
+@var{directories}, a list of directory names, and return a list of
+specification/value pairs. Use @var{getenv} to determine the current
+settings and report only settings not already effective.
+@end deffn
+
+The @code{(guix profiles)} provides a higher-level helper procedure,
+@code{load-profile}, that sets the environment variables of a profile.
+
@node The Store
@section The Store
@@ -10182,11 +10500,11 @@ headers, which comes in handy in this case:
(with-imported-modules (source-module-closure
'((guix build utils)
- (gnu build vm)))
+ (gnu build image)))
(gexp->derivation "something-with-vms"
#~(begin
(use-modules (guix build utils)
- (gnu build vm))
+ (gnu build image))
@dots{})))
@end lisp
@@ -11023,6 +11341,67 @@ available options and a synopsis (these options are not shown in the
@table @code
+@cindex performance, tuning code
+@cindex optimization, of package code
+@cindex tuning, of package code
+@cindex SIMD support
+@cindex tunable packages
+@cindex package multi-versioning
+@item --tune[=@var{cpu}]
+Use versions of the packages marked as ``tunable'' optimized for
+@var{cpu}. When @var{cpu} is @code{native}, or when it is omitted, tune
+for the CPU on which the @command{guix} command is running.
+
+Valid @var{cpu} names are those recognized by the underlying compiler,
+by default the GNU Compiler Collection. On x86_64 processors, this
+includes CPU names such as @code{nehalem}, @code{haswell}, and
+@code{skylake} (@pxref{x86 Options, @code{-march},, gcc, Using the GNU
+Compiler Collection (GCC)}).
+
+As new generations of CPUs come out, they augment the standard
+instruction set architecture (ISA) with additional instructions, in
+particular instructions for single-instruction/multiple-data (SIMD)
+parallel processing. For example, while Core2 and Skylake CPUs both
+implement the x86_64 ISA, only the latter supports AVX2 SIMD
+instructions.
+
+The primary gain one can expect from @option{--tune} is for programs
+that can make use of those SIMD capabilities @emph{and} that do not
+already have a mechanism to select the right optimized code at run time.
+Packages that have the @code{tunable?} property set are considered
+@dfn{tunable packages} by the @option{--tune} option; a package
+definition with the property set looks like this:
+
+@lisp
+(package
+ (name "hello-simd")
+ ;; ...
+
+ ;; This package may benefit from SIMD extensions so
+ ;; mark it as "tunable".
+ (properties '((tunable? . #t))))
+@end lisp
+
+Other packages are not considered tunable. This allows Guix to use
+generic binaries in the cases where tuning for a specific CPU is
+unlikely to provide any gain.
+
+Tuned packages are built with @code{-march=@var{CPU}}; under the hood,
+the @option{-march} option is passed to the actual wrapper by a compiler
+wrapper. Since the build machine may not be able to run code for the
+target CPU micro-architecture, the test suite is not run when building a
+tuned package.
+
+To reduce rebuilds to the minimum, tuned packages are @emph{grafted}
+onto packages that depend on them (@pxref{Security Updates, grafts}).
+Thus, using @option{--no-grafts} cancels the effect of @option{--tune}.
+
+We call this technique @dfn{package multi-versioning}: several variants
+of tunable packages may be built, one for each CPU variant. It is the
+coarse-grain counterpart of @dfn{function multi-versioning} as
+implemented by the GNU tool chain (@pxref{Function Multiversioning,,,
+gcc, Using the GNU Compiler Collection (GCC)}).
+
@item --with-source=@var{source}
@itemx --with-source=@var{package}=@var{source}
@itemx --with-source=@var{package}@@@var{version}=@var{source}
@@ -11742,7 +12121,7 @@ following options:
Compute a hash using the specified @var{algorithm}, @code{sha256} by
default.
-@var{algorithm} must the name of a cryptographic hash algorithm
+@var{algorithm} must be the name of a cryptographic hash algorithm
supported by Libgcrypt @i{via} Guile-Gcrypt---e.g., @code{sha512} or
@code{sha3-256} (@pxref{Hash Functions,,, guile-gcrypt, Guile-Gcrypt
Reference Manual}).
@@ -11760,11 +12139,12 @@ in the definitions of packages.
@item --recursive
@itemx -r
-This option is deprecated in favor of @option{--serializer}. It is a
-legacy alias for @var{type} sets to @code{nar}.
+The @option{--recursive} option is deprecated in favor of
+@option{--serializer=nar} (see below); @option{-r} remains accepted as a
+convenient shorthand.
@item --serializer=@var{type}
-@itemx -S
+@itemx -S @var{type}
Compute the hash on @var{file} using @var{type} serialization.
@var{type} may be one of the following:
@@ -11778,14 +12158,14 @@ Compute the hash of a ``normalized archive'' (or ``nar'') containing
@var{file}, including its children if it is a directory. Some of the
metadata of @var{file} is part of the archive; for instance, when
@var{file} is a regular file, the hash is different depending on whether
-@var{file} is executable or not. Metadata such as time stamps has no
+@var{file} is executable or not. Metadata such as time stamps have no
impact on the hash (@pxref{Invoking guix archive}, for more info on the
nar format).
@c FIXME: Replace xref above with xref to an ``Archive'' section when
@c it exists.
@item git
-Compute the has of the file or directory as a Git ``tree'', following
+Compute the hash of the file or directory as a Git ``tree'', following
the same method as the Git version control system.
@end table
@@ -11802,7 +12182,7 @@ Reference}):
@example
$ git clone http://example.org/foo.git
$ cd foo
-$ guix hash -rx .
+$ guix hash -x --serializer=nar .
@end example
@end table
@@ -12718,8 +13098,16 @@ otherwise.
The @command{guix style} command helps packagers style their package
definitions according to the latest fashionable trends. The command
-currently focuses on one aspect: the style of package inputs. It may
-eventually be extended to handle other stylistic matters.
+currently provides the following styling rules:
+
+@itemize
+@item
+formatting package definitions according to the project's conventions
+(@pxref{Formatting Code});
+
+@item
+rewriting package inputs to the ``new style'', as explained below.
+@end itemize
The way package inputs are written is going through a transition
(@pxref{package Reference}, for more on package inputs). Until version
@@ -12750,7 +13138,7 @@ Package Variants}, for more info on @code{modify-inputs}).
In the vast majority of cases, this is a purely mechanical change on the
surface syntax that does not even incur a package rebuild. Running
-@command{guix style} can do that for you, whether you're working on
+@command{guix style -S inputs} can do that for you, whether you're working on
packages in Guix proper or in an external channel.
The general syntax is:
@@ -12760,15 +13148,48 @@ guix style [@var{options}] @var{package}@dots{}
@end example
This causes @command{guix style} to analyze and rewrite the definition
-of @var{package}@dots{}. It does so in a conservative way: preserving
-comments and bailing out if it cannot make sense of the code that
-appears in an inputs field. The available options are listed below.
+of @var{package}@dots{} or, when @var{package} is omitted, of @emph{all}
+the packages. The @option{--styling} or @option{-S} option allows you
+to select the style rule, the default rule being @code{format}---see
+below.
+
+The available options are listed below.
@table @code
@item --dry-run
@itemx -n
Show source file locations that would be edited but do not modify them.
+@item --styling=@var{rule}
+@itemx -S @var{rule}
+Apply @var{rule}, one of the following styling rules:
+
+@table @code
+@item format
+Format the given package definition(s)---this is the default styling
+rule. For example, a packager running Guix on a checkout
+(@pxref{Running Guix Before It Is Installed}) might want to reformat the
+definition of the Coreutils package like so:
+
+@example
+./pre-inst-env guix style coreutils
+@end example
+
+@item inputs
+Rewrite package inputs to the ``new style'', as described above. This
+is how you would rewrite inputs of package @code{whatnot} in your own
+channel:
+
+@example
+guix style -L ~/my/channel -S inputs whatnot
+@end example
+
+Rewriting is done in a conservative way: preserving comments and bailing
+out if it cannot make sense of the code that appears in an inputs field.
+The @option{--input-simplification} option described below provides
+fine-grain control over when inputs should be simplified.
+@end table
+
@item --load-path=@var{directory}
@itemx -L @var{directory}
Add @var{directory} to the front of the package module search path
@@ -12787,9 +13208,10 @@ guix style -e '(@@ (gnu packages gcc) gcc-5)'
styles the @code{gcc-5} package definition.
@item --input-simplification=@var{policy}
-Specify the package input simplification policy for cases where an input
-label does not match the corresponding package name. @var{policy} may
-be one of the following:
+When using the @code{inputs} styling rule, with @samp{-S inputs}, this
+option specifies the package input simplification policy for cases where
+an input label does not match the corresponding package name.
+@var{policy} may be one of the following:
@table @code
@item silent
@@ -14384,7 +14806,7 @@ your operating system declaration:
(mingetty-service-type config =>
(mingetty-configuration
(inherit config)
- ;; Automatially log in as "guest".
+ ;; Automatically log in as "guest".
(auto-login "guest")))))
(operating-system
@@ -15395,6 +15817,11 @@ account is created.
@item @code{comment} (default: @code{""})
A comment about the account, such as the account owner's full name.
+Note that, for non-system accounts, users are free to change their real
+name as it appears in @file{/etc/passwd} using the @command{chfn}
+command. When they do, their choice prevails over the system
+administrator's choice; reconfiguring does @emph{not} change their name.
+
@item @code{home-directory}
This is the name of the home directory for the account.
@@ -16480,7 +16907,7 @@ The number of seconds of silence and the number of seconds of activity,
respectively, after which a build process times out. A value of zero
disables the timeout.
-@item @code{log-compression} (default: @code{'bzip2})
+@item @code{log-compression} (default: @code{'gzip})
The type of compression used for build logs---one of @code{gzip},
@code{bzip2}, or @code{none}.
@@ -16745,6 +17172,11 @@ cache miss. @xref{Invoking guix publish,
When it is an integer, this denotes the @dfn{time-to-live} in seconds
of the published archives. @xref{Invoking guix publish, @option{--ttl}},
for more information.
+
+@item @code{negative-ttl} (default: @code{#f})
+When it is an integer, this denotes the @dfn{time-to-live} in
+seconds for the negative lookups. @xref{Invoking guix publish,
+@option{--negative-ttl}}, for more information.
@end table
@end deftp
@@ -18068,7 +18500,17 @@ The value for this service type is a
@command{rsync-configuration} record as in this example:
@lisp
-(service rsync-service-type)
+;; Export two directories over rsync. By default rsync listens on
+;; all the network interfaces.
+(service rsync-service-type
+ (rsync-configuration
+ (modules (list (rsync-module
+ (name "music")
+ (file-name "/srv/zik")
+ (read-only? #f))
+ (rsync-module
+ (name "movies")
+ (file-name "/home/charlie/movies"))))))
@end lisp
See below for details about @code{rsync-configuration}.
@@ -18099,34 +18541,55 @@ Name of the file where @command{rsync} writes its lock file.
@item @code{log-file} (default: @code{"/var/log/rsyncd.log"})
Name of the file where @command{rsync} writes its log file.
-@item @code{use-chroot?} (default: @var{#t})
-Whether to use chroot for @command{rsync} shared directory.
-
-@item @code{share-path} (default: @file{/srv/rsync})
-Location of the @command{rsync} shared directory.
-
-@item @code{share-comment} (default: @code{"Rsync share"})
-Comment of the @command{rsync} shared directory.
-
-@item @code{read-only?} (default: @var{#f})
-Read-write permissions to shared directory.
-
-@item @code{timeout} (default: @code{300})
-I/O timeout in seconds.
-
-@item @code{user} (default: @var{"root"})
+@item @code{user} (default: @code{"root"})
Owner of the @code{rsync} process.
-@item @code{group} (default: @var{"root"})
+@item @code{group} (default: @code{"root"})
Group of the @code{rsync} process.
-@item @code{uid} (default: @var{"rsyncd"})
+@item @code{uid} (default: @code{"rsyncd"})
User name or user ID that file transfers to and from that module should take
place as when the daemon was run as @code{root}.
-@item @code{gid} (default: @var{"rsyncd"})
+@item @code{gid} (default: @code{"rsyncd"})
Group name or group ID that will be used when accessing the module.
+@item @code{modules} (default: @code{%default-modules})
+List of ``modules''---i.e., directories exported over rsync. Each
+element must be a @code{rsync-module} record, as described below.
+@end table
+@end deftp
+
+@deftp {Data Type} rsync-module
+This is the data type for rsync ``modules''. A module is a directory
+exported over the rsync protocol. The available fields are as follows:
+
+@table @asis
+@item @code{name}
+The module name. This is the name that shows up in URLs. For example,
+if the module is called @code{music}, the corresponding URL will be
+@code{rsync://host.example.org/music}.
+
+@item @code{file-name}
+Name of the directory being exported.
+
+@item @code{comment} (default: @code{""})
+Comment associated with the module. Client user interfaces may display
+it when they obtain the list of available modules.
+
+@item @code{read-only?} (default: @code{#t})
+Whether or not client will be able to upload files. If this is false,
+the uploads will be authorized if permissions on the daemon side permit
+it.
+
+@item @code{chroot?} (default: @code{#t})
+When this is true, the rsync daemon changes root to the module's
+directory before starting file transfers with the client. This improves
+security, but requires rsync to run as root.
+
+@item @code{timeout} (default: @code{300})
+Idle time in seconds after which the daemon closes a connection with the
+client.
@end table
@end deftp
@@ -23690,9 +24153,9 @@ service found under @file{/var/lib/jami} are recreated every time the
service starts.
Jami accounts and their corresponding backup archives can be generated
-using either the @code{jami-qt} or @code{jami-gnome} Jami clients. The
-accounts should not be password-protected, but it is wise to ensure
-their files are only readable by @samp{root}.
+using the @code{jami} or @code{jami-gnome} Jami clients. The accounts
+should not be password-protected, but it is wise to ensure their files
+are only readable by @samp{root}.
The next example shows how to declare that only some contacts should be
allowed to communicate with a given account:
@@ -23807,7 +24270,7 @@ The complete set of available configuration options is detailed below.
Available @code{jami-configuration} fields are:
@table @asis
-@item @code{jamid} (default: @code{libring}) (type: package)
+@item @code{jamid} (default: @code{libjami}) (type: package)
The Jami daemon package to use.
@item @code{dbus} (default: @code{dbus}) (type: package)
@@ -28610,6 +29073,9 @@ The IP addresses to be assigned to the above interface.
@item @code{port} (default: @code{51820})
The port on which to listen for incoming connections.
+@item @code{dns} (default: @code{#f})
+The DNS server(s) to announce to VPN clients via DHCP.
+
@item @code{private-key} (default: @code{"/etc/wireguard/private.key"})
The private key file for the interface. It is automatically generated if
the file does not exist.
@@ -32975,7 +33441,7 @@ Service type for a Guix Build Coordinator agent. Its value must be a
Data type representing the configuration a Guix Build Coordinator agent.
@table @asis
-@item @code{package} (default: @code{guix-build-coordinator})
+@item @code{package} (default: @code{guix-build-coordinator/agent-only})
The Guix Build Coordinator package to use.
@item @code{user} (default: @code{"guix-build-coordinator-agent"})
@@ -33970,14 +34436,27 @@ should be setuid root.
The @code{setuid-programs} field of an @code{operating-system}
declaration contains a list of @code{<setuid-program>} denoting the
names of programs to have a setuid or setgid bit set (@pxref{Using the
-Configuration System}). For instance, the @command{passwd} program,
-which is part of the Shadow package, with a setuid root can be
+Configuration System}). For instance, the @command{mount.nfs} program,
+which is part of the nfs-utils package, with a setuid root can be
designated like this:
-@example
+@lisp
(setuid-program
- (program (file-append shadow "/bin/passwd")))
-@end example
+ (program (file-append nfs-utils "/sbin/mount.nfs")))
+@end lisp
+
+And then, to make @command{mount.nfs} setuid on your system, add the
+previous example to your operating system declaration by appending it to
+@code{%setuid-programs} like this:
+
+@lisp
+(operating-system
+ ;; Some fields omitted...
+ (setuid-programs
+ (append (list (setuid-program
+ (program (file-append nfs-utils "/sbin/mount.nfs")))
+ %setuid-programs))))
+@end lisp
@deftp {Data Type} setuid-program
This data type represents a program with a setuid or setgid bit set.
@@ -34977,6 +35456,11 @@ $ $(guix system vm my-config.scm) -m 1024 -smp 2 -nic user,model=virtio-net-pci
The VM shares its store with the host system.
+By default, the root file system of the VM is mounted volatile; the
+@option{--persistent} option can be provided to make it persistent
+instead. In that case, the VM disk-image file will be copied from the
+store to the @env{TMPDIR} directory to make it writable.
+
Additional file systems can be shared between the host and the VM using
the @option{--share} and @option{--expose} command-line options: the former
specifies a directory to be shared with write access, while the latter
@@ -35013,18 +35497,9 @@ QEMU monitor and the VM.
@cindex System images, creation in various formats
@cindex Creating system images in various formats
@item image
-@itemx docker-image
-Return a virtual machine, disk image, or Docker image of the operating
-system declared in @var{file} that stands alone. By default,
-@command{guix system} estimates the size of the image needed to store
-the system, but you can use the @option{--image-size} option to specify
-a value. Docker images are built to contain exactly what they need, so
-the @option{--image-size} option is ignored in the case of
-@code{docker-image}.
-
@cindex image, creating disk images
-The @code{image} command can produce various image types. The
-image type can be selected using the @option{--image-type} option. It
+The @code{image} command can produce various image types. The image
+type can be selected using the @option{--image-type} option. It
defaults to @code{efi-raw}. When its value is @code{iso9660}, the
@option{--label} option can be used to specify a volume ID with
@code{image}. By default, the root file system of a disk image is
@@ -35067,11 +35542,11 @@ uses the SeaBIOS BIOS by default, expecting a bootloader to be installed
in the Master Boot Record (MBR).
@cindex docker-image, creating docker images
-When using @code{docker-image}, a Docker image is produced. Guix builds
-the image from scratch, not from a pre-existing Docker base image. As a
-result, it contains @emph{exactly} what you define in the operating
-system configuration file. You can then load the image and launch a
-Docker container using commands like the following:
+When using the @code{docker} image type, a Docker image is produced.
+Guix builds the image from scratch, not from a pre-existing Docker base
+image. As a result, it contains @emph{exactly} what you define in the
+operating system configuration file. You can then load the image and
+launch a Docker container using commands like the following:
@example
image_id="$(docker load < guix-system-docker-image.tar.gz)"
@@ -35496,6 +35971,16 @@ returned by @command{guix describe}) to determine whether commits
currently in use are descendants of those deployed. When this is not
the case and @code{allow-downgrades?} is false, it raises an error.
This ensures you do not accidentally downgrade remote machines.
+
+@item @code{safety-checks?} (default: @code{#t})
+Whether to perform ``safety checks'' before deployment. This includes
+verifying that devices and file systems referred to in the operating
+system configuration actually exist on the target machine, and making
+sure that Linux modules required to access storage devices at boot time
+are listed in the @code{initrd-modules} field of the operating system.
+
+These safety checks ensure that you do not inadvertently deploy a system
+that would fail to boot. Be careful before turning them off!
@end table
@end deftp
@@ -35665,6 +36150,7 @@ them in the first place? And what is a service anyway?
* Service Types and Services:: Types and services.
* Service Reference:: API reference.
* Shepherd Services:: A particular type of service.
+* Complex Configurations:: Defining bindings for complex configurations.
@end menu
@node Service Composition
@@ -36398,6 +36884,376 @@ system:
This service represents PID@tie{}1.
@end defvr
+@node Complex Configurations
+@subsection Complex Configurations
+@cindex complex configurations
+Some programs might have rather complex configuration files or formats,
+and to make it easier to create Scheme bindings for these configuration
+files, you can use the utilities defined in the @code{(gnu services
+configuration)} module.
+
+The main utility is the @code{define-configuration} macro, which you
+will use to define a Scheme record type (@pxref{Record Overview,,,
+guile, GNU Guile Reference Manual}). The Scheme record will be
+serialized to a configuration file by using @dfn{serializers}, which are
+procedures that take some kind of Scheme value and returns a
+G-expression (@pxref{G-Expressions}), which should, once serialized to
+the disk, return a string. More details are listed below.
+
+@deffn {Scheme Syntax} define-configuration @var{name} @var{clause1} @
+@var{clause2} ...
+Create a record type named @code{@var{name}} that contains the
+fields found in the clauses.
+
+A clause can have one of the following forms:
+
+@example
+(@var{field-name}
+ (@var{type} @var{default-value})
+ @var{documentation})
+
+(@var{field-name}
+ (@var{type} @var{default-value})
+ @var{documentation}
+ @var{serializer})
+
+(@var{field-name}
+ (@var{type})
+ @var{documentation})
+
+(@var{field-name}
+ (@var{type})
+ @var{documentation}
+ @var{serializer})
+@end example
+
+@var{field-name} is an identifier that denotes the name of the field in
+the generated record.
+
+@var{type} is the type of the value corresponding to @var{field-name};
+since Guile is untyped, a predicate
+procedure---@code{@var{type}?}---will be called on the value
+corresponding to the field to ensure that the value is of the correct
+type. This means that if say, @var{type} is @code{package}, then a
+procedure named @code{package?} will be applied on the value to make
+sure that it is indeed a @code{<package>} object.
+
+@var{default-value} is the default value corresponding to the field; if
+none is specified, the user is forced to provide a value when creating
+an object of the record type.
+
+@c XXX: Should these be full sentences or are they allow to be very
+@c short like package synopses?
+@var{documentation} is a string formatted with Texinfo syntax which
+should provide a description of what setting this field does.
+
+@var{serializer} is the name of a procedure which takes two arguments,
+the first is the name of the field, and the second is the value
+corresponding to the field. The procedure should return a string or
+G-expression (@pxref{G-Expressions}) that represents the content that
+will be serialized to the configuration file. If none is specified, a
+procedure of the name @code{serialize-@var{type}} will be used.
+
+A simple serializer procedure could look like this:
+
+@lisp
+(define (serialize-boolean field-name value)
+ (let ((value (if value "true" "false")))
+ #~(string-append #$field-name #$value)))
+@end lisp
+
+In some cases multiple different configuration records might be defined
+in the same file, but their serializers for the same type might have to
+be different, because they have different configuration formats. For
+example, the @code{serialize-boolean} procedure for the Getmail service
+would have to be different for the one for the Transmission service. To
+make it easier to deal with this situation, one can specify a serializer
+prefix by using the @code{prefix} literal in the
+@code{define-configuration} form. This means that one doesn't have to
+manually specify a custom @var{serializer} for every field.
+
+@lisp
+(define (foo-serialize-string field-name value)
+ @dots{})
+
+(define (bar-serialize-string field-name value)
+ @dots{})
+
+(define-configuration foo-configuration
+ (label
+ (string)
+ "The name of label.")
+ (prefix foo-))
+
+(define-configuration bar-configuration
+ (ip-address
+ (string)
+ "The IPv4 address for this device.")
+ (prefix bar-))
+@end lisp
+
+However, in some cases you might not want to serialize any of the values
+of the record, to do this, you can use the @code{no-serialization}
+literal. There is also the @code{define-configuration/no-serialization}
+macro which is a shorthand of this.
+
+@lisp
+;; Nothing will be serialized to disk.
+(define-configuration foo-configuration
+ (field
+ (string "test")
+ "Some documentation.")
+ (no-serialization))
+
+;; The same thing as above.
+(define-configuration/no-serialization bar-configuration
+ (field
+ (string "test")
+ "Some documentation."))
+@end lisp
+@end deffn
+
+@deffn {Scheme Syntax} define-maybe @var{type}
+Sometimes a field should not be serialized if the user doesn’t specify a
+value. To achieve this, you can use the @code{define-maybe} macro to
+define a ``maybe type''; if the value of a maybe type is set to the
+@code{disabled}, it will not be serialized.
+
+When defining a ``maybe type'', the corresponding serializer for the
+regular type will be used by default. For example, a field of type
+@code{maybe-string} will be serialized using the @code{serialize-string}
+procedure by default, you can of course change this by specifying a
+custom serializer procedure. Likewise, the type of the value would have
+to be a string, unless it is set to the @code{disabled} symbol.
+
+@lisp
+(define-maybe string)
+
+(define (serialize-string field-name value)
+ @dots{})
+
+(define-configuration baz-configuration
+ (name
+ ;; Nothing will be serialized by default. If set to a string, the
+ ;; `serialize-string' procedure will be used to serialize the string.
+ (maybe-string 'disabled)
+ "The name of this module."))
+@end lisp
+
+Like with @code{define-configuration}, one can set a prefix for the
+serializer name by using the @code{prefix} literal.
+
+@lisp
+(define-maybe integer
+ (prefix baz-))
+
+(define (baz-serialize-interger field-name value)
+ @dots{})
+@end lisp
+
+There is also the @code{no-serialization} literal, which when set means
+that no serializer will be defined for the ``maybe type'', regardless of
+its value is @code{disabled} or not.
+@code{define-maybe/no-serialization} is a shorthand for specifying the
+@code{no-serialization} literal.
+
+@lisp
+(define-maybe/no-serialization symbol)
+
+(define-configuration/no-serialization test-configuration
+ (mode
+ (maybe-symbol 'disabled)
+ "Docstring."))
+@end lisp
+@end deffn
+
+@deffn {Scheme Procedure} serialize-configuration @var{configuration} @
+@var{fields}
+Return a G-expression that contains the values corresponding to the
+@var{fields} of @var{configuration}, a record that has been generated by
+@code{define-configuration}. The G-expression can then be serialized to
+disk by using something like @code{mixed-text-file}.
+@end deffn
+
+@deffn {Scheme Procedure} validate-configuration @var{configuration}
+@var{fields}
+Type-check @var{fields}, a list of field names of @var{configuration}, a
+configuration record created by @code{define-configuration}.
+@end deffn
+
+@deffn {Scheme Procedure} empty-serializer @var{field-name} @var{value}
+A serializer that just returns an empty string. The
+@code{serialize-package} procedure is an alias for this.
+@end deffn
+
+Once you have defined a configuration record, you will most likely also
+want to document it so that other people know to use it. To help with
+that, there are two procedures, both of which are documented below.
+
+@deffn {Scheme Procedure} generate-documentation @var{documentation} @
+@var{documentation-name}
+Generate a Texinfo fragment from the docstrings in @var{documentation},
+a list of @code{(@var{label} @var{fields} @var{sub-documentation} ...)}.
+@var{label} should be a symbol and should be the name of the
+configuration record. @var{fields} should be a list of all the fields
+available for the configuration record.
+
+@var{sub-documentation} is a @code{(@var{field-name}
+@var{configuration-name})} tuple. @var{field-name} is the name of the
+field which takes another configuration record as its value, and
+@var{configuration-name} is the name of that configuration record.
+
+@var{sub-documentation} is only needed if there are nested configuration
+records. For example, the @code{getmail-configuration} record
+(@pxref{Mail Services}) accepts a @code{getmail-configuration-file}
+record in one of its @code{rcfile} field, therefore documentation for
+@code{getmail-configuration-file} is nested in
+@code{getmail-configuration}.
+
+@lisp
+(generate-documentation
+ `((getmail-configuration ,getmail-configuration-fields
+ (rcfile getmail-configuration-file))
+ @dots{})
+ 'getmail-configuration)
+@end lisp
+
+@var{documentation-name} should be a symbol and should be the name of
+the configuration record.
+
+@end deffn
+
+@deffn {Scheme Procedure} configuration->documentation
+@var{configuration-symbol}
+Take @var{configuration-symbol}, the symbol corresponding to the name
+used when defining a configuration record with
+@code{define-configuration}, and print the Texinfo documentation of its
+fields. This is useful if there aren’t any nested configuration records
+since it only prints the documentation for the top-level fields.
+@end deffn
+
+As of right now, there is no automated way to generate documentation for
+configuration records and put them in the manual. Instead, every
+time you make a change to the docstrings of a configuration record, you
+have to manually call @code{generate-documentation} or
+@code{configuration->documentation}, and paste the output into the
+@file{doc/guix.texi} file.
+
+@c TODO: Actually test this
+Below is an example of a record type created using
+@code{define-configuration} and friends.
+
+@lisp
+(use-modules (gnu services)
+ (guix gexp)
+ (gnu services configuration)
+ (srfi srfi-26)
+ (srfi srfi-1))
+
+;; Turn field names, which are Scheme symbols into strings
+(define (uglify-field-name field-name)
+ (let ((str (symbol->string field-name)))
+ ;; field? -> is-field
+ (if (string-suffix? "?" str)
+ (string-append "is-" (string-drop-right str 1))
+ str)))
+
+(define (serialize-string field-name value)
+ #~(string-append #$(uglify-field-name field-name) " = " #$value "\n"))
+
+(define (serialize-integer field-name value)
+ (serialize-string field-name (number->string value)))
+
+(define (serialize-boolean field-name value)
+ (serialize-string field-name (if value "true" "false")))
+
+(define (serialize-contact-name field-name value)
+ #~(string-append "\n[" #$value "]\n"))
+
+(define (list-of-contact-configurations? lst)
+ (every contact-configuration? lst))
+
+(define (serialize-list-of-contact-configurations field-name value)
+ #~(string-append #$@@(map (cut serialize-configuration <>
+ contact-configuration-fields)
+ value)))
+
+(define (serialize-contacts-list-configuration configuration)
+ (mixed-text-file
+ "contactrc"
+ #~(string-append "[Owner]\n"
+ #$(serialize-configuration
+ configuration contacts-list-configuration-fields))))
+
+(define-maybe integer)
+(define-maybe string)
+
+(define-configuration contact-configuration
+ (name
+ (string)
+ "The name of the contact."
+ serialize-contact-name)
+ (phone-number
+ (maybe-integer 'disabled)
+ "The person's phone number.")
+ (email
+ (maybe-string 'disabled)
+ "The person's email address.")
+ (married?
+ (boolean)
+ "Whether the person is married."))
+
+(define-configuration contacts-list-configuration
+ (name
+ (string)
+ "The name of the owner of this contact list.")
+ (email
+ (string)
+ "The owner's email address.")
+ (contacts
+ (list-of-contact-configurations '())
+ "A list of @@code@{contact-configuation@} records which contain
+information about all your contacts."))
+@end lisp
+
+A contacts list configuration could then be created like this:
+
+@lisp
+(define my-contacts
+ (contacts-list-configuration
+ (name "Alice")
+ (email "alice@@example.org")
+ (contacts
+ (list (contact-configuration
+ (name "Bob")
+ (phone-number 1234)
+ (email "bob@@gnu.org")
+ (married? #f))
+ (contact-configuration
+ (name "Charlie")
+ (phone-number 0000)
+ (married? #t))))))
+@end lisp
+
+After serializing the configuration to disk, the resulting file would
+look like this:
+
+@example
+[owner]
+name = Alice
+email = alice@@example.org
+
+[Bob]
+phone-number = 1234
+email = bob@@gnu.org
+is-married = false
+
+[Charlie]
+phone-number = 0
+is-married = true
+@end example
+
+
@node Home Configuration
@chapter Home Configuration
@cindex home configuration
@@ -36598,7 +37454,7 @@ Service}; declare daemons by extending @ref{Shepherd Home Service}; add
commands, which will be invoked on by the Bash by extending
@ref{Shells Home Services, @code{home-bash-service-type}}.
-A good way to discover avaliable home services is using the
+A good way to discover available home services is using the
@command{guix home search} command (@pxref{Invoking guix home}). After
the required home services are found, include its module with the
@code{use-modules} form (@pxref{use-modules,, Using Guile Modules,
@@ -36686,7 +37542,7 @@ The service of this type will be instantiated by every home environment
automatically, there is no need to define it, but you may want to extend
it with a list of packages if you want to install additional packages
into your profile. Other services, which need to make some programs
-avaliable to the user will also extend this service type.
+available to the user will also extend this service type.
The extension value is just a list of packages:
@@ -36722,9 +37578,9 @@ redundant executions of the script if multiple login shells are spawned.
It can be extended with a gexp. However, to autostart an application,
users @emph{should not} use this service, in most cases it's better to extend
-@code{home-shpeherd-service-type} with a Shepherd service
+@code{home-shepherd-service-type} with a Shepherd service
(@pxref{Shepherd Services}), or extend the shell's startup file with
-required command using the appropriate service type.
+the required command using the appropriate service type.
@end defvr
@defvr {Scheme Variable} home-activation-service-type
@@ -36768,8 +37624,8 @@ Available @code{home-shell-profile-configuration} fields are:
@code{home-environment}, DO NOT create this service manually, it can
only be extended. @code{profile} is a list of file-like objects, which
will go to @file{~/.profile}. By default @file{~/.profile} contains the
-initialization code, which have to be evaluated by login shell to make
-home-environment's profile avaliable to the user, but other commands can
+initialization code which must be evaluated by the login shell to make
+home-environment's profile available to the user, but other commands can
be added to the file if it is really necessary. In most cases shell's
configuration files are preferred places for user's customizations.
Extend home-shell-profile service only if you really know what you do.
@@ -36962,9 +37818,15 @@ specifications,, mcron, GNU@tie{}mcron}).
@end deftp
@node Shepherd Home Service
-@subsection Managing User's Daemons
-
-@cindex shepherd services
+@subsection Managing User Daemons
+
+@cindex shepherd services, for users
+The @code{(gnu home services shepherd)} module supports the definitions
+of per-user Shepherd services (@pxref{Introduction,,, shepherd, The GNU
+Shepherd Manual}). You extend @code{home-shepherd-service-type} with
+new services; Guix Home then takes care of starting the @code{shepherd}
+daemon for you when you log in, which in turns starts the services you
+asked for.
@defvr {Scheme Variable} home-shepherd-service-type
The service type for the userland Shepherd, which allows one to manage
@@ -36975,10 +37837,10 @@ init process (PID 1), but almost all other information described in
This is the service type that extensions target when they want to create
shepherd services (@pxref{Service Types and Services}, for an example).
Each extension must pass a list of @code{<shepherd-service>}. Its
-value must be a @code{shepherd-configuration}, as described below.
+value must be a @code{home-shepherd-configuration}, as described below.
@end defvr
-@deftp {Data Type} shepherd-configuration
+@deftp {Data Type} home-shepherd-configuration
This data type represents the Shepherd's configuration.
@table @code
@@ -37024,51 +37886,34 @@ regular expressions, sorted by relevance:
@example
$ guix home search shell
name: home-shell-profile
-location: gnu/home/services/shells.scm:73:2
+location: gnu/home/services/shells.scm:100:2
extends: home-files
-description: Create `~/.profile', which is used for environment initialization
-+ of POSIX compatible login shells. Can be extended with a list of strings or
-+ gexps.
+description: Create `~/.profile', which is used for environment initialization of POSIX compliant login shells.
++ This service type can be extended with a list of file-like objects.
relevance: 6
-name: home-zsh-plugin-manager
-location: gnu/home/services/shellutils.scm:28:2
-extends: home-zsh home-profile
-description: Install plugins in profile and configure Zsh to load them.
-relevance: 1
-
-name: home-zsh-direnv
-location: gnu/home/services/shellutils.scm:69:2
-extends: home-profile home-zsh
-description: Enables `direnv' for `zsh'. Adds hook to `.zshrc' and installs a
-+ package in the profile.
-relevance: 1
-
-name: home-zsh-autosuggestions
-location: gnu/home/services/shellutils.scm:43:2
-extends: home-zsh-plugin-manager home-zsh
-description: Enables Fish-like fast/unobtrusive autosuggestions for `zsh' and
-+ sets reasonable default values for some plugin's variables to improve perfomance
-+ and adjust behavior: `(history completion)' is set for strategy, manual rebind
-+ and async are enabled.
-relevance: 1
+name: home-fish
+location: gnu/home/services/shells.scm:640:2
+extends: home-files home-profile
+description: Install and configure Fish, the friendly interactive shell.
+relevance: 3
name: home-zsh
-location: gnu/home/services/shells.scm:236:2
+location: gnu/home/services/shells.scm:290:2
extends: home-files home-profile
description: Install and configure Zsh.
relevance: 1
name: home-bash
-location: gnu/home/services/shells.scm:388:2
+location: gnu/home/services/shells.scm:508:2
extends: home-files home-profile
-description: Install and configure Bash.
+description: Install and configure GNU Bash.
relevance: 1
@dots{}
@end example
-As for @command{guix package --search}, the result is written in
+As for @command{guix search}, the result is written in
@code{recutils} format, which makes it easy to filter the output
(@pxref{Top, GNU recutils databases,, recutils, GNU recutils manual}).
@@ -37078,7 +37923,7 @@ Switching means that the activation script will be evaluated and (in
basic scenario) symlinks to configuration files generated from
@code{home-environment} declaration will be created in @file{~}. If the
file with the same path already exists in home folder it will be moved
-to @file{~/TIMESTAMP-guix-home-legacy-configs-backup}, where TIMESTAMP
+to @file{~/@var{timestamp}-guix-home-legacy-configs-backup}, where @var{timestamp}
is a current UNIX epoch time.
@quotation Note
@@ -37091,7 +37936,7 @@ This effects all the configuration specified in @var{file}. The command
starts Shepherd services specified in @var{file} that are not currently
running; if a service is currently running, this command will arrange
for it to be upgraded the next time it is stopped (e.g.@: by @code{herd
-stop X} or @code{herd restart X}).
+stop @var{service}} or @code{herd restart @var{service}}).
This command creates a new generation whose number is one greater than
the current generation (as reported by @command{guix home
diff --git a/doc/local.mk b/doc/local.mk
index 029232b7ac..9619971296 100644
--- a/doc/local.mk
+++ b/doc/local.mk
@@ -22,8 +22,8 @@
# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
# If adding a language, update the following variables, and info_TEXINFOS.
-MANUAL_LANGUAGES = de es fa fr it ko pt_BR ru sk zh_CN
-COOKBOOK_LANGUAGES = de es fa fr ko ru sk zh_Hans
+MANUAL_LANGUAGES = de es fa fi fr it ko pt_BR ru sk zh_CN
+COOKBOOK_LANGUAGES = de es fa fi fr ko ru sk zh_Hans
# Arg1: A list of languages codes.
# Arg2: The file name stem.
@@ -35,6 +35,7 @@ info_TEXINFOS = %D%/guix.texi \
%D%/guix.de.texi \
%D%/guix.es.texi \
%D%/guix.fa.texi \
+ %D%/guix.fi.texi \
%D%/guix.fr.texi \
%D%/guix.it.texi \
%D%/guix.ko.texi \
@@ -46,6 +47,7 @@ info_TEXINFOS = %D%/guix.texi \
%D%/guix-cookbook.de.texi \
%D%/guix-cookbook.es.texi \
%D%/guix-cookbook.fa.texi \
+ %D%/guix-cookbook.fi.texi \
%D%/guix-cookbook.fr.texi \
%D%/guix-cookbook.ko.texi \
%D%/guix-cookbook.ru.texi \