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