nls: Update 'de' translation.
[jackhill/guix/guix.git] / guix / self.scm
CommitLineData
eaae07ec
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (guix self)
20 #:use-module (guix config)
21 #:use-module (guix i18n)
22 #:use-module (guix modules)
23 #:use-module (guix gexp)
24 #:use-module (guix store)
25 #:use-module (guix monads)
26 #:use-module (guix discovery)
27 #:use-module (guix packages)
28 #:use-module (guix sets)
eaae07ec 29 #:use-module (guix modules)
45779fa6 30 #:use-module ((guix build utils) #:select (find-files))
eaae07ec
LC
31 #:use-module ((guix build compile) #:select (%lightweight-optimizations))
32 #:use-module (srfi srfi-1)
33 #:use-module (srfi srfi-9)
34 #:use-module (ice-9 match)
35 #:export (make-config.scm
8a0d9bc8 36 whole-package ;for internal use in 'guix pull'
eaae07ec
LC
37 compiled-guix
38 guix-derivation
39 reload-guix))
40
41\f
42;;;
43;;; Dependency handling.
44;;;
45
46(define* (false-if-wrong-guile package
47 #:optional (guile-version (effective-version)))
48 "Return #f if PACKAGE depends on the \"wrong\" major version of Guile (e.g.,
492.0 instead of 2.2), otherwise return PACKAGE."
50 (let ((guile (any (match-lambda
51 ((label (? package? dep) _ ...)
52 (and (string=? (package-name dep) "guile")
53 dep)))
54 (package-direct-inputs package))))
55 (and (or (not guile)
56 (string-prefix? guile-version
57 (package-version guile)))
58 package)))
59
60(define (package-for-guile guile-version . names)
61 "Return the package with one of the given NAMES that depends on
62GUILE-VERSION (\"2.0\" or \"2.2\"), or #f if none of the packages matches."
63 (let loop ((names names))
64 (match names
65 (()
66 #f)
67 ((name rest ...)
68 (match (specification->package name)
69 (#f
70 (loop rest))
71 ((? package? package)
a1639ae9 72 (or (false-if-wrong-guile package guile-version)
eaae07ec
LC
73 (loop rest))))))))
74
75(define specification->package
76 ;; Use our own variant of that procedure because that of (gnu packages)
77 ;; would traverse all the .scm files, which is wasteful.
78 (let ((ref (lambda (module variable)
79 (module-ref (resolve-interface module) variable))))
80 (match-lambda
81 ("guile" (ref '(gnu packages commencement) 'guile-final))
82 ("guile-json" (ref '(gnu packages guile) 'guile-json))
83 ("guile-ssh" (ref '(gnu packages ssh) 'guile-ssh))
84 ("guile-git" (ref '(gnu packages guile) 'guile-git))
d59e75f3 85 ("guile-sqlite3" (ref '(gnu packages guile) 'guile-sqlite3))
ca719424 86 ("guile-gcrypt" (ref '(gnu packages gnupg) 'guile-gcrypt))
108015df 87 ("gnutls" (ref '(gnu packages tls) 'gnutls))
eaae07ec
LC
88 ("zlib" (ref '(gnu packages compression) 'zlib))
89 ("gzip" (ref '(gnu packages compression) 'gzip))
90 ("bzip2" (ref '(gnu packages compression) 'bzip2))
91 ("xz" (ref '(gnu packages compression) 'xz))
e69dd844
LC
92 ("guile2.0-json" (ref '(gnu packages guile) 'guile2.0-json))
93 ("guile2.0-ssh" (ref '(gnu packages ssh) 'guile2.0-ssh))
94 ("guile2.0-git" (ref '(gnu packages guile) 'guile2.0-git))
d59e75f3 95 ;; XXX: No "guile2.0-sqlite3".
108015df 96 ("guile2.0-gnutls" (ref '(gnu packages tls) 'gnutls/guile-2.0))
e69dd844 97 (_ #f)))) ;no such package
eaae07ec
LC
98
99\f
100;;;
101;;; Derivations.
102;;;
103
104;; Node in a DAG of build tasks. Each node maps to a derivation, but it's
105;; easier to express things this way.
106(define-record-type <node>
107 (node name modules source dependencies compiled)
108 node?
109 (name node-name) ;string
110 (modules node-modules) ;list of module names
111 (source node-source) ;list of source files
112 (dependencies node-dependencies) ;list of nodes
113 (compiled node-compiled)) ;node -> lowerable object
114
f5db54ea
LC
115;; File mappings are essentially an alist as passed to 'imported-files'.
116(define-record-type <file-mapping>
117 (file-mapping name alist)
118 file-mapping?
119 (name file-mapping-name)
120 (alist file-mapping-alist))
121
122(define-gexp-compiler (file-mapping-compiler (mapping <file-mapping>)
123 system target)
124 ;; Here we use 'imported-files', which can arrange to directly import all
125 ;; the files instead of creating a derivation, when possible.
126 (imported-files (map (match-lambda
127 ((destination (? local-file? file))
128 (cons destination
129 (local-file-absolute-file-name file)))
130 ((destination source)
131 (cons destination source))) ;silliness
132 (file-mapping-alist mapping))
133 #:name (file-mapping-name mapping)
134 #:system system))
135
eaae07ec
LC
136(define (node-fold proc init nodes)
137 (let loop ((nodes nodes)
138 (visited (setq))
139 (result init))
140 (match nodes
141 (() result)
142 ((head tail ...)
143 (if (set-contains? visited head)
144 (loop tail visited result)
145 (loop tail (set-insert head visited)
146 (proc head result)))))))
147
148(define (node-modules/recursive nodes)
149 (node-fold (lambda (node modules)
150 (append (node-modules node) modules))
151 '()
152 nodes))
153
154(define* (closure modules #:optional (except '()))
155 (source-module-closure modules
156 #:select?
157 (match-lambda
158 (('guix 'config)
159 #f)
160 ((and module
161 (or ('guix _ ...) ('gnu _ ...)))
162 (not (member module except)))
163 (rest #f))))
164
165(define module->import
166 ;; Return a file-name/file-like object pair for the specified module and
167 ;; suitable for 'imported-files'.
168 (match-lambda
169 ((module '=> thing)
170 (let ((file (module-name->file-name module)))
171 (list file thing)))
172 (module
173 (let ((file (module-name->file-name module)))
174 (list file
175 (local-file (search-path %load-path file)))))))
176
177(define* (scheme-node name modules #:optional (dependencies '())
178 #:key (extra-modules '()) (extra-files '())
179 (extensions '())
180 parallel? guile-for-build)
181 "Return a node that builds the given Scheme MODULES, and depends on
182DEPENDENCIES (a list of nodes). EXTRA-MODULES is a list of additional modules
183added to the source, and EXTRA-FILES is a list of additional files.
184EXTENSIONS is a set of full-blown Guile packages (e.g., 'guile-json') that
185must be present in the search path."
186 (let* ((modules (append extra-modules
187 (closure modules
188 (node-modules/recursive dependencies))))
189 (module-files (map module->import modules))
f5db54ea
LC
190 (source (file-mapping (string-append name "-source")
191 (append module-files extra-files))))
eaae07ec 192 (node name modules source dependencies
8031b3fa
LC
193 (compiled-modules name source
194 (map car module-files)
eaae07ec
LC
195 (map node-source dependencies)
196 (map node-compiled dependencies)
197 #:extensions extensions
198 #:parallel? parallel?
199 #:guile-for-build guile-for-build))))
200
201(define (file-imports directory sub-directory pred)
202 "List all the files matching PRED under DIRECTORY/SUB-DIRECTORY. Return a
203list of file-name/file-like objects suitable as inputs to 'imported-files'."
204 (map (lambda (file)
205 (list (string-drop file (+ 1 (string-length directory)))
206 (local-file file #:recursive? #t)))
207 (find-files (string-append directory "/" sub-directory) pred)))
208
6cf502d1
LC
209(define* (file-append* item file #:key (recursive? #t))
210 "Return FILE within ITEM, which may be a file name or a file-like object.
211When ITEM is a plain file name (a string), simply return a 'local-file'
212record with the new file name."
9f1c3559
LC
213 (match item
214 ((? string?)
215 ;; This is the optimal case: we return a new "source". Thus, a
216 ;; derivation that depends on this sub-directory does not depend on ITEM
217 ;; itself.
6cf502d1
LC
218 (local-file (string-append item "/" file)
219 #:recursive? recursive?))
9f1c3559
LC
220 ;; TODO: Add 'local-file?' case.
221 (_
222 ;; In this case, anything that refers to the result also depends on ITEM,
223 ;; which isn't great.
6cf502d1 224 (file-append item "/" file))))
9f1c3559
LC
225
226(define* (locale-data source domain
227 #:optional (directory domain))
228 "Return the locale data from 'po/DIRECTORY' in SOURCE, corresponding to
229DOMAIN, a gettext domain."
230 (define gettext
231 (module-ref (resolve-interface '(gnu packages gettext))
232 'gettext-minimal))
233
234 (define build
235 (with-imported-modules '((guix build utils))
236 #~(begin
237 (use-modules (guix build utils)
238 (srfi srfi-26)
239 (ice-9 match) (ice-9 ftw))
240
241 (define po-directory
6cf502d1 242 #+(file-append* source (string-append "po/" directory)))
9f1c3559
LC
243
244 (define (compile language)
245 (let ((gmo (string-append #$output "/" language "/LC_MESSAGES/"
246 #$domain ".mo")))
247 (mkdir-p (dirname gmo))
248 (invoke #+(file-append gettext "/bin/msgfmt")
249 "-c" "--statistics" "--verbose"
250 "-o" gmo
251 (string-append po-directory "/" language ".po"))))
252
253 (define (linguas)
254 ;; Return the list of languages. Note: don't read 'LINGUAS'
255 ;; because it contains things like 'en@boldquot' that do not have
256 ;; a corresponding .po file.
257 (map (cut basename <> ".po")
258 (scandir po-directory
259 (cut string-suffix? ".po" <>))))
260
261 (for-each compile (linguas)))))
262
263 (computed-file (string-append "guix-locale-" domain)
264 build))
265
4554d4c8
LC
266(define (info-manual source)
267 "Return the Info manual built from SOURCE."
268 (define texinfo
269 (module-ref (resolve-interface '(gnu packages texinfo))
270 'texinfo))
271
272 (define graphviz
273 (module-ref (resolve-interface '(gnu packages graphviz))
274 'graphviz))
275
276 (define documentation
6cf502d1 277 (file-append* source "doc"))
4554d4c8
LC
278
279 (define examples
6cf502d1 280 (file-append* source "gnu/system/examples"))
4554d4c8
LC
281
282 (define build
283 (with-imported-modules '((guix build utils))
284 #~(begin
285 (use-modules (guix build utils))
286
287 (mkdir #$output)
288
289 ;; Create 'version.texi'.
290 ;; XXX: Can we use a more meaningful version string yet one that
291 ;; doesn't change at each commit?
292 (call-with-output-file "version.texi"
293 (lambda (port)
cbe7387c 294 (let ((version "0.0-git"))
4554d4c8
LC
295 (format port "
296@set UPDATED 1 January 1970
297@set UPDATED-MONTH January 1970
298@set EDITION ~a
299@set VERSION ~a\n" version version))))
300
301 ;; Copy configuration templates that the manual includes.
302 (for-each (lambda (template)
303 (copy-file template
304 (string-append
305 "os-config-"
306 (basename template ".tmpl")
307 ".texi")))
308 (find-files #$examples "\\.tmpl$"))
309
310 ;; Build graphs.
311 (mkdir-p (string-append #$output "/images"))
312 (for-each (lambda (dot-file)
313 (invoke #+(file-append graphviz "/bin/dot")
314 "-Tpng" "-Gratio=.9" "-Gnodesep=.005"
315 "-Granksep=.00005" "-Nfontsize=9"
316 "-Nheight=.1" "-Nwidth=.1"
317 "-o" (string-append #$output "/images/"
318 (basename dot-file ".dot")
319 ".png")
320 dot-file))
321 (find-files (string-append #$documentation "/images")
322 "\\.dot$"))
323
324 ;; Copy other PNGs.
325 (for-each (lambda (png-file)
326 (install-file png-file
327 (string-append #$output "/images")))
328 (find-files (string-append #$documentation "/images")
329 "\\.png$"))
330
331 ;; Finally build the manual. Copy it the Texinfo files to $PWD and
332 ;; add a symlink to the 'images' directory so that 'makeinfo' can
333 ;; see those images and produce image references in the Info output.
334 (copy-recursively #$documentation "."
335 #:log (%make-void-port "w"))
336 (delete-file-recursively "images")
337 (symlink (string-append #$output "/images") "images")
338
339 (for-each (lambda (texi)
340 (unless (string=? "guix.texi" texi)
341 ;; Create 'version-LL.texi'.
342 (let* ((base (basename texi ".texi"))
343 (dot (string-index base #\.))
344 (tag (string-drop base (+ 1 dot))))
345 (symlink "version.texi"
346 (string-append "version-" tag ".texi"))))
347
348 (invoke #+(file-append texinfo "/bin/makeinfo")
349 texi "-I" #$documentation
350 "-I" "."
351 "-o" (string-append #$output "/"
352 (basename texi ".texi")
353 ".info")))
354 (cons "guix.texi"
355 (find-files "." "^guix\\.[a-z]{2}\\.texi$"))))))
356
357 (computed-file "guix-manual" build))
358
a89faa3f
LC
359(define* (guix-command modules #:optional compiled-modules
360 #:key source (dependencies '())
8970a886 361 guile (guile-version (effective-version)))
8a0d9bc8
LC
362 "Return the 'guix' command such that it adds MODULES and DEPENDENCIES in its
363load path."
f2d0a2cf
LC
364 (define source-directories
365 (map (lambda (package)
366 (file-append package "/share/guile/site/"
367 guile-version))
368 dependencies))
369
370 (define object-directories
371 (map (lambda (package)
372 (file-append package "/lib/guile/"
373 guile-version "/site-ccache"))
374 dependencies))
375
8a0d9bc8
LC
376 (program-file "guix-command"
377 #~(begin
378 (set! %load-path
f2d0a2cf 379 (append (filter file-exists? '#$source-directories)
8a0d9bc8
LC
380 %load-path))
381
382 (set! %load-compiled-path
f2d0a2cf 383 (append (filter file-exists? '#$object-directories)
8a0d9bc8
LC
384 %load-compiled-path))
385
386 (set! %load-path (cons #$modules %load-path))
387 (set! %load-compiled-path
a89faa3f
LC
388 (cons (or #$compiled-modules #$modules)
389 %load-compiled-path))
8a0d9bc8
LC
390
391 (let ((guix-main (module-ref (resolve-interface '(guix ui))
392 'guix-main)))
9f1c3559
LC
393 #$(if source
394 #~(begin
395 (bindtextdomain "guix"
396 #$(locale-data source "guix"))
397 (bindtextdomain "guix-packages"
398 #$(locale-data source
399 "guix-packages"
400 "packages")))
401 #t)
8a0d9bc8
LC
402
403 ;; XXX: It would be more convenient to change it to:
404 ;; (exit (apply guix-main (command-line)))
8970a886
LC
405 (apply guix-main (command-line))))
406 #:guile guile))
8a0d9bc8
LC
407
408(define* (whole-package name modules dependencies
9f1c3559
LC
409 #:key
410 (guile-version (effective-version))
a89faa3f 411 compiled-modules
8d3beb3a
LC
412 info daemon substitute-keys
413 guile
9f1c3559
LC
414 (command (guix-command modules
415 #:dependencies dependencies
8970a886 416 #:guile guile
9f1c3559 417 #:guile-version guile-version)))
8a0d9bc8 418 "Return the whole Guix package NAME that uses MODULES, a derivation of all
9f1c3559 419the modules, and DEPENDENCIES, a list of packages depended on. COMMAND is the
a89faa3f
LC
420'guix' program to use; INFO is the Info manual. When COMPILED-MODULES is
421true, it is linked as 'lib/guile/X.Y/site-ccache'; otherwise, .go files are
422assumed to be part of MODULES."
9f1c3559
LC
423 (computed-file name
424 (with-imported-modules '((guix build utils))
425 #~(begin
426 (use-modules (guix build utils))
427 (mkdir-p (string-append #$output "/bin"))
428 (symlink #$command
429 (string-append #$output "/bin/guix"))
430
baed9236
LC
431 (when #$daemon
432 (symlink (string-append #$daemon "/bin/guix-daemon")
433 (string-append #$output "/bin/guix-daemon")))
434
8d3beb3a
LC
435 (when #$substitute-keys
436 (mkdir-p (string-append #$output "/share/guix"))
437 (copy-recursively #$substitute-keys
438 (string-append #$output
439 "/share/guix")
440 #:log (%make-void-port "w")))
441
9f1c3559
LC
442 (let ((modules (string-append #$output
443 "/share/guile/site/"
4554d4c8
LC
444 (effective-version)))
445 (info #$info))
9f1c3559 446 (mkdir-p (dirname modules))
4554d4c8
LC
447 (symlink #$modules modules)
448 (when info
449 (symlink #$info
450 (string-append #$output
a89faa3f
LC
451 "/share/info"))))
452
453 ;; Object files.
454 (when #$compiled-modules
455 (let ((modules (string-append #$output "/lib/guile/"
456 (effective-version)
457 "/site-ccache")))
458 (mkdir-p (dirname modules))
459 (symlink #$compiled-modules modules)))))))
8a0d9bc8 460
eaae07ec 461(define* (compiled-guix source #:key (version %guix-version)
8a0d9bc8 462 (pull-version 1)
eaae07ec
LC
463 (name (string-append "guix-" version))
464 (guile-version (effective-version))
465 (guile-for-build (guile-for-build guile-version))
eaae07ec
LC
466 (zlib (specification->package "zlib"))
467 (gzip (specification->package "gzip"))
468 (bzip2 (specification->package "bzip2"))
469 (xz (specification->package "xz"))
470 (guix (specification->package "guix")))
471 "Return a file-like object that contains a compiled Guix."
472 (define guile-json
473 (package-for-guile guile-version
474 "guile-json"
eaae07ec
LC
475 "guile2.0-json"))
476
477 (define guile-ssh
478 (package-for-guile guile-version
479 "guile-ssh"
eaae07ec
LC
480 "guile2.0-ssh"))
481
482 (define guile-git
483 (package-for-guile guile-version
484 "guile-git"
485 "guile2.0-git"))
486
d59e75f3
LC
487 (define guile-sqlite3
488 (package-for-guile guile-version
489 "guile-sqlite3"
490 "guile2.0-sqlite3"))
491
ca719424
LC
492 (define guile-gcrypt
493 (package-for-guile guile-version
494 "guile-gcrypt"))
495
108015df
LC
496 (define gnutls
497 (package-for-guile guile-version
498 "gnutls" "guile2.0-gnutls"))
499
eaae07ec
LC
500 (define dependencies
501 (match (append-map (lambda (package)
502 (cons (list "x" package)
e13240f5 503 (package-transitive-propagated-inputs package)))
ca719424 504 (list guile-gcrypt gnutls guile-git guile-json
108015df 505 guile-ssh guile-sqlite3))
eaae07ec
LC
506 (((labels packages _ ...) ...)
507 packages)))
508
509 (define *core-modules*
510 (scheme-node "guix-core"
511 '((guix)
512 (guix monad-repl)
513 (guix packages)
514 (guix download)
515 (guix discovery)
516 (guix profiles)
517 (guix build-system gnu)
518 (guix build-system trivial)
519 (guix build profiles)
520 (guix build gnu-build-system))
521
522 ;; Provide a dummy (guix config) with the default version
523 ;; number, storedir, etc. This is so that "guix-core" is the
524 ;; same across all installations and doesn't need to be
525 ;; rebuilt when the version changes, which in turn means we
526 ;; can have substitutes for it.
527 #:extra-modules
ca719424 528 `(((guix config) => ,(make-config.scm)))
eaae07ec 529
8292f5a9
LC
530 ;; (guix man-db) is needed at build-time by (guix profiles)
531 ;; but we don't need to compile it; not compiling it allows
532 ;; us to avoid an extra dependency on guile-gdbm-ffi.
533 #:extra-files
3931c761
LC
534 `(("guix/man-db.scm" ,(local-file "../guix/man-db.scm"))
535 ("guix/store/schema.sql"
536 ,(local-file "../guix/store/schema.sql")))
8292f5a9 537
ca719424 538 #:extensions (list guile-gcrypt)
eaae07ec
LC
539 #:guile-for-build guile-for-build))
540
541 (define *extra-modules*
542 (scheme-node "guix-extra"
543 (filter-map (match-lambda
544 (('guix 'scripts _ ..1) #f)
8292f5a9 545 (('guix 'man-db) #f)
eaae07ec
LC
546 (name name))
547 (scheme-modules* source "guix"))
548 (list *core-modules*)
549 #:extensions dependencies
550 #:guile-for-build guile-for-build))
551
f2e66663
LC
552 (define *core-package-modules*
553 (scheme-node "guix-packages-base"
eaae07ec 554 `((gnu packages)
f2e66663 555 (gnu packages base))
eaae07ec
LC
556 (list *core-modules* *extra-modules*)
557 #:extensions dependencies
f2e66663
LC
558
559 ;; Add all the non-Scheme files here. We must do it here so
560 ;; that 'search-patches' & co. can find them. Ideally we'd
561 ;; keep them next to the .scm files that use them but it's
562 ;; difficult to do (XXX).
563 #:extra-files
eaae07ec
LC
564 (file-imports source "gnu/packages"
565 (lambda (file stat)
566 (and (eq? 'regular (stat:type stat))
567 (not (string-suffix? ".scm" file))
568 (not (string-suffix? ".go" file))
569 (not (string-prefix? ".#" file))
570 (not (string-suffix? "~" file)))))
571 #:guile-for-build guile-for-build))
572
f2e66663
LC
573 (define *package-modules*
574 (scheme-node "guix-packages"
575 (scheme-modules* source "gnu/packages")
576 (list *core-modules* *extra-modules* *core-package-modules*)
577 #:extensions dependencies
578 #:guile-for-build guile-for-build))
579
eaae07ec
LC
580 (define *system-modules*
581 (scheme-node "guix-system"
582 `((gnu system)
583 (gnu services)
584 ,@(scheme-modules* source "gnu/system")
585 ,@(scheme-modules* source "gnu/services"))
f2e66663
LC
586 (list *core-package-modules* *package-modules*
587 *extra-modules* *core-modules*)
eaae07ec
LC
588 #:extensions dependencies
589 #:extra-files
1458f768
LC
590 (append (file-imports source "gnu/system/examples"
591 (const #t))
592
593 ;; Build-side code that we don't build. Some of
594 ;; these depend on guile-rsvg, the Shepherd, etc.
595 (file-imports source "gnu/build" (const #t)))
eaae07ec
LC
596 #:guile-for-build
597 guile-for-build))
598
599 (define *cli-modules*
600 (scheme-node "guix-cli"
601 (scheme-modules* source "/guix/scripts")
f2e66663
LC
602 (list *core-modules* *extra-modules*
603 *core-package-modules* *package-modules*
eaae07ec
LC
604 *system-modules*)
605 #:extensions dependencies
606 #:guile-for-build guile-for-build))
607
608 (define *config*
609 (scheme-node "guix-config"
610 '()
611 #:extra-modules
612 `(((guix config)
ca719424 613 => ,(make-config.scm #:zlib zlib
eaae07ec
LC
614 #:gzip gzip
615 #:bzip2 bzip2
616 #:xz xz
eaae07ec
LC
617 #:package-name
618 %guix-package-name
619 #:package-version
620 version
621 #:bug-report-address
622 %guix-bug-report-address
623 #:home-page-url
624 %guix-home-page-url)))
625 #:guile-for-build guile-for-build))
626
a89faa3f 627 (define (built-modules node-subset)
8a0d9bc8 628 (directory-union (string-append name "-modules")
a89faa3f 629 (append-map node-subset
8a0d9bc8
LC
630
631 ;; Note: *CONFIG* comes first so that it
632 ;; overrides the (guix config) module that
633 ;; comes with *CORE-MODULES*.
634 (list *config*
635 *cli-modules*
636 *system-modules*
637 *package-modules*
638 *core-package-modules*
639 *extra-modules*
640 *core-modules*))
641
642 ;; Silently choose the first entry upon collision so that
643 ;; we choose *CONFIG*.
644 #:resolve-collision 'first
645
646 ;; When we do (add-to-store "utils.scm"), "utils.scm" must
647 ;; be a regular file, not a symlink. Thus, arrange so that
648 ;; regular files appear as regular files in the final
649 ;; output.
650 #:copy? #t
651 #:quiet? #t))
652
653 ;; Version 0 of 'guix pull' meant we'd just return Scheme modules.
654 ;; Version 1 is when we return the full package.
655 (cond ((= 1 pull-version)
656 ;; The whole package, with a standard file hierarchy.
a89faa3f
LC
657 (let* ((modules (built-modules (compose list node-source)))
658 (compiled (built-modules (compose list node-compiled)))
659 (command (guix-command modules compiled
660 #:source source
661 #:dependencies dependencies
8970a886 662 #:guile guile-for-build
a89faa3f
LC
663 #:guile-version guile-version)))
664 (whole-package name modules dependencies
665 #:compiled-modules compiled
9f1c3559 666 #:command command
8970a886 667 #:guile guile-for-build
baed9236
LC
668
669 ;; Include 'guix-daemon'. XXX: Here we inject an
670 ;; older snapshot of guix-daemon, but that's a good
671 ;; enough approximation for now.
672 #:daemon (module-ref (resolve-interface
673 '(gnu packages
674 package-management))
675 'guix-daemon)
676
4554d4c8 677 #:info (info-manual source)
6cf502d1
LC
678 #:substitute-keys (file-append* source
679 "etc/substitutes")
9f1c3559 680 #:guile-version guile-version)))
8a0d9bc8 681 ((= 0 pull-version)
a89faa3f
LC
682 ;; Legacy 'guix pull': return the .scm and .go files as one
683 ;; directory.
684 (built-modules (lambda (node)
685 (list (node-source node)
686 (node-compiled node)))))
8a0d9bc8
LC
687 (else
688 ;; Unsupported 'guix pull' version.
689 #f)))
eaae07ec
LC
690
691\f
692;;;
693;;; Generating (guix config).
694;;;
695
696(define %dependency-variables
697 ;; (guix config) variables corresponding to dependencies.
ca719424 698 '(%libz %xz %gzip %bzip2))
eaae07ec
LC
699
700(define %persona-variables
701 ;; (guix config) variables that define Guix's persona.
702 '(%guix-package-name
703 %guix-version
704 %guix-bug-report-address
705 %guix-home-page-url))
706
707(define %config-variables
45779fa6
LC
708 ;; (guix config) variables corresponding to Guix configuration.
709 (letrec-syntax ((variables (syntax-rules ()
710 ((_)
711 '())
712 ((_ variable rest ...)
713 (cons `(variable . ,variable)
714 (variables rest ...))))))
7af5c2a2 715 (variables %localstatedir %storedir %sysconfdir %system)))
eaae07ec 716
ca719424 717(define* (make-config.scm #:key zlib gzip xz bzip2
eaae07ec
LC
718 (package-name "GNU Guix")
719 (package-version "0")
720 (bug-report-address "bug-guix@gnu.org")
721 (home-page-url "https://gnu.org/s/guix"))
722
723 ;; Hack so that Geiser is not confused.
724 (define defmod 'define-module)
725
726 (scheme-file "config.scm"
eb72cdf0 727 #~(;; The following expressions get spliced.
eaae07ec
LC
728 (#$defmod (guix config)
729 #:export (%guix-package-name
730 %guix-version
731 %guix-bug-report-address
732 %guix-home-page-url
7af5c2a2
LC
733 %store-directory
734 %state-directory
735 %store-database-directory
736 %config-directory
eaae07ec
LC
737 %libz
738 %gzip
739 %bzip2
e8cb9c01 740 %xz))
eaae07ec 741
63cab418
LC
742 #$@(map (match-lambda
743 ((name . value)
744 #~(define-public #$name #$value)))
745 %config-variables)
746
7af5c2a2
LC
747 (define %store-directory
748 (or (and=> (getenv "NIX_STORE_DIR") canonicalize-path)
749 %storedir))
750
751 (define %state-directory
752 ;; This must match `NIX_STATE_DIR' as defined in
753 ;; `nix/local.mk'.
754 (or (getenv "NIX_STATE_DIR")
755 (string-append %localstatedir "/guix")))
756
757 (define %store-database-directory
758 (or (getenv "NIX_DB_DIR")
759 (string-append %state-directory "/db")))
760
761 (define %config-directory
762 ;; This must match `GUIX_CONFIGURATION_DIRECTORY' as
763 ;; defined in `nix/local.mk'.
764 (or (getenv "GUIX_CONFIGURATION_DIRECTORY")
765 (string-append %sysconfdir "/guix")))
766
63cab418
LC
767 (define %guix-package-name #$package-name)
768 (define %guix-version #$package-version)
769 (define %guix-bug-report-address #$bug-report-address)
770 (define %guix-home-page-url #$home-page-url)
771
63cab418
LC
772 (define %gzip
773 #+(and gzip (file-append gzip "/bin/gzip")))
774 (define %bzip2
775 #+(and bzip2 (file-append bzip2 "/bin/bzip2")))
776 (define %xz
777 #+(and xz (file-append xz "/bin/xz")))
778
63cab418
LC
779 (define %libz
780 #+(and zlib
e8cb9c01 781 (file-append zlib "/lib/libz"))))
eb72cdf0
LC
782
783 ;; Guile 2.0 *requires* the 'define-module' to be at the
e8cb9c01 784 ;; top-level or the 'toplevel-ref' in the resulting .go file are
eb72cdf0
LC
785 ;; made relative to a nonexistent anonymous module.
786 #:splice? #t))
eaae07ec
LC
787
788
789\f
790;;;
791;;; Building.
792;;;
793
8031b3fa 794(define* (compiled-modules name module-tree module-files
eaae07ec
LC
795 #:optional
796 (dependencies '())
797 (dependencies-compiled '())
798 #:key
799 (extensions '()) ;full-blown Guile packages
800 parallel?
801 guile-for-build)
8031b3fa
LC
802 "Build all the MODULE-FILES from MODULE-TREE. MODULE-FILES must be a list
803like '(\"guix/foo.scm\" \"gnu/bar.scm\") and MODULE-TREE is the directory
804containing MODULE-FILES and possibly other files as well."
eaae07ec
LC
805 ;; This is a non-monadic, enhanced version of 'compiled-file' from (guix
806 ;; gexp).
807 (define build
808 (with-imported-modules (source-module-closure
809 '((guix build compile)
810 (guix build utils)))
811 #~(begin
812 (use-modules (srfi srfi-26)
813 (ice-9 match)
814 (ice-9 format)
815 (ice-9 threads)
816 (guix build compile)
817 (guix build utils))
818
819 (define (regular? file)
820 (not (member file '("." ".."))))
821
822 (define (report-load file total completed)
823 (display #\cr)
824 (format #t
825 "loading...\t~5,1f% of ~d files" ;FIXME: i18n
826 (* 100. (/ completed total)) total)
827 (force-output))
828
829 (define (report-compilation file total completed)
830 (display #\cr)
831 (format #t "compiling...\t~5,1f% of ~d files" ;FIXME: i18n
832 (* 100. (/ completed total)) total)
833 (force-output))
834
8031b3fa
LC
835 (define (process-directory directory files output)
836 ;; Hide compilation warnings.
837 (parameterize ((current-warning-port (%make-void-port "w")))
838 (compile-files directory #$output files
839 #:workers (parallel-job-count)
840 #:report-load report-load
841 #:report-compilation report-compilation)))
eaae07ec
LC
842
843 (setvbuf (current-output-port) _IONBF)
844 (setvbuf (current-error-port) _IONBF)
845
846 (set! %load-path (cons #+module-tree %load-path))
847 (set! %load-path
848 (append '#+dependencies
849 (map (lambda (extension)
850 (string-append extension "/share/guile/site/"
851 (effective-version)))
852 '#+extensions)
853 %load-path))
854
855 (set! %load-compiled-path
856 (append '#+dependencies-compiled
857 (map (lambda (extension)
858 (string-append extension "/lib/guile/"
859 (effective-version)
860 "/site-ccache"))
861 '#+extensions)
862 %load-compiled-path))
863
864 ;; Load the compiler modules upfront.
865 (compile #f)
866
867 (mkdir #$output)
868 (chdir #+module-tree)
8031b3fa 869 (process-directory "." '#+module-files #$output)
69447b63 870 (newline))))
eaae07ec
LC
871
872 (computed-file name build
873 #:guile guile-for-build
874 #:options
875 `(#:local-build? #f ;allow substitutes
876
877 ;; Don't annoy people about _IONBF deprecation.
54be2b4d
LC
878 ;; Initialize 'terminal-width' in (system repl debug)
879 ;; to a large-enough value to make backtrace more
880 ;; verbose.
881 #:env-vars (("GUILE_WARN_DEPRECATED" . "no")
882 ("COLUMNS" . "200")))))
eaae07ec
LC
883
884\f
885;;;
886;;; Building.
887;;;
888
889(define (guile-for-build version)
890 "Return a derivation for Guile 2.0 or 2.2, whichever matches the currently
891running Guile."
892 (define canonical-package ;soft reference
893 (module-ref (resolve-interface '(gnu packages base))
894 'canonical-package))
895
896 (match version
897 ("2.2.2"
898 ;; Gross hack to avoid ABI incompatibilities (see
899 ;; <https://bugs.gnu.org/29570>.)
900 (module-ref (resolve-interface '(gnu packages guile))
901 'guile-2.2.2))
902 ("2.2"
084f64cb
LC
903 ;; Use the latest version, which has fixes for
904 ;; <https://bugs.gnu.org/30602> and VM stack-marking issues.
eaae07ec 905 (canonical-package (module-ref (resolve-interface '(gnu packages guile))
084f64cb 906 'guile-2.2.4)))
eaae07ec 907 ("2.0"
e69dd844
LC
908 (module-ref (resolve-interface '(gnu packages guile))
909 'guile-2.0))))
eaae07ec
LC
910
911(define* (guix-derivation source version
8a0d9bc8
LC
912 #:optional (guile-version (effective-version))
913 #:key (pull-version 0))
eaae07ec 914 "Return, as a monadic value, the derivation to build the Guix from SOURCE
8a0d9bc8
LC
915for GUILE-VERSION. Use VERSION as the version string. PULL-VERSION specifies
916the version of the 'guix pull' protocol. Return #f if this PULL-VERSION value
917is not supported."
eaae07ec
LC
918 (define (shorten version)
919 (if (and (string-every char-set:hex-digit version)
920 (> (string-length version) 9))
921 (string-take version 9) ;Git commit
922 version))
923
924 (define guile
099bb017
LC
925 ;; When PULL-VERSION >= 1, produce a self-contained Guix and use Guile 2.2
926 ;; unconditionally.
927 (guile-for-build (if (>= pull-version 1)
928 "2.2"
929 guile-version)))
eaae07ec
LC
930
931 (mbegin %store-monad
932 (set-guile-for-build guile)
8a0d9bc8
LC
933 (let ((guix (compiled-guix source
934 #:version version
935 #:name (string-append "guix-"
936 (shorten version))
937 #:pull-version pull-version
099bb017
LC
938 #:guile-version (if (>= pull-version 1)
939 "2.2"
940 (match guile-version
941 ("2.2.2" "2.2")
942 (version version)))
8a0d9bc8
LC
943 #:guile-for-build guile)))
944 (if guix
945 (lower-object guix)
946 (return #f)))))