guix package: Support package transformation options.
[jackhill/guix/guix.git] / build-aux / compile-all.scm
CommitLineData
de6af327
TUBK
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
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(use-modules (system base target)
20 (ice-9 match)
21 (ice-9 threads)
22 (guix build utils))
23
24(define compile-options '(format unbound-variable arity-mismatch))
25
26(define host (getenv "host"))
27
28(define srcdir (getenv "srcdir"))
29
30(define (relative-file file)
31 (if (string-prefix? (string-append srcdir "/") file)
32 (string-drop file (+ 1 (string-length srcdir)))
33 file))
34
35(define (file-mtime<? f1 f2)
36 (< (stat:mtime (stat f1))
37 (stat:mtime (stat f2))))
38
39(define (scm->go file)
40 (let* ((relative (relative-file file))
41 (without-extension (string-drop-right relative 4)))
42 (string-append without-extension ".go")))
43
44(define (file-needs-compilation? file)
45 (let ((go (scm->go file)))
46 (or (not (file-exists? go))
47 (file-mtime<? go file))))
48
49(define (file->module file)
50 (let* ((relative (relative-file file))
51 (module-path (string-drop-right relative 4)))
52 (map string->symbol
53 (string-split module-path #\/))))
54
55;;; To work around <http://bugs.gnu.org/15602> (FIXME), we want to load all
56;;; files to be compiled first. We do this via resolve-interface so that the
57;;; top-level of each file (module) is only executed once.
58(define (load-module-file file)
59 (let ((module (file->module file)))
60 (format #t " LOAD ~a~%" module)
61 (resolve-interface module)))
62
63(define (compile-file* file output-mutex)
64 (let ((go (scm->go file)))
65 (with-mutex output-mutex
66 (format #t " GUILEC ~a~%" go)
67 (force-output))
68 (mkdir-p (dirname go))
69 (with-target host
70 (lambda ()
71 (compile-file file
72 #:output-file go
73 #:opts compile-options)))))
74
75(match (command-line)
76 ((_ . files)
77 (let ((files (filter file-needs-compilation? files)))
78 (for-each load-module-file files)
79 (let ((mutex (make-mutex)))
80 (par-for-each (lambda (file)
81 (compile-file* file mutex))
82 files)))))