1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
4 ;;; This file is part of GNU Guix.
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.
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.
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/>.
19 (define-module (guix build-system gnu)
20 #:use-module (guix store)
21 #:use-module (guix utils)
22 #:use-module (guix derivations)
23 #:use-module (guix search-paths)
24 #:use-module (guix build-system)
25 #:use-module (guix packages)
26 #:use-module (srfi srfi-1)
27 #:use-module (ice-9 match)
28 #:export (%gnu-build-system-modules
32 package-with-explicit-inputs
33 package-with-extra-configure-variable
37 package-with-restricted-references))
41 ;; Standard build procedure for packages using the GNU Build System or
42 ;; something compatible ("./configure && make && make install").
46 (define %gnu-build-system-modules
47 ;; Build-side modules imported and used by default.
48 '((guix build gnu-build-system)
53 (define %default-modules
54 ;; Modules in scope in the build-side environment.
55 '((guix build gnu-build-system)
58 (define* (package-with-explicit-inputs p inputs
60 (loc (current-source-location))
61 #:key (native-inputs '())
63 "Rewrite P, which is assumed to use GNU-BUILD-SYSTEM, to take INPUTS and
64 NATIVE-INPUTS as explicit inputs instead of the implicit default, and return
65 it. INPUTS and NATIVE-INPUTS can be either input lists or thunks; in the
66 latter case, they will be called in a context where the `%current-system' and
67 `%current-target-system' are suitably parametrized. Use GUILE to run the
68 builder, or the distro's final Guile when GUILE is #f."
69 (define inputs* inputs)
70 (define native-inputs* native-inputs)
73 (if (procedure? inputs)
77 (define (duplicate-filter inputs)
78 (let ((names (match (call inputs)
82 (fold alist-delete inputs names))))
85 (define rewritten-input
88 ((name (? package? p) sub-drv ...)
89 ;; XXX: Check whether P's build system knows #:implicit-inputs, for
90 ;; things like `cross-pkg-config'.
91 (if (eq? (package-build-system p) gnu-build-system)
92 (cons* name (loop p) sub-drv)
93 (cons* name p sub-drv)))
97 (location (if (pair? loc) (source-properties->location loc) loc))
99 (let ((args (package-arguments p)))
101 #:implicit-inputs? #f
104 (let ((replacement (package-replacement p)))
106 (package-with-explicit-inputs replacement inputs loc
111 (let ((filtered (duplicate-filter native-inputs*)))
112 `(,@(call native-inputs*)
113 ,@(map rewritten-input
114 (filtered (package-native-inputs p))))))
117 (package-propagated-inputs p)))
119 (let ((filtered (duplicate-filter inputs*)))
121 ,@(map rewritten-input
122 (filtered (package-inputs p)))))))))
124 (define (package-with-extra-configure-variable p variable value)
125 "Return a version of P with VARIABLE=VALUE specified as an extra `configure'
126 flag, recursively. An example is LDFLAGS=-static. If P already has configure
127 flags for VARIABLE, the associated value is augmented."
129 (define (rewritten-inputs inputs)
131 ((name (? package? p) sub ...)
132 `(,name ,(loop p) ,@sub))
138 (let ((args (package-arguments p)))
139 (substitute-keyword-arguments args
140 ((#:configure-flags flags)
141 (let* ((var= (string-append variable "="))
142 (len (string-length var=)))
143 `(cons ,(string-append var= value)
145 (if (string-prefix? ,var= flag)
147 ,(string-append var= value " ")
148 (substring flag ,len))
152 (let ((replacement (package-replacement p)))
154 (package-with-extra-configure-variable replacement
156 (inputs (rewritten-inputs (package-inputs p)))
157 (propagated-inputs (rewritten-inputs (package-propagated-inputs p))))))
159 (define (static-libgcc-package p)
160 "A version of P linked with `-static-gcc'."
161 (package-with-extra-configure-variable p "LDFLAGS" "-static-libgcc"))
163 (define* (static-package p #:optional (loc (current-source-location))
164 #:key (strip-all? #t))
165 "Return a statically-linked version of package P. If STRIP-ALL? is true,
166 use `--strip-all' as the arguments to `strip'."
168 (location (source-properties->location loc))
170 (let ((a (default-keyword-arguments (package-arguments p)
171 '(#:configure-flags '()
172 #:strip-flags '("--strip-debug")))))
173 (substitute-keyword-arguments a
174 ((#:configure-flags flags)
175 `(cons* "--disable-shared" "LDFLAGS=-static" ,flags))
176 ((#:strip-flags flags)
180 (replacement (and=> (package-replacement p) static-package))))
182 (define* (dist-package p source)
183 "Return a package that runs takes source files from the SOURCE directory,
184 runs `make distcheck' and whose result is one or more source tarballs."
187 (name (string-append (package-name p) "-dist"))
190 ;; Use the right phases and modules.
191 (let* ((args (default-keyword-arguments (package-arguments p)
193 #:modules ,%default-modules
194 #:imported-modules ,%gnu-build-system-modules))))
195 (substitute-keyword-arguments args
197 `((guix build gnu-dist)
199 ((#:imported-modules modules)
200 `((guix build gnu-dist)
205 ;; Add autotools & co. as inputs.
206 (let ((ref (lambda (module var)
207 (module-ref (resolve-interface module) var))))
208 `(,@(package-native-inputs p)
209 ("autoconf" ,(ref '(gnu packages autotools) 'autoconf))
210 ("automake" ,(ref '(gnu packages autotools) 'automake))
211 ("libtool" ,(ref '(gnu packages autotools) 'libtool))
212 ("gettext" ,(ref '(gnu packages gettext) 'gnu-gettext))
213 ("texinfo" ,(ref '(gnu packages texinfo) 'texinfo))))))))
215 (define (package-with-restricted-references p refs)
216 "Return a package whose outputs are guaranteed to only refer to the packages
218 (if (eq? (package-build-system p) gnu-build-system) ; XXX: dirty
220 (arguments `(#:allowed-references ,refs
221 ,@(package-arguments p))))
225 (define (standard-packages)
226 "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of
227 standard packages used as implicit inputs of the GNU build system."
229 ;; Resolve (gnu packages commencement) lazily to hide circular dependency.
230 (let ((distro (resolve-module '(gnu packages commencement))))
231 (module-ref distro '%final-inputs)))
234 #:key source inputs native-inputs outputs target
235 (implicit-inputs? #t) (implicit-cross-inputs? #t)
236 (strip-binaries? #t) system
239 "Return a bag for NAME from the given arguments."
240 (define private-keywords
241 `(#:source #:inputs #:native-inputs #:outputs
242 #:implicit-inputs? #:implicit-cross-inputs?
243 ,@(if target '() '(#:target))))
247 (system system) (target target)
248 (build-inputs `(,@(if source
249 `(("source" ,source))
252 ,@(if (and target implicit-cross-inputs?)
253 (standard-cross-packages target 'host)
255 ,@(if implicit-inputs?
260 ;; The cross-libc is really a target package, but for bootstrapping
261 ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
262 ;; native package, so it would end up using a "native" variant of
263 ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
264 ;; would use a target variant (built with 'gnu-cross-build'.)
265 (target-inputs (if (and target implicit-cross-inputs?)
266 (standard-cross-packages target 'target)
268 (outputs (if strip-binaries?
270 (delete "debug" outputs)))
271 (build (if target gnu-cross-build gnu-build))
272 (arguments (strip-keyword-arguments private-keywords arguments))))
274 (define* (gnu-build store name input-drvs
278 (configure-flags ''())
282 (test-target "check")
287 (strip-flags ''("--strip-debug"))
288 (strip-directories ''("lib" "lib64" "libexec"
290 (validate-runpath? #t)
291 (phases '%standard-phases)
292 (locale "en_US.UTF-8")
293 (system (%current-system))
294 (imported-modules %gnu-build-system-modules)
295 (modules %default-modules)
298 "Return a derivation called NAME that builds from tarball SOURCE, with
299 input derivation INPUTS, using the usual procedure of the GNU Build
300 System. The builder is run with GUILE, or with the distro's final Guile
301 package if GUILE is #f or omitted.
303 The builder is run in a context where MODULES are used; IMPORTED-MODULES
304 specifies modules not provided by Guile itself that must be imported in
305 the builder's environment, from the host. Note that we distinguish
306 between both, because for Guile's own modules like (ice-9 foo), we want
307 to use GUILE's own version of it, rather than import the user's one,
308 which could lead to gratuitous input divergence.
310 SUBSTITUTABLE? determines whether users may be able to use substitutes of the
311 returned derivations, or whether they should always build it locally.
313 ALLOWED-REFERENCES can be either #f, or a list of packages that the outputs
314 are allowed to refer to."
315 (define canonicalize-reference
318 (derivation->output-path (package-derivation store p system
320 (((? package? p) output)
321 (derivation->output-path (package-derivation store p system
329 (use-modules ,@modules)
330 (gnu-build #:source ,(match (assoc-ref input-drvs "source")
331 (((? derivation? source))
332 (derivation->output-path source))
339 #:inputs %build-inputs
340 #:search-paths ',(map search-path-specification->sexp
344 #:configure-flags ,configure-flags
345 #:make-flags ,make-flags
346 #:out-of-source? ,out-of-source?
348 #:test-target ,test-target
349 #:parallel-build? ,parallel-build?
350 #:parallel-tests? ,parallel-tests?
351 #:patch-shebangs? ,patch-shebangs?
352 #:strip-binaries? ,strip-binaries?
353 #:validate-runpath? ,validate-runpath?
354 #:strip-flags ,strip-flags
355 #:strip-directories ,strip-directories)))
357 (define guile-for-build
360 (package-derivation store guile system #:graft? #f))
362 (let* ((distro (resolve-interface '(gnu packages commencement)))
363 (guile (module-ref distro 'guile-final)))
364 (package-derivation store guile system
367 (build-expression->derivation store name builder
371 #:modules imported-modules
374 ;; <http://bugs.gnu.org/18747> is fixed.
375 #:local-build? (not substitutable?)
378 (and allowed-references
379 (map canonicalize-reference
381 #:guile-for-build guile-for-build))
385 ;;; Cross-compilation.
388 (define standard-cross-packages
390 (lambda (target kind)
391 "Return the list of name/package tuples to cross-build for TARGET. KIND
392 is one of `host' or `target'."
393 (let* ((cross (resolve-interface '(gnu packages cross-base)))
394 (gcc (module-ref cross 'cross-gcc))
395 (binutils (module-ref cross 'cross-binutils))
396 (libc (module-ref cross 'cross-libc)))
399 `(("cross-gcc" ,(gcc target
402 ("cross-binutils" ,(binutils target))))
404 `(("cross-libc" ,(libc target)))))))))
406 (define* (gnu-cross-build store name
408 target native-drvs target-drvs
413 (native-search-paths '())
415 (configure-flags ''())
418 (tests? #f) ; nothing can be done
419 (test-target "check")
420 (parallel-build? #t) (parallel-tests? #t)
423 (strip-flags ''("--strip-debug"))
424 (strip-directories ''("lib" "lib64" "libexec"
426 (validate-runpath? #t)
427 (phases '%standard-phases)
428 (locale "en_US.UTF-8")
429 (system (%current-system))
430 (imported-modules %gnu-build-system-modules)
431 (modules %default-modules)
434 "Cross-build NAME for TARGET, where TARGET is a GNU triplet. INPUTS are
435 cross-built inputs, and NATIVE-INPUTS are inputs that run on the build
437 (define canonicalize-reference
440 (derivation->output-path (package-cross-derivation store p system)))
441 (((? package? p) output)
442 (derivation->output-path (package-cross-derivation store p system)
449 (use-modules ,@modules)
452 (define %build-host-inputs
454 ((name (? derivation? drv) sub ...)
455 `(,name . ,(apply derivation->output-path drv sub)))
460 (define %build-target-inputs
462 ((name (? derivation? drv) sub ...)
463 `(,name . ,(apply derivation->output-path drv sub)))
464 ((name (? package? pkg) sub ...)
465 (let ((drv (package-cross-derivation store pkg
467 `(,name . ,(apply derivation->output-path drv sub))))
472 (gnu-build #:source ,(match (assoc-ref native-drvs "source")
473 (((? derivation? source))
474 (derivation->output-path source))
482 #:inputs %build-target-inputs
483 #:native-inputs %build-host-inputs
484 #:search-paths ',(map search-path-specification->sexp
486 #:native-search-paths ',(map
487 search-path-specification->sexp
491 #:configure-flags ,configure-flags
492 #:make-flags ,make-flags
493 #:out-of-source? ,out-of-source?
495 #:test-target ,test-target
496 #:parallel-build? ,parallel-build?
497 #:parallel-tests? ,parallel-tests?
498 #:patch-shebangs? ,patch-shebangs?
499 #:strip-binaries? ,strip-binaries?
500 #:validate-runpath? ,validate-runpath?
501 #:strip-flags ,strip-flags
502 #:strip-directories ,strip-directories))))
504 (define guile-for-build
507 (package-derivation store guile system #:graft? #f))
509 (let* ((distro (resolve-interface '(gnu packages commencement)))
510 (guile (module-ref distro 'guile-final)))
511 (package-derivation store guile system #:graft? #f)))))
513 (build-expression->derivation store name builder
515 #:inputs (append native-drvs target-drvs)
517 #:modules imported-modules
520 ;; <http://bugs.gnu.org/18747> is fixed.
521 #:local-build? (not substitutable?)
524 (and allowed-references
525 (map canonicalize-reference
527 #:guile-for-build guile-for-build))
529 (define gnu-build-system
533 "The GNU Build System—i.e., ./configure && make && make install")