Merge branch 'master' into core-updates
[jackhill/guix/guix.git] / guix / build-system / gnu.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
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 gnu)
20 #:use-module (guix store)
21 #:use-module (guix utils)
22 #:use-module (guix memoization)
23 #:use-module (guix derivations)
24 #:use-module (guix search-paths)
25 #:use-module (guix build-system)
26 #:use-module (guix packages)
27 #:use-module (srfi srfi-1)
28 #:use-module (ice-9 match)
29 #:export (%gnu-build-system-modules
30 gnu-build
31 gnu-build-system
32 standard-packages
33 standard-cross-packages
34 package-with-explicit-inputs
35 package-with-extra-configure-variable
36 static-libgcc-package
37 static-package
38 dist-package
39 package-with-restricted-references))
40
41 ;; Commentary:
42 ;;
43 ;; Standard build procedure for packages using the GNU Build System or
44 ;; something compatible ("./configure && make && make install").
45 ;;
46 ;; Code:
47
48 (define %gnu-build-system-modules
49 ;; Build-side modules imported and used by default.
50 '((guix build gnu-build-system)
51 (guix build utils)
52 (guix build gremlin)
53 (guix elf)))
54
55 (define %default-modules
56 ;; Modules in scope in the build-side environment.
57 '((guix build gnu-build-system)
58 (guix build utils)))
59
60 (define* (package-with-explicit-inputs/deprecated p inputs
61 #:optional
62 (loc (current-source-location))
63 #:key (native-inputs '())
64 guile)
65 "This variant is deprecated because it is inefficient: it memoizes only
66 temporarily instead of memoizing across all transformations where INPUTS is
67 the same.
68
69 Rewrite P, which is assumed to use GNU-BUILD-SYSTEM, to take INPUTS and
70 NATIVE-INPUTS as explicit inputs instead of the implicit default, and return
71 it. INPUTS and NATIVE-INPUTS can be either input lists or thunks; in the
72 latter case, they will be called in a context where the `%current-system' and
73 `%current-target-system' are suitably parametrized. Use GUILE to run the
74 builder, or the distro's final Guile when GUILE is #f."
75 (define inputs* inputs)
76 (define native-inputs* native-inputs)
77
78 (define (call inputs)
79 (if (procedure? inputs)
80 (inputs)
81 inputs))
82
83 (define (duplicate-filter inputs)
84 (let ((names (match (call inputs)
85 (((name _ ...) ...)
86 name))))
87 (lambda (inputs)
88 (fold alist-delete inputs names))))
89
90 (let loop ((p p))
91 (define rewritten-input
92 (mlambda (input)
93 (match input
94 ((name (? package? p) sub-drv ...)
95 ;; XXX: Check whether P's build system knows #:implicit-inputs, for
96 ;; things like `cross-pkg-config'.
97 (if (eq? (package-build-system p) gnu-build-system)
98 (cons* name (loop p) sub-drv)
99 (cons* name p sub-drv)))
100 (x x))))
101
102 (package (inherit p)
103 (location (if (pair? loc) (source-properties->location loc) loc))
104 (arguments
105 ;; 'ensure-keyword-arguments' guarantees that this procedure is
106 ;; idempotent.
107 (ensure-keyword-arguments (package-arguments p)
108 `(#:guile ,guile
109 #:implicit-inputs? #f)))
110 (replacement
111 (let ((replacement (package-replacement p)))
112 (and replacement
113 (package-with-explicit-inputs replacement inputs loc
114 #:native-inputs
115 native-inputs
116 #:guile guile))))
117 (native-inputs
118 (let ((filtered (duplicate-filter native-inputs*)))
119 `(,@(call native-inputs*)
120 ,@(map rewritten-input
121 (filtered (package-native-inputs p))))))
122 (propagated-inputs
123 (map rewritten-input
124 (package-propagated-inputs p)))
125 (inputs
126 (let ((filtered (duplicate-filter inputs*)))
127 `(,@(call inputs*)
128 ,@(map rewritten-input
129 (filtered (package-inputs p)))))))))
130
131 (define* (package-with-explicit-inputs* inputs #:optional guile)
132 "Return a procedure that rewrites the given package and all its dependencies
133 so that they use INPUTS (a thunk) instead of implicit inputs."
134 (define (duplicate-filter package-inputs)
135 (let ((names (match (inputs)
136 (((name _ ...) ...)
137 name))))
138 (fold alist-delete package-inputs names)))
139
140 (define (add-explicit-inputs p)
141 (if (and (eq? (package-build-system p) gnu-build-system)
142 (not (memq #:implicit-inputs? (package-arguments p))))
143 (package
144 (inherit p)
145 (inputs (append (inputs)
146 (duplicate-filter (package-inputs p))))
147 (arguments
148 (ensure-keyword-arguments (package-arguments p)
149 `(#:implicit-inputs? #f
150 #:guile ,guile))))
151 p))
152
153 (define (cut? p)
154 (or (not (eq? (package-build-system p) gnu-build-system))
155 (memq #:implicit-inputs? (package-arguments p))))
156
157 (package-mapping add-explicit-inputs cut?))
158
159 (define package-with-explicit-inputs
160 (case-lambda*
161 ((inputs #:optional guile)
162 (package-with-explicit-inputs* inputs guile))
163 ((p inputs #:optional (loc (current-source-location))
164 #:key (native-inputs '()) guile)
165 ;; deprecated
166 (package-with-explicit-inputs/deprecated p inputs
167 loc
168 #:native-inputs
169 native-inputs
170 #:guile guile))))
171
172 (define (package-with-extra-configure-variable p variable value)
173 "Return a version of P with VARIABLE=VALUE specified as an extra `configure'
174 flag, recursively. An example is LDFLAGS=-static. If P already has configure
175 flags for VARIABLE, the associated value is augmented."
176 (let loop ((p p))
177 (define (rewritten-inputs inputs)
178 (map (match-lambda
179 ((name (? package? p) sub ...)
180 `(,name ,(loop p) ,@sub))
181 (input input))
182 inputs))
183
184 (package (inherit p)
185 (arguments
186 (let ((args (package-arguments p)))
187 (substitute-keyword-arguments args
188 ((#:configure-flags flags)
189 (let* ((var= (string-append variable "="))
190 (len (string-length var=)))
191 `(cons ,(string-append var= value)
192 (map (lambda (flag)
193 (if (string-prefix? ,var= flag)
194 (string-append
195 ,(string-append var= value " ")
196 (substring flag ,len))
197 flag))
198 ,flags)))))))
199 (replacement
200 (let ((replacement (package-replacement p)))
201 (and replacement
202 (package-with-extra-configure-variable replacement
203 variable value))))
204 (inputs (rewritten-inputs (package-inputs p)))
205 (propagated-inputs (rewritten-inputs (package-propagated-inputs p))))))
206
207 (define (static-libgcc-package p)
208 "A version of P linked with `-static-gcc'."
209 (package-with-extra-configure-variable p "LDFLAGS" "-static-libgcc"))
210
211 (define* (static-package p #:key (strip-all? #t))
212 "Return a statically-linked version of package P. If STRIP-ALL? is true,
213 use `--strip-all' as the arguments to `strip'."
214 (package (inherit p)
215 (arguments
216 (let ((a (default-keyword-arguments (package-arguments p)
217 '(#:configure-flags '()
218 #:strip-flags '("--strip-debug")))))
219 (substitute-keyword-arguments a
220 ((#:configure-flags flags)
221 `(cons* "--disable-shared" "LDFLAGS=-static" ,flags))
222 ((#:strip-flags flags)
223 (if strip-all?
224 ''("--strip-all")
225 flags)))))
226 (replacement (and=> (package-replacement p) static-package))))
227
228 (define* (dist-package p source #:key (phases '%dist-phases))
229 "Return a package that runs takes source files from the SOURCE directory,
230 runs `make distcheck' and whose result is one or more source tarballs. The
231 exact build phases are defined by PHASES."
232 (let ((s source))
233 (package (inherit p)
234 (name (string-append (package-name p) "-dist"))
235 (source s)
236 (arguments
237 ;; Use the right phases and modules.
238 (let* ((args (default-keyword-arguments (package-arguments p)
239 `(#:phases #f
240 #:modules ,%default-modules
241 #:imported-modules ,%gnu-build-system-modules))))
242 (substitute-keyword-arguments args
243 ((#:modules modules)
244 `((guix build gnu-dist)
245 ,@modules))
246 ((#:imported-modules modules)
247 `((guix build gnu-dist)
248 ,@modules))
249 ((#:phases _)
250 phases))))
251 (native-inputs
252 ;; Add autotools & co. as inputs.
253 (let ((ref (lambda (module var)
254 (module-ref (resolve-interface module) var))))
255 `(,@(package-native-inputs p)
256 ("autoconf" ,((ref '(gnu packages autotools) 'autoconf-wrapper)))
257 ("automake" ,(ref '(gnu packages autotools) 'automake))
258 ("libtool" ,(ref '(gnu packages autotools) 'libtool))
259 ("gettext" ,(ref '(gnu packages gettext) 'gnu-gettext))
260 ("texinfo" ,(ref '(gnu packages texinfo) 'texinfo))))))))
261
262 (define (package-with-restricted-references p refs)
263 "Return a package whose outputs are guaranteed to only refer to the packages
264 listed in REFS."
265 (if (eq? (package-build-system p) gnu-build-system) ; XXX: dirty
266 (package (inherit p)
267 (arguments `(#:allowed-references ,refs
268 ,@(package-arguments p))))
269 p))
270
271 \f
272 (define (standard-packages)
273 "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of
274 standard packages used as implicit inputs of the GNU build system."
275
276 ;; Resolve (gnu packages commencement) lazily to hide circular dependency.
277 (let ((distro (resolve-module '(gnu packages commencement))))
278 (module-ref distro '%final-inputs)))
279
280 (define* (lower name
281 #:key source inputs native-inputs outputs target
282 (implicit-inputs? #t) (implicit-cross-inputs? #t)
283 (strip-binaries? #t) system
284 #:allow-other-keys
285 #:rest arguments)
286 "Return a bag for NAME from the given arguments."
287 (define private-keywords
288 `(#:source #:inputs #:native-inputs #:outputs
289 #:implicit-inputs? #:implicit-cross-inputs?
290 ,@(if target '() '(#:target))))
291
292 (bag
293 (name name)
294 (system system) (target target)
295 (build-inputs `(,@(if source
296 `(("source" ,source))
297 '())
298 ,@native-inputs
299
300 ;; When not cross-compiling, ensure implicit inputs come
301 ;; last. That way, libc headers come last, which allows
302 ;; #include_next to work correctly; see
303 ;; <https://bugs.gnu.org/30756>.
304 ,@(if target '() inputs)
305 ,@(if (and target implicit-cross-inputs?)
306 (standard-cross-packages target 'host)
307 '())
308 ,@(if implicit-inputs?
309 (standard-packages)
310 '())))
311 (host-inputs (if target inputs '()))
312
313 ;; The cross-libc is really a target package, but for bootstrapping
314 ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
315 ;; native package, so it would end up using a "native" variant of
316 ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
317 ;; would use a target variant (built with 'gnu-cross-build'.)
318 (target-inputs (if (and target implicit-cross-inputs?)
319 (standard-cross-packages target 'target)
320 '()))
321 (outputs (if strip-binaries?
322 outputs
323 (delete "debug" outputs)))
324 (build (if target gnu-cross-build gnu-build))
325 (arguments (strip-keyword-arguments private-keywords arguments))))
326
327 (define %license-file-regexp
328 ;; Regexp matching license files.
329 "^(COPYING.*|LICEN[CS]E.*|[Ll]icen[cs]e.*|Copy[Rr]ight(\\.(txt|md))?)$")
330
331 (define* (gnu-build store name input-drvs
332 #:key (guile #f)
333 (outputs '("out"))
334 (search-paths '())
335 (configure-flags ''())
336 (make-flags ''())
337 (out-of-source? #f)
338 (tests? #t)
339 (test-target "check")
340 (parallel-build? #t)
341 (parallel-tests? #t)
342 (patch-shebangs? #t)
343 (strip-binaries? #t)
344 (strip-flags ''("--strip-debug"
345 "--enable-deterministic-archives"))
346 (strip-directories ''("lib" "lib64" "libexec"
347 "bin" "sbin"))
348 (validate-runpath? #t)
349 (license-file-regexp %license-file-regexp)
350 (phases '%standard-phases)
351 (locale "en_US.utf8")
352 (system (%current-system))
353 (build (nix-system->gnu-triplet system))
354 (imported-modules %gnu-build-system-modules)
355 (modules %default-modules)
356 (substitutable? #t)
357 allowed-references
358 disallowed-references)
359 "Return a derivation called NAME that builds from tarball SOURCE, with
360 input derivation INPUTS, using the usual procedure of the GNU Build
361 System. The builder is run with GUILE, or with the distro's final Guile
362 package if GUILE is #f or omitted.
363
364 The builder is run in a context where MODULES are used; IMPORTED-MODULES
365 specifies modules not provided by Guile itself that must be imported in
366 the builder's environment, from the host. Note that we distinguish
367 between both, because for Guile's own modules like (ice-9 foo), we want
368 to use GUILE's own version of it, rather than import the user's one,
369 which could lead to gratuitous input divergence.
370
371 SUBSTITUTABLE? determines whether users may be able to use substitutes of the
372 returned derivations, or whether they should always build it locally.
373
374 ALLOWED-REFERENCES can be either #f, or a list of packages that the outputs
375 are allowed to refer to. Likewise for DISALLOWED-REFERENCES, which lists
376 packages that must not be referenced."
377 (define canonicalize-reference
378 (match-lambda
379 ((? package? p)
380 (derivation->output-path (package-derivation store p system
381 #:graft? #f)))
382 (((? package? p) output)
383 (derivation->output-path (package-derivation store p system
384 #:graft? #f)
385 output))
386 ((? string? output)
387 output)))
388
389 (define builder
390 `(begin
391 (use-modules ,@modules)
392 (gnu-build #:source ,(match (assoc-ref input-drvs "source")
393 (((? derivation? source))
394 (derivation->output-path source))
395 ((source)
396 source)
397 (source
398 source))
399 #:system ,system
400 #:build ,build
401 #:outputs %outputs
402 #:inputs %build-inputs
403 #:search-paths ',(map search-path-specification->sexp
404 search-paths)
405 #:phases ,phases
406 #:locale ,locale
407 #:configure-flags ,configure-flags
408 #:make-flags ,make-flags
409 #:out-of-source? ,out-of-source?
410 #:tests? ,tests?
411 #:test-target ,test-target
412 #:parallel-build? ,parallel-build?
413 #:parallel-tests? ,parallel-tests?
414 #:patch-shebangs? ,patch-shebangs?
415 #:strip-binaries? ,strip-binaries?
416 #:validate-runpath? ,validate-runpath?
417 #:license-file-regexp ,license-file-regexp
418 #:strip-flags ,strip-flags
419 #:strip-directories ,strip-directories)))
420
421 (define guile-for-build
422 (match guile
423 ((? package?)
424 (package-derivation store guile system #:graft? #f))
425 (#f ; the default
426 (let* ((distro (resolve-interface '(gnu packages commencement)))
427 (guile (module-ref distro 'guile-final)))
428 (package-derivation store guile system
429 #:graft? #f)))))
430
431 (build-expression->derivation store name builder
432 #:system system
433 #:inputs input-drvs
434 #:outputs outputs
435 #:modules imported-modules
436 #:substitutable? substitutable?
437
438 #:allowed-references
439 (and allowed-references
440 (map canonicalize-reference
441 allowed-references))
442 #:disallowed-references
443 (and disallowed-references
444 (map canonicalize-reference
445 disallowed-references))
446 #:guile-for-build guile-for-build))
447
448 \f
449 ;;;
450 ;;; Cross-compilation.
451 ;;;
452
453 (define standard-cross-packages
454 (mlambda (target kind)
455 "Return the list of name/package tuples to cross-build for TARGET. KIND
456 is one of `host' or `target'."
457 (let* ((cross (resolve-interface '(gnu packages cross-base)))
458 (gcc (module-ref cross 'cross-gcc))
459 (binutils (module-ref cross 'cross-binutils))
460 (libc (module-ref cross 'cross-libc)))
461 (case kind
462 ((host)
463 ;; Cross-GCC appears once here, so that it's in $PATH...
464 `(("cross-gcc" ,(gcc target
465 #:xbinutils (binutils target)
466 #:libc (libc target)))
467 ("cross-binutils" ,(binutils target))))
468 ((target)
469 (let ((libc (libc target)))
470 ;; ... and once here, so that libstdc++ & co. are in
471 ;; CROSS_CPLUS_INCLUDE_PATH, etc.
472 `(("cross-gcc" ,(gcc target
473 #:xbinutils (binutils target)
474 #:libc libc))
475 ("cross-libc" ,libc)
476
477 ;; MinGW's libc doesn't have a "static" output.
478 ,@(if (member "static" (package-outputs libc))
479 `(("cross-libc:static" ,libc "static"))
480 '()))))))))
481
482 (define* (gnu-cross-build store name
483 #:key
484 target native-drvs target-drvs
485 (guile #f)
486 source
487 (outputs '("out"))
488 (search-paths '())
489 (native-search-paths '())
490
491 (configure-flags ''())
492 (make-flags ''())
493 (out-of-source? #f)
494 (tests? #f) ; nothing can be done
495 (test-target "check")
496 (parallel-build? #t) (parallel-tests? #t)
497 (patch-shebangs? #t)
498 (strip-binaries? #t)
499 (strip-flags ''("--strip-debug"
500 "--enable-deterministic-archives"))
501 (strip-directories ''("lib" "lib64" "libexec"
502 "bin" "sbin"))
503 (validate-runpath? #t)
504 (license-file-regexp %license-file-regexp)
505 (phases '%standard-phases)
506 (locale "en_US.utf8")
507 (system (%current-system))
508 (build (nix-system->gnu-triplet system))
509 (imported-modules %gnu-build-system-modules)
510 (modules %default-modules)
511 (substitutable? #t)
512 allowed-references
513 disallowed-references)
514 "Cross-build NAME for TARGET, where TARGET is a GNU triplet. INPUTS are
515 cross-built inputs, and NATIVE-INPUTS are inputs that run on the build
516 platform."
517 (define canonicalize-reference
518 (match-lambda
519 ((? package? p)
520 (derivation->output-path (package-cross-derivation store p system)))
521 (((? package? p) output)
522 (derivation->output-path (package-cross-derivation store p system)
523 output))
524 ((? string? output)
525 output)))
526
527 (define builder
528 `(begin
529 (use-modules ,@modules)
530
531 (let ()
532 (define %build-host-inputs
533 ',(map (match-lambda
534 ((name (? derivation? drv) sub ...)
535 `(,name . ,(apply derivation->output-path drv sub)))
536 ((name path)
537 `(,name . ,path)))
538 native-drvs))
539
540 (define %build-target-inputs
541 ',(map (match-lambda
542 ((name (? derivation? drv) sub ...)
543 `(,name . ,(apply derivation->output-path drv sub)))
544 ((name (? package? pkg) sub ...)
545 (let ((drv (package-cross-derivation store pkg
546 target system)))
547 `(,name . ,(apply derivation->output-path drv sub))))
548 ((name path)
549 `(,name . ,path)))
550 target-drvs))
551
552 (gnu-build #:source ,(match (assoc-ref native-drvs "source")
553 (((? derivation? source))
554 (derivation->output-path source))
555 ((source)
556 source)
557 (source
558 source))
559 #:system ,system
560 #:build ,build
561 #:target ,target
562 #:outputs %outputs
563 #:inputs %build-target-inputs
564 #:native-inputs %build-host-inputs
565 #:search-paths ',(map search-path-specification->sexp
566 search-paths)
567 #:native-search-paths ',(map
568 search-path-specification->sexp
569 native-search-paths)
570 #:phases ,phases
571 #:locale ,locale
572 #:configure-flags ,configure-flags
573 #:make-flags ,make-flags
574 #:out-of-source? ,out-of-source?
575 #:tests? ,tests?
576 #:test-target ,test-target
577 #:parallel-build? ,parallel-build?
578 #:parallel-tests? ,parallel-tests?
579 #:patch-shebangs? ,patch-shebangs?
580 #:strip-binaries? ,strip-binaries?
581 #:validate-runpath? ,validate-runpath?
582 #:license-file-regexp ,license-file-regexp
583 #:strip-flags ,strip-flags
584 #:strip-directories ,strip-directories))))
585
586 (define guile-for-build
587 (match guile
588 ((? package?)
589 (package-derivation store guile system #:graft? #f))
590 (#f ; the default
591 (let* ((distro (resolve-interface '(gnu packages commencement)))
592 (guile (module-ref distro 'guile-final)))
593 (package-derivation store guile system #:graft? #f)))))
594
595 (build-expression->derivation store name builder
596 #:system system
597 #:inputs (append native-drvs target-drvs)
598 #:outputs outputs
599 #:modules imported-modules
600 #:substitutable? substitutable?
601
602 #:allowed-references
603 (and allowed-references
604 (map canonicalize-reference
605 allowed-references))
606 #:disallowed-references
607 (and disallowed-references
608 (map canonicalize-reference
609 disallowed-references))
610 #:guile-for-build guile-for-build))
611
612 (define gnu-build-system
613 (build-system
614 (name 'gnu)
615 (description
616 "The GNU Build System—i.e., ./configure && make && make install")
617 (lower lower)))