gnu: Remove unneeded 'imported-modules' fields for 'origin'.
[jackhill/guix/guix.git] / guix / packages.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
7adf9b84 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
2e9511df 3;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
a6d0b306 4;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org>
e3ce5d70 5;;;
233e7676 6;;; This file is part of GNU Guix.
e3ce5d70 7;;;
233e7676 8;;; GNU Guix is free software; you can redistribute it and/or modify it
e3ce5d70
LC
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;;;
233e7676 13;;; GNU Guix is distributed in the hope that it will be useful, but
e3ce5d70
LC
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
233e7676 19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
e3ce5d70
LC
20
21(define-module (guix packages)
22 #:use-module (guix utils)
c0cd1b3e 23 #:use-module (guix records)
e3ce5d70 24 #:use-module (guix store)
e87f0591 25 #:use-module (guix monads)
ff40e9b7 26 #:use-module (guix gexp)
ddc29a78 27 #:use-module (guix base32)
7adf9b84 28 #:use-module (guix grafts)
d510ab46 29 #:use-module (guix derivations)
e3ce5d70 30 #:use-module (guix build-system)
e89431bf 31 #:use-module (guix search-paths)
cf87cc89 32 #:use-module (guix gexp)
c22a1324 33 #:use-module (guix sets)
e3ce5d70 34 #:use-module (ice-9 match)
c37a74bd 35 #:use-module (ice-9 vlist)
062c6927 36 #:use-module (srfi srfi-1)
946b72c9 37 #:use-module (srfi srfi-9 gnu)
05962f29 38 #:use-module (srfi srfi-11)
a63062b5 39 #:use-module (srfi srfi-26)
d36622dc
LC
40 #:use-module (srfi srfi-34)
41 #:use-module (srfi srfi-35)
3b4d0103 42 #:use-module (web uri)
cd52703a 43 #:re-export (%current-system
e89431bf
LC
44 %current-target-system
45 search-path-specification) ;for convenience
ff352cfb 46 #:export (origin
90c68be8
LC
47 origin?
48 origin-uri
49 origin-method
50 origin-sha256
51 origin-file-name
3b4d0103 52 origin-actual-file-name
ac10e0e1
LC
53 origin-patches
54 origin-patch-flags
55 origin-patch-inputs
56 origin-patch-guile
f9cc8971
LC
57 origin-snippet
58 origin-modules
59 origin-imported-modules
e4c245f8 60 base32
e3ce5d70
LC
61
62 package
63 package?
64 package-name
65 package-version
2847050a 66 package-full-name
e3ce5d70
LC
67 package-source
68 package-build-system
69 package-arguments
70 package-inputs
71 package-native-inputs
062c6927 72 package-propagated-inputs
e3ce5d70 73 package-outputs
a18eda27 74 package-native-search-paths
e3ce5d70 75 package-search-paths
05962f29 76 package-replacement
d45122f5 77 package-synopsis
e3ce5d70 78 package-description
e3ce5d70 79 package-license
52bda18a 80 package-home-page
4e097f86 81 package-supported-systems
e3ce5d70 82 package-maintainers
062c6927 83 package-properties
35f3c5f5 84 package-location
d66c7096 85 package-field-location
e3ce5d70 86
f77bcbc3
EB
87 package-direct-sources
88 package-transitive-sources
7d193ec3 89 package-direct-inputs
a3d73f59 90 package-transitive-inputs
9c1edabd
LC
91 package-transitive-target-inputs
92 package-transitive-native-inputs
113aef68 93 package-transitive-propagated-inputs
aa8e0515 94 package-transitive-native-search-paths
7c3c0374 95 package-transitive-supported-systems
e3ce5d70
LC
96 package-source-derivation
97 package-derivation
d36622dc 98 package-cross-derivation
d510ab46 99 package-output
05962f29 100 package-grafts
d36622dc 101
a6d0b306
EB
102 transitive-input-references
103
4e097f86 104 %supported-systems
035b6ff7 105 %hurd-systems
abcbda48 106 %hydra-supported-systems
bbceb0ef 107 supported-package?
4e097f86 108
d36622dc 109 &package-error
07783858 110 package-error?
d36622dc
LC
111 package-error-package
112 &package-input-error
07783858 113 package-input-error?
9b222abe
LC
114 package-error-invalid-input
115 &package-cross-build-system-error
0d5a559f
LC
116 package-cross-build-system-error?
117
118 package->bag
d3d337d2 119 bag->derivation
cceab875 120 bag-direct-inputs
0d5a559f
LC
121 bag-transitive-inputs
122 bag-transitive-host-inputs
123 bag-transitive-build-inputs
e87f0591
LC
124 bag-transitive-target-inputs
125
126 default-guile
ff40e9b7 127 default-guile-derivation
e87f0591
LC
128 set-guile-for-build
129 package-file
130 package->derivation
131 package->cross-derivation
132 origin->derivation))
e3ce5d70
LC
133
134;;; Commentary:
135;;;
136;;; This module provides a high-level mechanism to define packages in a
137;;; Guix-based distribution.
138;;;
139;;; Code:
140
90c68be8
LC
141;; The source of a package, such as a tarball URL and fetcher---called
142;; "origin" to avoid name clash with `package-source', `source', etc.
143(define-record-type* <origin>
144 origin make-origin
145 origin?
146 (uri origin-uri) ; string
9b5b5c17 147 (method origin-method) ; procedure
90c68be8 148 (sha256 origin-sha256) ; bytevector
ac10e0e1 149 (file-name origin-file-name (default #f)) ; optional file name
6b1f9721
LC
150
151 ;; Patches are delayed so that the 'search-patch' calls are made lazily,
152 ;; which reduces I/O on startup and allows patch-not-found errors to be
153 ;; gracefully handled at run time.
154 (patches origin-patches ; list of file names
155 (default '()) (delayed))
156
f9cc8971 157 (snippet origin-snippet (default #f)) ; sexp or #f
ac10e0e1
LC
158 (patch-flags origin-patch-flags ; list of strings
159 (default '("-p1")))
1d9bc459
LC
160
161 ;; Patching requires Guile, GNU Patch, and a few more. These two fields are
162 ;; used to specify these dependencies when needed.
ac10e0e1
LC
163 (patch-inputs origin-patch-inputs ; input list or #f
164 (default #f))
f9cc8971
LC
165 (modules origin-modules ; list of module names
166 (default '()))
167 (imported-modules origin-imported-modules ; list of module names
168 (default '()))
1d9bc459 169 (patch-guile origin-patch-guile ; package or #f
ac10e0e1 170 (default #f)))
e3ce5d70 171
f1096964
LC
172(define (print-origin origin port)
173 "Write a concise representation of ORIGIN to PORT."
174 (match origin
175 (($ <origin> uri method sha256 file-name patches)
176 (simple-format port "#<origin ~s ~a ~s ~a>"
177 uri (bytevector->base32-string sha256)
6b1f9721 178 (force patches)
f1096964
LC
179 (number->string (object-address origin) 16)))))
180
181(set-record-type-printer! <origin> print-origin)
182
e4c245f8
LC
183(define-syntax base32
184 (lambda (s)
185 "Return the bytevector corresponding to the given Nix-base32
186representation."
187 (syntax-case s ()
188 ((_ str)
189 (string? (syntax->datum #'str))
aba326f7 190 ;; A literal string: do the conversion at expansion time.
e4c245f8
LC
191 (with-syntax ((bv (nix-base32-string->bytevector
192 (syntax->datum #'str))))
aba326f7
LC
193 #''bv))
194 ((_ str)
195 #'(nix-base32-string->bytevector str)))))
e4c245f8 196
3b4d0103
EB
197(define (origin-actual-file-name origin)
198 "Return the file name of ORIGIN, either its 'file-name' field or the file
199name of its URI."
200 (define (uri->file-name uri)
201 ;; Return the 'base name' of URI or URI itself, where URI is a string.
202 (let ((path (and=> (string->uri uri) uri-path)))
203 (if path
204 (basename path)
205 uri)))
206
207 (or (origin-file-name origin)
208 (match (origin-uri origin)
209 ((head . tail)
210 (uri->file-name head))
211 ((? string? uri)
212 (uri->file-name uri))
213 (else
214 ;; git, svn, cvs, etc. reference
215 #f))))
216
4e097f86
LC
217(define %supported-systems
218 ;; This is the list of system types that are supported. By default, we
219 ;; expect all packages to build successfully here.
fc34deea 220 '("x86_64-linux" "i686-linux" "armhf-linux" "mips64el-linux"))
4e097f86 221
035b6ff7
LC
222(define %hurd-systems
223 ;; The GNU/Hurd systems for which support is being developed.
224 '("i585-gnu" "i686-gnu"))
225
abcbda48
LC
226(define %hydra-supported-systems
227 ;; This is the list of system types for which build slaves are available.
52c20d8e 228 %supported-systems)
abcbda48
LC
229
230
a18eda27 231;; A package.
e3ce5d70
LC
232(define-record-type* <package>
233 package make-package
234 package?
235 (name package-name) ; string
236 (version package-version) ; string
90c68be8 237 (source package-source) ; <origin> instance
e3ce5d70 238 (build-system package-build-system) ; build system
64fddd74 239 (arguments package-arguments ; arguments for the build method
21c203a5 240 (default '()) (thunked))
062c6927 241
e3ce5d70 242 (inputs package-inputs ; input packages or derivations
dd6b9a37 243 (default '()) (thunked))
062c6927 244 (propagated-inputs package-propagated-inputs ; same, but propagated
9d97a1b3 245 (default '()) (thunked))
e3ce5d70 246 (native-inputs package-native-inputs ; native input packages/derivations
a7dc055b 247 (default '()) (thunked))
c9d01150
LC
248 (self-native-input? package-self-native-input? ; whether to use itself as
249 ; a native input when cross-
250 (default #f)) ; compiling
062c6927 251
e3ce5d70
LC
252 (outputs package-outputs ; list of strings
253 (default '("out")))
a18eda27
LC
254
255 ; lists of
256 ; <search-path-specification>,
257 ; for native and cross
258 ; inputs
259 (native-search-paths package-native-search-paths (default '()))
260 (search-paths package-search-paths (default '()))
05962f29
LC
261 (replacement package-replacement ; package | #f
262 (default #f) (thunked))
e3ce5d70 263
d45122f5
LC
264 (synopsis package-synopsis) ; one-line description
265 (description package-description) ; one or two paragraphs
1fb78cb2 266 (license package-license)
45753b65 267 (home-page package-home-page)
4e097f86
LC
268 (supported-systems package-supported-systems ; list of strings
269 (default %supported-systems))
35f3c5f5 270 (maintainers package-maintainers (default '()))
45753b65 271
062c6927
LC
272 (properties package-properties (default '())) ; alist for anything else
273
35f3c5f5
LC
274 (location package-location
275 (default (and=> (current-source-location)
0004c590
LC
276 source-properties->location))
277 (innate)))
e3ce5d70 278
946b72c9
LC
279(set-record-type-printer! <package>
280 (lambda (package port)
281 (let ((loc (package-location package))
282 (format simple-format))
74e667d1 283 (format port "#<package ~a@~a ~a~a>"
946b72c9
LC
284 (package-name package)
285 (package-version package)
2e1bafb0
LC
286 (if loc
287 (format #f "~a:~a "
288 (location-file loc)
289 (location-line loc))
290 "")
946b72c9
LC
291 (number->string (object-address
292 package)
293 16)))))
294
d66c7096 295(define (package-field-location package field)
f903dc05
LC
296 "Return the source code location of the definition of FIELD for PACKAGE, or
297#f if it could not be determined."
298 (define (goto port line column)
299 (unless (and (= (port-column port) (- column 1))
300 (= (port-line port) (- line 1)))
301 (unless (eof-object? (read-char port))
302 (goto port line column))))
d66c7096
LC
303
304 (match (package-location package)
305 (($ <location> file line column)
306 (catch 'system
307 (lambda ()
0b8749b7
LC
308 ;; In general we want to keep relative file names for modules.
309 (with-fluids ((%file-port-name-canonicalization 'relative))
310 (call-with-input-file (search-path %load-path file)
311 (lambda (port)
312 (goto port line column)
313 (match (read port)
314 (('package inits ...)
315 (let ((field (assoc field inits)))
316 (match field
317 ((_ value)
318 ;; Put the `or' here, and not in the first argument of
319 ;; `and=>', to work around a compiler bug in 2.0.5.
320 (or (and=> (source-properties value)
321 source-properties->location)
322 (and=> (source-properties field)
323 source-properties->location)))
324 (_
325 #f))))
326 (_
327 #f))))))
d66c7096 328 (lambda _
f903dc05 329 #f)))
d66c7096
LC
330 (_ #f)))
331
d36622dc
LC
332
333;; Error conditions.
334
335(define-condition-type &package-error &error
336 package-error?
337 (package package-error-package))
338
339(define-condition-type &package-input-error &package-error
340 package-input-error?
341 (input package-error-invalid-input))
342
9b222abe
LC
343(define-condition-type &package-cross-build-system-error &package-error
344 package-cross-build-system-error?)
345
d36622dc 346
2847050a
LC
347(define (package-full-name package)
348 "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
349 (string-append (package-name package) "-" (package-version package)))
350
ac10e0e1 351(define (%standard-patch-inputs)
5ae4169c
LC
352 (let* ((canonical (module-ref (resolve-interface '(gnu packages base))
353 'canonical-package))
354 (ref (lambda (module var)
355 (canonical
356 (module-ref (resolve-interface module) var)))))
ac10e0e1
LC
357 `(("tar" ,(ref '(gnu packages base) 'tar))
358 ("xz" ,(ref '(gnu packages compression) 'xz))
359 ("bzip2" ,(ref '(gnu packages compression) 'bzip2))
360 ("gzip" ,(ref '(gnu packages compression) 'gzip))
361 ("lzip" ,(ref '(gnu packages compression) 'lzip))
17287d7d 362 ("unzip" ,(ref '(gnu packages zip) 'unzip))
9cca706c 363 ("patch" ,(ref '(gnu packages base) 'patch))
5ae4169c 364 ("locales" ,(ref '(gnu packages base) 'glibc-utf8-locales)))))
ac10e0e1 365
1d9bc459 366(define (default-guile)
e87f0591
LC
367 "Return the default Guile package used to run the build code of
368derivations."
bdb36958 369 (let ((distro (resolve-interface '(gnu packages commencement))))
1d9bc459 370 (module-ref distro 'guile-final)))
ac10e0e1 371
ff40e9b7
LC
372(define* (default-guile-derivation #:optional (system (%current-system)))
373 "Return the derivation for SYSTEM of the default Guile package used to run
374the build code of derivation."
375 (package->derivation (default-guile) system
376 #:graft? #f))
377
cf87cc89 378(define* (patch-and-repack source patches
ac10e0e1 379 #:key
a158484d 380 inputs
f9cc8971 381 (snippet #f)
ac10e0e1 382 (flags '("-p1"))
f9cc8971
LC
383 (modules '())
384 (imported-modules '())
ac10e0e1
LC
385 (guile-for-build (%guile-for-build))
386 (system (%current-system)))
f9cc8971
LC
387 "Unpack SOURCE (a derivation or store path), apply all of PATCHES, and
388repack the tarball using the tools listed in INPUTS. When SNIPPET is true,
389it must be an s-expression that will run from within the directory where
390SOURCE was unpacked, after all of PATCHES have been applied. MODULES and
391IMPORTED-MODULES specify modules to use/import for use by SNIPPET."
392 (define source-file-name
393 ;; SOURCE is usually a derivation, but it could be a store file.
394 (if (derivation? source)
395 (derivation->output-path source)
396 source))
397
a158484d
LC
398 (define lookup-input
399 ;; The default value of the 'patch-inputs' field, and thus INPUTS is #f,
400 ;; so deal with that.
401 (let ((inputs (or inputs (%standard-patch-inputs))))
402 (lambda (name)
403 (match (assoc-ref inputs name)
404 ((package) package)
405 (#f #f)))))
cf87cc89 406
ac10e0e1 407 (define decompression-type
f9cc8971 408 (cond ((string-suffix? "gz" source-file-name) "gzip")
5257ab6d 409 ((string-suffix? "Z" source-file-name) "gzip")
f9cc8971
LC
410 ((string-suffix? "bz2" source-file-name) "bzip2")
411 ((string-suffix? "lz" source-file-name) "lzip")
17287d7d 412 ((string-suffix? "zip" source-file-name) "unzip")
f9cc8971 413 (else "xz")))
ac10e0e1
LC
414
415 (define original-file-name
f9cc8971
LC
416 ;; Remove the store prefix plus the slash, hash, and hyphen.
417 (let* ((sans (string-drop source-file-name
418 (+ (string-length (%store-prefix)) 1)))
419 (dash (string-index sans #\-)))
420 (string-drop sans (+ 1 dash))))
ac10e0e1 421
3ca00bb5
LC
422 (define (numeric-extension? file-name)
423 ;; Return true if FILE-NAME ends with digits.
857ecb3d
LC
424 (and=> (file-extension file-name)
425 (cut string-every char-set:hex-digit <>)))
3ca00bb5
LC
426
427 (define (tarxz-name file-name)
428 ;; Return a '.tar.xz' file name based on FILE-NAME.
429 (let ((base (if (numeric-extension? file-name)
430 original-file-name
431 (file-sans-extension file-name))))
432 (string-append base
433 (if (equal? (file-extension base) "tar")
434 ".xz"
435 ".tar.xz"))))
436
cf87cc89
LC
437 (define instantiate-patch
438 (match-lambda
439 ((? string? patch)
440 (interned-file patch #:recursive? #t))
441 ((? origin? patch)
442 (origin->derivation patch system))))
443
444 (mlet %store-monad ((tar -> (lookup-input "tar"))
445 (xz -> (lookup-input "xz"))
446 (patch -> (lookup-input "patch"))
447 (locales -> (lookup-input "locales"))
448 (decomp -> (lookup-input decompression-type))
449 (patches (sequence %store-monad
450 (map instantiate-patch patches))))
451 (define build
452 #~(begin
453 (use-modules (ice-9 ftw)
454 (srfi srfi-1)
455 (guix build utils))
456
140b4bc6
MW
457 ;; The --sort option was added to GNU tar in version 1.28, released
458 ;; 2014-07-28. During bootstrap we must cope with older versions.
459 (define tar-supports-sort?
460 (zero? (system* (string-append #+tar "/bin/tar")
461 "cf" "/dev/null" "--files-from=/dev/null"
462 "--sort=name")))
463
cf87cc89
LC
464 (define (apply-patch patch)
465 (format (current-error-port) "applying '~a'...~%" patch)
466
467 ;; Use '--force' so that patches that do not apply perfectly are
468 ;; rejected.
1590e8a1
LC
469 (zero? (system* (string-append #+patch "/bin/patch")
470 "--force" #+@flags "--input" patch)))
cf87cc89
LC
471
472 (define (first-file directory)
473 ;; Return the name of the first file in DIRECTORY.
474 (car (scandir directory
475 (lambda (name)
476 (not (member name '("." "..")))))))
477
478 ;; Encoding/decoding errors shouldn't be silent.
479 (fluid-set! %default-port-conversion-strategy 'error)
480
1590e8a1 481 (when #+locales
cf87cc89
LC
482 ;; First of all, install a UTF-8 locale so that UTF-8 file names
483 ;; are correctly interpreted. During bootstrap, LOCALES is #f.
85b81cf8
LC
484 (setenv "LOCPATH"
485 (string-append #+locales "/lib/locale/"
486 #+(and locales
487 (package-version locales))))
afd3d931 488 (setlocale LC_ALL "en_US.utf8"))
cf87cc89 489
1590e8a1
LC
490 (setenv "PATH" (string-append #+xz "/bin" ":"
491 #+decomp "/bin"))
cf87cc89
LC
492
493 ;; SOURCE may be either a directory or a tarball.
1590e8a1 494 (and (if (file-is-directory? #+source)
2fdcc607 495 (let* ((store (%store-directory))
cf87cc89 496 (len (+ 1 (string-length store)))
1590e8a1 497 (base (string-drop #+source len))
cf87cc89
LC
498 (dash (string-index base #\-))
499 (directory (string-drop base (+ 1 dash))))
500 (mkdir directory)
1590e8a1 501 (copy-recursively #+source directory)
cf87cc89 502 #t)
1590e8a1
LC
503 #+(if (string=? decompression-type "unzip")
504 #~(zero? (system* "unzip" #+source))
505 #~(zero? (system* (string-append #+tar "/bin/tar")
506 "xvf" #+source))))
cf87cc89
LC
507 (let ((directory (first-file ".")))
508 (format (current-error-port)
509 "source is under '~a'~%" directory)
510 (chdir directory)
511
1590e8a1
LC
512 (and (every apply-patch '#+patches)
513 #+@(if snippet
cf87cc89
LC
514 #~((let ((module (make-fresh-user-module)))
515 (module-use-interfaces! module
516 (map resolve-interface
1590e8a1 517 '#+modules))
cf87cc89 518 ((@ (system base compile) compile)
1590e8a1 519 '#+snippet
cf87cc89
LC
520 #:to 'value
521 #:opts %auto-compilation-options
522 #:env module)))
523 #~())
524
525 (begin (chdir "..") #t)
140b4bc6
MW
526
527 (unless tar-supports-sort?
528 (call-with-output-file ".file_list"
529 (lambda (port)
530 (for-each (lambda (name) (format port "~a~%" name))
531 (find-files directory
532 #:directories? #t
533 #:fail-on-error? #t)))))
534 (zero? (apply system* (string-append #+tar "/bin/tar")
535 "cvfa" #$output
536 ;; avoid non-determinism in the archive
537 "--mtime=@0"
538 "--owner=root:0"
539 "--group=root:0"
540 (if tar-supports-sort?
541 `("--sort=name"
542 ,directory)
543 '("--no-recursion"
544 "--files-from=.file_list")))))))))
cf87cc89
LC
545
546 (let ((name (tarxz-name original-file-name))
a7db719f
LC
547 (modules (delete-duplicates (cons '(guix build utils)
548 imported-modules))))
cf87cc89
LC
549 (gexp->derivation name build
550 #:graft? #f
551 #:system system
552 #:modules modules
553 #:guile-for-build guile-for-build))))
ac10e0e1 554
113aef68 555(define (transitive-inputs inputs)
161094c8
LC
556 "Return the closure of INPUTS when considering the 'propagated-inputs'
557edges. Omit duplicate inputs, except for those already present in INPUTS
558itself.
559
560This is implemented as a breadth-first traversal such that INPUTS is
561preserved, and only duplicate propagated inputs are removed."
562 (define (seen? seen item outputs)
563 (match (vhash-assq item seen)
564 ((_ . o) (equal? o outputs))
565 (_ #f)))
566
567 (let loop ((inputs inputs)
568 (result '())
569 (propagated '())
570 (first? #t)
571 (seen vlist-null))
a3d73f59
LC
572 (match inputs
573 (()
161094c8
LC
574 (if (null? propagated)
575 (reverse result)
576 (loop (reverse (concatenate propagated)) result '() #f seen)))
577 (((and input (label (? package? package) outputs ...)) rest ...)
578 (if (and (not first?) (seen? seen package outputs))
579 (loop rest result propagated first? seen)
580 (loop rest
581 (cons input result)
582 (cons (package-propagated-inputs package) propagated)
583 first?
584 (vhash-consq package outputs seen))))
a3d73f59 585 ((input rest ...)
161094c8 586 (loop rest (cons input result) propagated first? seen)))))
a3d73f59 587
f77bcbc3
EB
588(define (package-direct-sources package)
589 "Return all source origins associated with PACKAGE; including origins in
590PACKAGE's inputs."
591 `(,@(or (and=> (package-source package) list) '())
592 ,@(filter-map (match-lambda
593 ((_ (? origin? orig) _ ...)
594 orig)
595 (_ #f))
596 (package-direct-inputs package))))
597
598(define (package-transitive-sources package)
599 "Return PACKAGE's direct sources, and their direct sources, recursively."
600 (delete-duplicates
601 (concatenate (filter-map (match-lambda
602 ((_ (? origin? orig) _ ...)
603 (list orig))
604 ((_ (? package? p) _ ...)
605 (package-direct-sources p))
606 (_ #f))
607 (bag-transitive-inputs
608 (package->bag package))))))
609
7d193ec3
EB
610(define (package-direct-inputs package)
611 "Return all the direct inputs of PACKAGE---i.e, its direct inputs along
612with their propagated inputs."
613 (append (package-native-inputs package)
614 (package-inputs package)
615 (package-propagated-inputs package)))
616
113aef68
LC
617(define (package-transitive-inputs package)
618 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
619with their propagated inputs, recursively."
7d193ec3 620 (transitive-inputs (package-direct-inputs package)))
113aef68 621
9c1edabd
LC
622(define (package-transitive-target-inputs package)
623 "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
624along with their propagated inputs, recursively. This only includes inputs
625for the target system, and not native inputs."
626 (transitive-inputs (append (package-inputs package)
627 (package-propagated-inputs package))))
628
629(define (package-transitive-native-inputs package)
630 "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
631along with their propagated inputs, recursively. This only includes inputs
632for the host system (\"native inputs\"), and not target inputs."
633 (transitive-inputs (package-native-inputs package)))
634
113aef68
LC
635(define (package-transitive-propagated-inputs package)
636 "Return the propagated inputs of PACKAGE, and their propagated inputs,
637recursively."
638 (transitive-inputs (package-propagated-inputs package)))
639
aa8e0515
LC
640(define (package-transitive-native-search-paths package)
641 "Return the list of search paths for PACKAGE and its propagated inputs,
642recursively."
643 (append (package-native-search-paths package)
644 (append-map (match-lambda
645 ((label (? package? p) _ ...)
646 (package-native-search-paths p))
647 (_
648 '()))
649 (package-transitive-propagated-inputs package))))
650
a6d0b306
EB
651(define (transitive-input-references alist inputs)
652 "Return a list of (assoc-ref ALIST <label>) for each (<label> <package> . _)
653in INPUTS and their transitive propagated inputs."
654 (define label
655 (match-lambda
656 ((label . _)
657 label)))
658
659 (map (lambda (input)
660 `(assoc-ref ,alist ,(label input)))
661 (transitive-inputs inputs)))
662
a193b824
MW
663(define-syntax define-memoized/v
664 (lambda (form)
665 "Define a memoized single-valued unary procedure with docstring.
666The procedure argument is compared to cached keys using `eqv?'."
667 (syntax-case form ()
668 ((_ (proc arg) docstring body body* ...)
669 (string? (syntax->datum #'docstring))
670 #'(define proc
671 (let ((cache (make-hash-table)))
672 (define (proc arg)
673 docstring
674 (match (hashv-get-handle cache arg)
675 ((_ . value)
676 value)
677 (_
678 (let ((result (let () body body* ...)))
679 (hashv-set! cache arg result)
680 result))))
681 proc))))))
c37a74bd 682
a193b824 683(define-memoized/v (package-transitive-supported-systems package)
7c3c0374
LC
684 "Return the intersection of the systems supported by PACKAGE and those
685supported by its dependencies."
a193b824
MW
686 (fold (lambda (input systems)
687 (match input
688 ((label (? package? p) . _)
689 (lset-intersection
690 string=? systems (package-transitive-supported-systems p)))
691 (_
692 systems)))
693 (package-supported-systems package)
9bf3ced0 694 (bag-direct-inputs (package->bag package))))
7c3c0374 695
bbceb0ef
LC
696(define* (supported-package? package #:optional (system (%current-system)))
697 "Return true if PACKAGE is supported on SYSTEM--i.e., if PACKAGE and all its
698dependencies are known to build on SYSTEM."
699 (member system (package-transitive-supported-systems package)))
700
cceab875
LC
701(define (bag-direct-inputs bag)
702 "Same as 'package-direct-inputs', but applied to a bag."
703 (append (bag-build-inputs bag)
704 (bag-host-inputs bag)
705 (bag-target-inputs bag)))
706
0d5a559f
LC
707(define (bag-transitive-inputs bag)
708 "Same as 'package-transitive-inputs', but applied to a bag."
cceab875 709 (transitive-inputs (bag-direct-inputs bag)))
0d5a559f
LC
710
711(define (bag-transitive-build-inputs bag)
712 "Same as 'package-transitive-native-inputs', but applied to a bag."
713 (transitive-inputs (bag-build-inputs bag)))
714
715(define (bag-transitive-host-inputs bag)
716 "Same as 'package-transitive-target-inputs', but applied to a bag."
717 (transitive-inputs (bag-host-inputs bag)))
718
719(define (bag-transitive-target-inputs bag)
720 "Return the \"target inputs\" of BAG, recursively."
721 (transitive-inputs (bag-target-inputs bag)))
722
a2ebaddd
LC
723\f
724;;;
725;;; Package derivations.
726;;;
727
728(define %derivation-cache
729 ;; Package to derivation-path mapping.
e4588af9 730 (make-weak-key-hash-table 100))
a2ebaddd 731
198d84b7
LC
732(define (cache! cache package system thunk)
733 "Memoize in CACHE the return values of THUNK as the derivation of PACKAGE on
e509d152 734SYSTEM."
bce7526f
LC
735 ;; FIXME: This memoization should be associated with the open store, because
736 ;; otherwise it breaks when switching to a different store.
e509d152
LC
737 (let ((vals (call-with-values thunk list)))
738 ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
739 ;; same value for all structs (as of Guile 2.0.6), and because pointer
740 ;; equality is sufficient in practice.
198d84b7 741 (hashq-set! cache package
8dcec914 742 `((,system ,@vals)
198d84b7 743 ,@(or (hashq-ref cache package) '())))
e509d152
LC
744 (apply values vals)))
745
198d84b7
LC
746(define-syntax cached
747 (syntax-rules (=>)
748 "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
e509d152 749Return the cached result when available."
198d84b7
LC
750 ((_ (=> cache) package system body ...)
751 (let ((thunk (lambda () body ...))
752 (key system))
753 (match (hashq-ref cache package)
754 ((alist (... ...))
755 (match (assoc-ref alist key)
756 ((vals (... ...))
757 (apply values vals))
758 (#f
759 (cache! cache package key thunk))))
e509d152 760 (#f
198d84b7
LC
761 (cache! cache package key thunk)))))
762 ((_ package system body ...)
763 (cached (=> %derivation-cache) package system body ...))))
a2ebaddd 764
a63062b5
LC
765(define* (expand-input store package input system #:optional cross-system)
766 "Expand INPUT, an input tuple, such that it contains only references to
767derivation paths or store paths. PACKAGE is only used to provide contextual
768information in exceptions."
592ef6c8
LC
769 (define (intern file)
770 ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
771 ;; file permissions are preserved.
a9ebd9ef 772 (add-to-store store (basename file) #t "sha256" file))
592ef6c8 773
a63062b5
LC
774 (define derivation
775 (if cross-system
05962f29
LC
776 (cut package-cross-derivation store <> cross-system system
777 #:graft? #f)
778 (cut package-derivation store <> system #:graft? #f)))
a63062b5
LC
779
780 (match input
781 (((? string? name) (? package? package))
782 (list name (derivation package)))
783 (((? string? name) (? package? package)
784 (? string? sub-drv))
785 (list name (derivation package)
786 sub-drv))
787 (((? string? name)
788 (and (? string?) (? derivation-path?) drv))
789 (list name drv))
790 (((? string? name)
791 (and (? string?) (? file-exists? file)))
792 ;; Add FILE to the store. When FILE is in the sub-directory of a
793 ;; store path, it needs to be added anyway, so it can be used as a
794 ;; source.
795 (list name (intern file)))
da675305 796 (((? string? name) (? struct? source))
a63062b5
LC
797 (list name (package-source-derivation store source system)))
798 (x
799 (raise (condition (&package-input-error
800 (package package)
801 (input x)))))))
592ef6c8 802
9775412e
LC
803(define %bag-cache
804 ;; 'eq?' cache mapping packages to system+target+graft?-dependent bags.
805 ;; It significantly speeds things up when doing repeated calls to
806 ;; 'package->bag' as is the case when building a profile.
807 (make-weak-key-hash-table 200))
808
0d5a559f
LC
809(define* (package->bag package #:optional
810 (system (%current-system))
05962f29
LC
811 (target (%current-target-system))
812 #:key (graft? (%graft?)))
0d5a559f
LC
813 "Compile PACKAGE into a bag for SYSTEM, possibly cross-compiled to TARGET,
814and return it."
9775412e
LC
815 (cached (=> %bag-cache)
816 package (list system target graft?)
817 ;; Bind %CURRENT-SYSTEM and %CURRENT-TARGET-SYSTEM so that thunked
818 ;; field values can refer to it.
819 (parameterize ((%current-system system)
820 (%current-target-system target))
821 (match (if graft?
822 (or (package-replacement package) package)
823 package)
824 (($ <package> name version source build-system
825 args inputs propagated-inputs native-inputs
826 self-native-input? outputs)
827 (or (make-bag build-system (string-append name "-" version)
828 #:system system
829 #:target target
830 #:source source
831 #:inputs (append (inputs)
832 (propagated-inputs))
833 #:outputs outputs
834 #:native-inputs `(,@(if (and target
835 self-native-input?)
836 `(("self" ,package))
837 '())
838 ,@(native-inputs))
839 #:arguments (args))
840 (raise (if target
841 (condition
842 (&package-cross-build-system-error
843 (package package)))
844 (condition
845 (&package-error
846 (package package)))))))))))
0d5a559f 847
ced71ac7
LC
848(define %graft-cache
849 ;; 'eq?' cache mapping package objects to a graft corresponding to their
850 ;; replacement package.
851 (make-weak-key-hash-table 200))
852
05962f29 853(define (input-graft store system)
c22a1324
LC
854 "Return a procedure that, given a package with a graft, returns a graft, and
855#f otherwise."
05962f29 856 (match-lambda
c22a1324
LC
857 ((? package? package)
858 (let ((replacement (package-replacement package)))
859 (and replacement
ced71ac7
LC
860 (cached (=> %graft-cache) package system
861 (let ((orig (package-derivation store package system
862 #:graft? #f))
863 (new (package-derivation store replacement system)))
864 (graft
865 (origin orig)
866 (replacement new)))))))
c22a1324
LC
867 (x
868 #f)))
05962f29
LC
869
870(define (input-cross-graft store target system)
871 "Same as 'input-graft', but for cross-compilation inputs."
872 (match-lambda
c22a1324 873 ((? package? package)
05962f29
LC
874 (let ((replacement (package-replacement package)))
875 (and replacement
876 (let ((orig (package-cross-derivation store package target system
877 #:graft? #f))
878 (new (package-cross-derivation store replacement
879 target system)))
880 (graft
881 (origin orig)
c22a1324 882 (replacement new))))))
05962f29
LC
883 (_
884 #f)))
885
c22a1324
LC
886(define* (fold-bag-dependencies proc seed bag
887 #:key (native? #t))
888 "Fold PROC over the packages BAG depends on. Each package is visited only
889once, in depth-first order. If NATIVE? is true, restrict to native
890dependencies; otherwise, restrict to target dependencies."
891 (define nodes
892 (match (if native?
893 (append (bag-build-inputs bag)
894 (bag-target-inputs bag)
895 (if (bag-target bag)
896 '()
897 (bag-host-inputs bag)))
898 (bag-host-inputs bag))
899 (((labels things _ ...) ...)
900 things)))
901
902 (let loop ((nodes nodes)
903 (result seed)
904 (visited (setq)))
905 (match nodes
906 (()
907 result)
908 (((? package? head) . tail)
909 (if (set-contains? visited head)
910 (loop tail result visited)
911 (let ((inputs (bag-direct-inputs (package->bag head))))
912 (loop (match inputs
913 (((labels things _ ...) ...)
914 (append things tail)))
915 (proc head result)
916 (set-insert head visited)))))
917 ((head . tail)
918 (loop tail result visited)))))
919
05962f29 920(define* (bag-grafts store bag)
c22a1324
LC
921 "Return the list of grafts potentially applicable to BAG. Potentially
922applicable grafts are collected by looking at direct or indirect dependencies
923of BAG that have a 'replacement'. Whether a graft is actually applicable
924depends on whether the outputs of BAG depend on the items the grafts refer
925to (see 'graft-derivation'.)"
926 (define system (bag-system bag))
927 (define target (bag-target bag))
928
929 (define native-grafts
930 (let ((->graft (input-graft store system)))
931 (fold-bag-dependencies (lambda (package grafts)
932 (match (->graft package)
933 (#f grafts)
934 (graft (cons graft grafts))))
935 '()
936 bag)))
937
938 (define target-grafts
939 (if target
940 (let ((->graft (input-cross-graft store target system)))
941 (fold-bag-dependencies (lambda (package grafts)
942 (match (->graft package)
943 (#f grafts)
944 (graft (cons graft grafts))))
945 '()
946 bag
947 #:native? #f))
948 '()))
949
fcadd9ff
LC
950 ;; We can end up with several identical grafts if we stumble upon packages
951 ;; that are not 'eq?' but map to the same derivation (this can happen when
952 ;; using things like 'package-with-explicit-inputs'.) Hence the
953 ;; 'delete-duplicates' call.
954 (delete-duplicates
955 (append native-grafts target-grafts)))
05962f29
LC
956
957(define* (package-grafts store package
958 #:optional (system (%current-system))
959 #:key target)
960 "Return the list of grafts applicable to PACKAGE as built for SYSTEM and
961TARGET."
962 (let* ((package (or (package-replacement package) package))
963 (bag (package->bag package system target)))
964 (bag-grafts store bag)))
965
d3d337d2
LC
966(define* (bag->derivation store bag
967 #:optional context)
968 "Return the derivation to build BAG for SYSTEM. Optionally, CONTEXT can be
969a package object describing the context in which the call occurs, for improved
970error reporting."
971 (if (bag-target bag)
972 (bag->cross-derivation store bag)
973 (let* ((system (bag-system bag))
974 (inputs (bag-transitive-inputs bag))
975 (input-drvs (map (cut expand-input store context <> system)
976 inputs))
977 (paths (delete-duplicates
978 (append-map (match-lambda
979 ((_ (? package? p) _ ...)
980 (package-native-search-paths
981 p))
982 (_ '()))
983 inputs))))
984
985 (apply (bag-build bag)
986 store (bag-name bag) input-drvs
987 #:search-paths paths
988 #:outputs (bag-outputs bag) #:system system
989 (bag-arguments bag)))))
990
991(define* (bag->cross-derivation store bag
992 #:optional context)
993 "Return the derivation to build BAG, which is actually a cross build.
994Optionally, CONTEXT can be a package object denoting the context of the call.
995This is an internal procedure."
996 (let* ((system (bag-system bag))
997 (target (bag-target bag))
998 (host (bag-transitive-host-inputs bag))
999 (host-drvs (map (cut expand-input store context <> system target)
1000 host))
1001 (target* (bag-transitive-target-inputs bag))
1002 (target-drvs (map (cut expand-input store context <> system)
1003 target*))
1004 (build (bag-transitive-build-inputs bag))
1005 (build-drvs (map (cut expand-input store context <> system)
1006 build))
1007 (all (append build target* host))
1008 (paths (delete-duplicates
1009 (append-map (match-lambda
1010 ((_ (? package? p) _ ...)
1011 (package-search-paths p))
1012 (_ '()))
1013 all)))
1014 (npaths (delete-duplicates
1015 (append-map (match-lambda
1016 ((_ (? package? p) _ ...)
1017 (package-native-search-paths
1018 p))
1019 (_ '()))
1020 all))))
1021
1022 (apply (bag-build bag)
1023 store (bag-name bag)
1024 #:native-drvs build-drvs
1025 #:target-drvs (append host-drvs target-drvs)
1026 #:search-paths paths
1027 #:native-search-paths npaths
1028 #:outputs (bag-outputs bag)
1029 #:system system #:target target
1030 (bag-arguments bag))))
1031
a63062b5 1032(define* (package-derivation store package
05962f29
LC
1033 #:optional (system (%current-system))
1034 #:key (graft? (%graft?)))
59688fc4
LC
1035 "Return the <derivation> object of PACKAGE for SYSTEM."
1036
e509d152
LC
1037 ;; Compute the derivation and cache the result. Caching is important
1038 ;; because some derivations, such as the implicit inputs of the GNU build
1039 ;; system, will be queried many, many times in a row.
05962f29
LC
1040 (cached package (cons system graft?)
1041 (let* ((bag (package->bag package system #f #:graft? graft?))
1042 (drv (bag->derivation store bag package)))
1043 (if graft?
1044 (match (bag-grafts store bag)
1045 (()
1046 drv)
1047 (grafts
1048 (let ((guile (package-derivation store (default-guile)
1049 system #:graft? #f)))
c22a1324
LC
1050 ;; TODO: As an optimization, we can simply graft the tip
1051 ;; of the derivation graph since 'graft-derivation'
1052 ;; recurses anyway.
b0fef4d6 1053 (graft-derivation store drv grafts
05962f29
LC
1054 #:system system
1055 #:guile guile))))
1056 drv))))
e3ce5d70 1057
9c1edabd 1058(define* (package-cross-derivation store package target
05962f29
LC
1059 #:optional (system (%current-system))
1060 #:key (graft? (%graft?)))
9c1edabd
LC
1061 "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
1062system identifying string)."
05962f29
LC
1063 (cached package (list system target graft?)
1064 (let* ((bag (package->bag package system target #:graft? graft?))
1065 (drv (bag->derivation store bag package)))
1066 (if graft?
1067 (match (bag-grafts store bag)
1068 (()
1069 drv)
1070 (grafts
b0fef4d6 1071 (graft-derivation store drv grafts
05962f29
LC
1072 #:system system
1073 #:guile
1074 (package-derivation store (default-guile)
1075 system #:graft? #f))))
1076 drv))))
d510ab46 1077
de8bcdae
LC
1078(define* (package-output store package
1079 #:optional (output "out") (system (%current-system)))
d510ab46
LC
1080 "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
1081symbolic output name, such as \"out\". Note that this procedure calls
1082`package-derivation', which is costly."
59688fc4
LC
1083 (let ((drv (package-derivation store package system)))
1084 (derivation->output-path drv output)))
e87f0591
LC
1085
1086\f
1087;;;
1088;;; Monadic interface.
1089;;;
1090
1091(define (set-guile-for-build guile)
1092 "This monadic procedure changes the Guile currently used to run the build
1093code of derivations to GUILE, a package object."
1094 (lambda (store)
1095 (let ((guile (package-derivation store guile)))
4e190c28 1096 (values (%guile-for-build guile) store))))
e87f0591
LC
1097
1098(define* (package-file package
1099 #:optional file
1100 #:key
1101 system (output "out") target)
1102 "Return as a monadic value the absolute file name of FILE within the
1103OUTPUT directory of PACKAGE. When FILE is omitted, return the name of the
1104OUTPUT directory of PACKAGE. When TARGET is true, use it as a
1105cross-compilation target triplet."
1106 (lambda (store)
1107 (define compute-derivation
1108 (if target
1109 (cut package-cross-derivation <> <> target <>)
1110 package-derivation))
1111
1112 (let* ((system (or system (%current-system)))
1113 (drv (compute-derivation store package system))
1114 (out (derivation->output-path drv output)))
4e190c28
LC
1115 (values (if file
1116 (string-append out "/" file)
1117 out)
1118 store))))
e87f0591
LC
1119
1120(define package->derivation
1121 (store-lift package-derivation))
1122
1123(define package->cross-derivation
1124 (store-lift package-cross-derivation))
1125
ff40e9b7
LC
1126(define-gexp-compiler (package-compiler (package package?) system target)
1127 ;; Compile PACKAGE to a derivation for SYSTEM, optionally cross-compiled for
1128 ;; TARGET. This is used when referring to a package from within a gexp.
1129 (if target
1130 (package->cross-derivation package target system)
1131 (package->derivation package system)))
1132
78951064 1133(define* (origin->derivation origin
f220a838 1134 #:optional (system (%current-system)))
78951064
LC
1135 "Return the derivation corresponding to ORIGIN."
1136 (match origin
6b1f9721 1137 (($ <origin> uri method sha256 name (= force ()) #f)
f220a838
LC
1138 ;; No patches, no snippet: this is a fixed-output derivation.
1139 (method uri 'sha256 sha256 name #:system system))
6b1f9721 1140 (($ <origin> uri method sha256 name (= force (patches ...)) snippet
f220a838
LC
1141 (flags ...) inputs (modules ...) (imported-modules ...)
1142 guile-for-build)
1143 ;; Patches and/or a snippet.
1144 (mlet %store-monad ((source (method uri 'sha256 sha256 name
1145 #:system system))
1146 (guile (package->derivation (or guile-for-build
1147 (default-guile))
1148 system
1149 #:graft? #f)))
cf87cc89
LC
1150 (patch-and-repack source patches
1151 #:inputs inputs
1152 #:snippet snippet
1153 #:flags flags
1154 #:system system
1155 #:modules modules
a7db719f 1156 #:imported-modules imported-modules
78951064 1157 #:guile-for-build guile)))))
f220a838 1158
ff40e9b7
LC
1159(define-gexp-compiler (origin-compiler (origin origin?) system target)
1160 ;; Compile ORIGIN to a derivation for SYSTEM. This is used when referring
1161 ;; to an origin from within a gexp.
1162 (origin->derivation origin system))
1163
78951064 1164(define package-source-derivation ;somewhat deprecated
da675305 1165 (let ((lower (store-lower lower-object)))
78951064
LC
1166 (lambda* (store source #:optional (system (%current-system)))
1167 "Return the derivation or file corresponding to SOURCE, which can be an
da675305
LC
1168a file name or any object handled by 'lower-object', such as an <origin>.
1169When SOURCE is a file name, return either the interned file name (if SOURCE is
1170outside of the store) or SOURCE itself (if SOURCE is already a store item.)"
78951064
LC
1171 (match source
1172 ((and (? string?) (? direct-store-path?) file)
1173 file)
1174 ((? string? file)
1175 (add-to-store store (basename file) #t "sha256" file))
1176 (_
1177 (lower store source system))))))