Merge branch 'core-updates'
[jackhill/guix/guix.git] / guix / build-system / cmake.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com>
4 ;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
5 ;;;
6 ;;; This file is part of GNU Guix.
7 ;;;
8 ;;; GNU Guix is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; GNU Guix is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21 (define-module (guix build-system cmake)
22 #:use-module (guix store)
23 #:use-module (guix utils)
24 #:use-module (guix derivations)
25 #:use-module (guix search-paths)
26 #:use-module (guix build-system)
27 #:use-module (guix build-system gnu)
28 #:use-module (guix packages)
29 #:use-module (ice-9 match)
30 #:export (%cmake-build-system-modules
31 cmake-build
32 cmake-build-system))
33
34 ;; Commentary:
35 ;;
36 ;; Standard build procedure for packages using CMake. This is implemented as an
37 ;; extension of `gnu-build-system'.
38 ;;
39 ;; Code:
40
41 (define %cmake-build-system-modules
42 ;; Build-side modules imported by default.
43 `((guix build cmake-build-system)
44 ,@%gnu-build-system-modules))
45
46 (define (default-cmake)
47 "Return the default CMake package."
48
49 ;; Do not use `@' to avoid introducing circular dependencies.
50 (let ((module (resolve-interface '(gnu packages cmake))))
51 (module-ref module 'cmake)))
52
53 (define* (lower name
54 #:key source inputs native-inputs outputs system target
55 (cmake (default-cmake))
56 #:allow-other-keys
57 #:rest arguments)
58 "Return a bag for NAME."
59 (define private-keywords
60 `(#:source #:cmake #:inputs #:native-inputs #:outputs
61 ,@(if target '() '(#:target))))
62
63 (bag
64 (name name)
65 (system system)
66 (target target)
67 (build-inputs `(,@(if source
68 `(("source" ,source))
69 '())
70 ,@`(("cmake" ,cmake))
71 ,@native-inputs
72 ,@(if target
73 ;; Use the standard cross inputs of
74 ;; 'gnu-build-system'.
75 (standard-cross-packages target 'host)
76 '())
77 ;; Keep the standard inputs of 'gnu-build-system'.
78 ,@(standard-packages)))
79 (host-inputs inputs)
80
81 ;; The cross-libc is really a target package, but for bootstrapping
82 ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
83 ;; native package, so it would end up using a "native" variant of
84 ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
85 ;; would use a target variant (built with 'gnu-cross-build'.)
86 (target-inputs (if target
87 (standard-cross-packages target 'target)
88 '()))
89 (outputs outputs)
90 (build (if target cmake-cross-build cmake-build))
91 (arguments (strip-keyword-arguments private-keywords arguments))))
92
93 (define* (cmake-build store name inputs
94 #:key (guile #f)
95 (outputs '("out")) (configure-flags ''())
96 (search-paths '())
97 (make-flags ''())
98 (out-of-source? #t)
99 (build-type "RelWithDebInfo")
100 (tests? #t)
101 (test-target "test")
102 (parallel-build? #t) (parallel-tests? #f)
103 (validate-runpath? #t)
104 (patch-shebangs? #t)
105 (strip-binaries? #t)
106 (strip-flags ''("--strip-debug"))
107 (strip-directories ''("lib" "lib64" "libexec"
108 "bin" "sbin"))
109 (phases '(@ (guix build cmake-build-system)
110 %standard-phases))
111 (system (%current-system))
112 (imported-modules %cmake-build-system-modules)
113 (modules '((guix build cmake-build-system)
114 (guix build utils))))
115 "Build SOURCE using CMAKE, and with INPUTS. This assumes that SOURCE
116 provides a 'CMakeLists.txt' file as its build system."
117 (define builder
118 `(begin
119 (use-modules ,@modules)
120 (cmake-build #:source ,(match (assoc-ref inputs "source")
121 (((? derivation? source))
122 (derivation->output-path source))
123 ((source)
124 source)
125 (source
126 source))
127 #:system ,system
128 #:outputs %outputs
129 #:inputs %build-inputs
130 #:search-paths ',(map search-path-specification->sexp
131 search-paths)
132 #:phases ,phases
133 #:configure-flags ,configure-flags
134 #:make-flags ,make-flags
135 #:out-of-source? ,out-of-source?
136 #:build-type ,build-type
137 #:tests? ,tests?
138 #:test-target ,test-target
139 #:parallel-build? ,parallel-build?
140 #:parallel-tests? ,parallel-tests?
141 #:validate-runpath? ,validate-runpath?
142 #:patch-shebangs? ,patch-shebangs?
143 #:strip-binaries? ,strip-binaries?
144 #:strip-flags ,strip-flags
145 #:strip-directories ,strip-directories)))
146
147 (define guile-for-build
148 (match guile
149 ((? package?)
150 (package-derivation store guile system #:graft? #f))
151 (#f ; the default
152 (let* ((distro (resolve-interface '(gnu packages commencement)))
153 (guile (module-ref distro 'guile-final)))
154 (package-derivation store guile system #:graft? #f)))))
155
156 (build-expression->derivation store name builder
157 #:system system
158 #:inputs inputs
159 #:modules imported-modules
160 #:outputs outputs
161 #:guile-for-build guile-for-build))
162
163 \f
164 ;;;
165 ;;; Cross-compilation.
166 ;;;
167
168 (define* (cmake-cross-build store name
169 #:key
170 target native-drvs target-drvs
171 (guile #f)
172 (outputs '("out"))
173 (configure-flags ''())
174 (search-paths '())
175 (native-search-paths '())
176 (make-flags ''())
177 (out-of-source? #t)
178 (build-type "RelWithDebInfo")
179 (tests? #f) ; nothing can be done
180 (test-target "test")
181 (parallel-build? #t) (parallel-tests? #f)
182 (validate-runpath? #t)
183 (patch-shebangs? #t)
184 (strip-binaries? #t)
185 (strip-flags ''("--strip-debug"
186 "--enable-deterministic-archives"))
187 (strip-directories ''("lib" "lib64" "libexec"
188 "bin" "sbin"))
189 (phases '(@ (guix build cmake-build-system)
190 %standard-phases))
191 (system (%current-system))
192 (build (nix-system->gnu-triplet system))
193 (imported-modules %cmake-build-system-modules)
194 (modules '((guix build cmake-build-system)
195 (guix build utils))))
196 "Cross-build NAME using CMAKE for TARGET, where TARGET is a GNU triplet and
197 with INPUTS. This assumes that SOURCE provides a 'CMakeLists.txt' file as its
198 build system."
199 (define builder
200 `(begin
201 (use-modules ,@modules)
202 (let ()
203 (define %build-host-inputs
204 ',(map (match-lambda
205 ((name (? derivation? drv) sub ...)
206 `(,name . ,(apply derivation->output-path drv sub)))
207 ((name path)
208 `(,name . ,path)))
209 native-drvs))
210
211 (define %build-target-inputs
212 ',(map (match-lambda
213 ((name (? derivation? drv) sub ...)
214 `(,name . ,(apply derivation->output-path drv sub)))
215 ((name (? package? pkg) sub ...)
216 (let ((drv (package-cross-derivation store pkg
217 target system)))
218 `(,name . ,(apply derivation->output-path drv sub))))
219 ((name path)
220 `(,name . ,path)))
221 target-drvs))
222
223 (cmake-build #:source ,(match (assoc-ref native-drvs "source")
224 (((? derivation? source))
225 (derivation->output-path source))
226 ((source)
227 source)
228 (source
229 source))
230 #:system ,system
231 #:build ,build
232 #:target ,target
233 #:outputs %outputs
234 #:inputs %build-target-inputs
235 #:native-inputs %build-host-inputs
236 #:search-paths ',(map search-path-specification->sexp
237 search-paths)
238 #:native-search-paths ',(map
239 search-path-specification->sexp
240 native-search-paths)
241 #:phases ,phases
242 #:configure-flags ,configure-flags
243 #:make-flags ,make-flags
244 #:out-of-source? ,out-of-source?
245 #:build-type ,build-type
246 #:tests? ,tests?
247 #:test-target ,test-target
248 #:parallel-build? ,parallel-build?
249 #:parallel-tests? ,parallel-tests?
250 #:validate-runpath? ,validate-runpath?
251 #:patch-shebangs? ,patch-shebangs?
252 #:strip-binaries? ,strip-binaries?
253 #:strip-flags ,strip-flags
254 #:strip-directories ,strip-directories))))
255
256 (define guile-for-build
257 (match guile
258 ((? package?)
259 (package-derivation store guile system #:graft? #f))
260 (#f ; the default
261 (let* ((distro (resolve-interface '(gnu packages commencement)))
262 (guile (module-ref distro 'guile-final)))
263 (package-derivation store guile system #:graft? #f)))))
264
265 (build-expression->derivation store name builder
266 #:system system
267 #:inputs (append native-drvs target-drvs)
268 #:outputs outputs
269 #:modules imported-modules
270 #:guile-for-build guile-for-build))
271
272 (define cmake-build-system
273 (build-system
274 (name 'cmake)
275 (description "The standard CMake build system")
276 (lower lower)))
277
278 ;;; cmake.scm ends here