1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
| | ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (build-self)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-19)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
#:use-module (system base compile)
#:export (build))
;;; Commentary:
;;;
;;; When loaded, this module returns a monadic procedure of at least one
;;; argument: the source tree to build. It returns a derivation that
;;; builds it.
;;;
;;; Code:
;; Use our very own Guix modules.
(eval-when (compile load eval)
(and=> (assoc-ref (current-source-location) 'filename)
(lambda (file)
(let ((dir (string-append (dirname file) "/..")))
(set! %load-path (cons dir %load-path))))))
(define (date-version-string)
"Return the current date and hour in UTC timezone, for use as a poor
person's version identifier."
;; XXX: Last resort when the Git commit id is missing.
(date->string (current-date 0) "~Y~m~d.~H"))
(define-syntax parameterize*
(syntax-rules ()
"Like 'parameterize' but for regular variables (!)."
((_ ((var value) rest ...) body ...)
(let ((old var)
(new value))
(dynamic-wind
(lambda ()
(set! var new))
(lambda ()
(parameterize* (rest ...) body ...))
(lambda ()
(set! var old)))))
((_ () body ...)
(begin body ...))))
(define (pure-load-compiled-path)
"Return %LOAD-COMPILED-PATH minus the directories containing .go files from
Guix."
(define (purify path)
(fold-right delete path
(filter-map (lambda (file)
(and=> (search-path path file) dirname))
'("guix.go" "gnu.go"))))
(let loop ((path %load-compiled-path))
(let ((next (purify path)))
(if (equal? next path)
path
(loop next)))))
;; The procedure below is our return value.
(define* (build source
#:key verbose? (version (date-version-string))
#:allow-other-keys
#:rest rest)
"Return a derivation that unpacks SOURCE into STORE and compiles Scheme
files."
;; Pre-load the compiler modules so we don't end up rebuilding them due to
;; %FRESH-AUTO-COMPILE.
(compile #t)
;; Start by jumping into the target Guix so that we have access to the
;; latest packages and APIs.
;;
;; Our checkout in the store has mtime set to the epoch, and thus .go
;; files look newer, even though they may not correspond.
(parameterize* ((%load-should-auto-compile #t)
(%fresh-auto-compile #t)
;; Work around <https://bugs.gnu.org/29226>.
(%load-compiled-path (pure-load-compiled-path)))
;; Hide auto-compilation messages.
(parameterize ((current-warning-port (%make-void-port "w")))
(let ((reload-guix (module-ref (resolve-interface '(guix self))
'reload-guix)))
(reload-guix))) ;cross fingers!
(let ((guix-derivation (module-ref (resolve-interface '(guix self))
'guix-derivation)))
(guix-derivation source version))))
;; This file is loaded by 'guix pull'; return it the build procedure.
build
;;; build-self.scm ends here
|