build-system/haskell: Support parallel builds.
[jackhill/guix/guix.git] / guix / build-system / haskell.scm
CommitLineData
14dfdf2e
FB
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
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 build-system haskell)
20 #:use-module (guix store)
21 #:use-module (guix utils)
22 #:use-module (guix packages)
23 #:use-module (guix derivations)
bb6419f3 24 #:use-module (guix download)
e89431bf 25 #:use-module (guix search-paths)
14dfdf2e
FB
26 #:use-module (guix build-system)
27 #:use-module (guix build-system gnu)
28 #:use-module (ice-9 match)
29 #:use-module (srfi srfi-26)
cd6c6d60
LC
30 #:export (%haskell-build-system-modules
31 haskell-build
14dfdf2e
FB
32 haskell-build-system))
33
34;; Commentary:
35;;
36;; Standard build procedure for Haskell packages using 'Setup.hs'. This is
37;; implemented as an extension of 'gnu-build-system'.
38;;
39;; Code:
40
cd6c6d60
LC
41(define %haskell-build-system-modules
42 ;; Build-side modules imported by default.
43 `((guix build haskell-build-system)
44 ,@%gnu-build-system-modules))
45
14dfdf2e
FB
46(define (default-haskell)
47 "Return the default Haskell package."
48 ;; Lazily resolve the binding to avoid a circular dependency.
49 (let ((haskell (resolve-interface '(gnu packages haskell))))
50 (module-ref haskell 'ghc)))
51
bb6419f3
TS
52(define (source-url->revision-url url revision)
53 "Convert URL (a Hackage source URL) to the URL for the Cabal file at
54version REVISION."
55 (let* ((last-slash (string-rindex url #\/))
56 (next-slash (string-rindex url #\/ 0 last-slash)))
57 (string-append (substring url 0 next-slash)
58 (substring url last-slash (- (string-length url)
59 (string-length ".tar.gz")))
60 "/revision/" revision ".cabal")))
61
14dfdf2e
FB
62(define* (lower name
63 #:key source inputs native-inputs outputs system target
64 (haskell (default-haskell))
bb6419f3 65 cabal-revision
14dfdf2e
FB
66 #:allow-other-keys
67 #:rest arguments)
68 "Return a bag for NAME."
69 (define private-keywords
bb6419f3
TS
70 '(#:target #:haskell #:cabal-revision #:inputs #:native-inputs))
71
72 (define (cabal-revision->origin cabal-revision)
73 (match cabal-revision
74 ((revision hash)
75 (origin
76 (method url-fetch)
77 (uri (source-url->revision-url (origin-uri source) revision))
78 (sha256 (base32 hash))
79 (file-name (string-append name "-" revision ".cabal"))))
80 (#f #f)))
14dfdf2e
FB
81
82 (and (not target) ;XXX: no cross-compilation
83 (bag
84 (name name)
85 (system system)
86 (host-inputs `(,@(if source
87 `(("source" ,source))
88 '())
bb6419f3
TS
89 ,@(match (cabal-revision->origin cabal-revision)
90 (#f '())
91 (revision `(("cabal-revision" ,revision))))
14dfdf2e
FB
92 ,@inputs
93
94 ;; Keep the standard inputs of 'gnu-build-system'.
95 ,@(standard-packages)))
96 (build-inputs `(("haskell" ,haskell)
97 ,@native-inputs))
98 (outputs outputs)
99 (build haskell-build)
100 (arguments (strip-keyword-arguments private-keywords arguments)))))
101
102(define* (haskell-build store name inputs
103 #:key source
104 (haddock? #t)
105 (haddock-flags ''())
106 (tests? #t)
107 (test-target "test")
67cb9fa2 108 (parallel-build? #t)
14dfdf2e
FB
109 (configure-flags ''())
110 (phases '(@ (guix build haskell-build-system)
111 %standard-phases))
112 (outputs '("out"))
113 (search-paths '())
114 (system (%current-system))
115 (guile #f)
cd6c6d60 116 (imported-modules %haskell-build-system-modules)
14dfdf2e
FB
117 (modules '((guix build haskell-build-system)
118 (guix build utils))))
119 "Build SOURCE using HASKELL, and with INPUTS. This assumes that SOURCE
120provides a 'Setup.hs' file as its build system."
121 (define builder
122 `(begin
123 (use-modules ,@modules)
124 (haskell-build #:name ,name
125 #:source ,(match (assoc-ref inputs "source")
126 (((? derivation? source))
127 (derivation->output-path source))
128 ((source)
129 source)
130 (source
131 source))
bb6419f3
TS
132 #:cabal-revision ,(match (assoc-ref inputs
133 "cabal-revision")
134 (((? derivation? revision))
135 (derivation->output-path revision))
136 (revision revision))
14dfdf2e
FB
137 #:configure-flags ,configure-flags
138 #:haddock-flags ,haddock-flags
139 #:system ,system
140 #:test-target ,test-target
141 #:tests? ,tests?
67cb9fa2 142 #:parallel-build? ,parallel-build?
14dfdf2e
FB
143 #:haddock? ,haddock?
144 #:phases ,phases
145 #:outputs %outputs
146 #:search-paths ',(map search-path-specification->sexp
147 search-paths)
148 #:inputs %build-inputs)))
149
150 (define guile-for-build
151 (match guile
152 ((? package?)
153 (package-derivation store guile system #:graft? #f))
154 (#f ; the default
155 (let* ((distro (resolve-interface '(gnu packages commencement)))
156 (guile (module-ref distro 'guile-final)))
157 (package-derivation store guile system #:graft? #f)))))
158
159 (build-expression->derivation store name builder
160 #:inputs inputs
161 #:system system
162 #:modules imported-modules
163 #:outputs outputs
164 #:guile-for-build guile-for-build))
165
166(define haskell-build-system
167 (build-system
168 (name 'haskell)
169 (description "The standard Haskell build system")
170 (lower lower)))
171
172;;; haskell.scm ends here