You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

696 lines
29 KiB

  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2012, 2013, 2014 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. (define-module (guix packages)
  19. #:use-module (guix utils)
  20. #:use-module (guix records)
  21. #:use-module (guix store)
  22. #:use-module (guix base32)
  23. #:use-module (guix derivations)
  24. #:use-module (guix build-system)
  25. #:use-module (ice-9 match)
  26. #:use-module (srfi srfi-1)
  27. #:use-module (srfi srfi-9 gnu)
  28. #:use-module (srfi srfi-26)
  29. #:use-module (srfi srfi-34)
  30. #:use-module (srfi srfi-35)
  31. #:re-export (%current-system
  32. %current-target-system)
  33. #:export (origin
  34. origin?
  35. origin-uri
  36. origin-method
  37. origin-sha256
  38. origin-file-name
  39. origin-patches
  40. origin-patch-flags
  41. origin-patch-inputs
  42. origin-patch-guile
  43. origin-snippet
  44. origin-modules
  45. origin-imported-modules
  46. base32
  47. <search-path-specification>
  48. search-path-specification
  49. search-path-specification?
  50. search-path-specification->sexp
  51. package
  52. package?
  53. package-name
  54. package-version
  55. package-full-name
  56. package-source
  57. package-build-system
  58. package-arguments
  59. package-inputs
  60. package-native-inputs
  61. package-propagated-inputs
  62. package-outputs
  63. package-native-search-paths
  64. package-search-paths
  65. package-synopsis
  66. package-description
  67. package-license
  68. package-home-page
  69. package-platforms
  70. package-maintainers
  71. package-properties
  72. package-location
  73. package-field-location
  74. package-direct-inputs
  75. package-transitive-inputs
  76. package-transitive-target-inputs
  77. package-transitive-native-inputs
  78. package-transitive-propagated-inputs
  79. package-source-derivation
  80. package-derivation
  81. package-cross-derivation
  82. package-output
  83. &package-error
  84. package-error?
  85. package-error-package
  86. &package-input-error
  87. package-input-error?
  88. package-error-invalid-input
  89. &package-cross-build-system-error
  90. package-cross-build-system-error?))
  91. ;;; Commentary:
  92. ;;;
  93. ;;; This module provides a high-level mechanism to define packages in a
  94. ;;; Guix-based distribution.
  95. ;;;
  96. ;;; Code:
  97. ;; The source of a package, such as a tarball URL and fetcher---called
  98. ;; "origin" to avoid name clash with `package-source', `source', etc.
  99. (define-record-type* <origin>
  100. origin make-origin
  101. origin?
  102. (uri origin-uri) ; string
  103. (method origin-method) ; procedure
  104. (sha256 origin-sha256) ; bytevector
  105. (file-name origin-file-name (default #f)) ; optional file name
  106. (patches origin-patches (default '())) ; list of file names
  107. (snippet origin-snippet (default #f)) ; sexp or #f
  108. (patch-flags origin-patch-flags ; list of strings
  109. (default '("-p1")))
  110. ;; Patching requires Guile, GNU Patch, and a few more. These two fields are
  111. ;; used to specify these dependencies when needed.
  112. (patch-inputs origin-patch-inputs ; input list or #f
  113. (default #f))
  114. (modules origin-modules ; list of module names
  115. (default '()))
  116. (imported-modules origin-imported-modules ; list of module names
  117. (default '()))
  118. (patch-guile origin-patch-guile ; package or #f
  119. (default #f)))
  120. (define (print-origin origin port)
  121. "Write a concise representation of ORIGIN to PORT."
  122. (match origin
  123. (($ <origin> uri method sha256 file-name patches)
  124. (simple-format port "#<origin ~s ~a ~s ~a>"
  125. uri (bytevector->base32-string sha256)
  126. patches
  127. (number->string (object-address origin) 16)))))
  128. (set-record-type-printer! <origin> print-origin)
  129. (define-syntax base32
  130. (lambda (s)
  131. "Return the bytevector corresponding to the given Nix-base32
  132. representation."
  133. (syntax-case s ()
  134. ((_ str)
  135. (string? (syntax->datum #'str))
  136. ;; A literal string: do the conversion at expansion time.
  137. (with-syntax ((bv (nix-base32-string->bytevector
  138. (syntax->datum #'str))))
  139. #''bv))
  140. ((_ str)
  141. #'(nix-base32-string->bytevector str)))))
  142. ;; The specification of a search path.
  143. (define-record-type* <search-path-specification>
  144. search-path-specification make-search-path-specification
  145. search-path-specification?
  146. (variable search-path-specification-variable)
  147. (directories search-path-specification-directories)
  148. (separator search-path-specification-separator (default ":")))
  149. (define (search-path-specification->sexp spec)
  150. "Return an sexp representing SPEC, a <search-path-specification>. The sexp
  151. corresponds to the arguments expected by `set-path-environment-variable'."
  152. (match spec
  153. (($ <search-path-specification> variable directories separator)
  154. `(,variable ,directories ,separator))))
  155. ;; A package.
  156. (define-record-type* <package>
  157. package make-package
  158. package?
  159. (name package-name) ; string
  160. (version package-version) ; string
  161. (source package-source) ; <origin> instance
  162. (build-system package-build-system) ; build system
  163. (arguments package-arguments ; arguments for the build method
  164. (default '()) (thunked))
  165. (inputs package-inputs ; input packages or derivations
  166. (default '()) (thunked))
  167. (propagated-inputs package-propagated-inputs ; same, but propagated
  168. (default '()) (thunked))
  169. (native-inputs package-native-inputs ; native input packages/derivations
  170. (default '()) (thunked))
  171. (self-native-input? package-self-native-input? ; whether to use itself as
  172. ; a native input when cross-
  173. (default #f)) ; compiling
  174. (outputs package-outputs ; list of strings
  175. (default '("out")))
  176. ; lists of
  177. ; <search-path-specification>,
  178. ; for native and cross
  179. ; inputs
  180. (native-search-paths package-native-search-paths (default '()))
  181. (search-paths package-search-paths (default '()))
  182. (synopsis package-synopsis) ; one-line description
  183. (description package-description) ; one or two paragraphs
  184. (license package-license)
  185. (home-page package-home-page)
  186. (platforms package-platforms (default '()))
  187. (maintainers package-maintainers (default '()))
  188. (properties package-properties (default '())) ; alist for anything else
  189. (location package-location
  190. (default (and=> (current-source-location)
  191. source-properties->location))))
  192. (set-record-type-printer! <package>
  193. (lambda (package port)
  194. (let ((loc (package-location package))
  195. (format simple-format))
  196. (format port "#<package ~a-~a ~a:~a ~a>"
  197. (package-name package)
  198. (package-version package)
  199. (location-file loc)
  200. (location-line loc)
  201. (number->string (object-address
  202. package)
  203. 16)))))
  204. (define (package-field-location package field)
  205. "Return the source code location of the definition of FIELD for PACKAGE, or
  206. #f if it could not be determined."
  207. (define (goto port line column)
  208. (unless (and (= (port-column port) (- column 1))
  209. (= (port-line port) (- line 1)))
  210. (unless (eof-object? (read-char port))
  211. (goto port line column))))
  212. (match (package-location package)
  213. (($ <location> file line column)
  214. (catch 'system
  215. (lambda ()
  216. ;; In general we want to keep relative file names for modules.
  217. (with-fluids ((%file-port-name-canonicalization 'relative))
  218. (call-with-input-file (search-path %load-path file)
  219. (lambda (port)
  220. (goto port line column)
  221. (match (read port)
  222. (('package inits ...)
  223. (let ((field (assoc field inits)))
  224. (match field
  225. ((_ value)
  226. ;; Put the `or' here, and not in the first argument of
  227. ;; `and=>', to work around a compiler bug in 2.0.5.
  228. (or (and=> (source-properties value)
  229. source-properties->location)
  230. (and=> (source-properties field)
  231. source-properties->location)))
  232. (_
  233. #f))))
  234. (_
  235. #f))))))
  236. (lambda _
  237. #f)))
  238. (_ #f)))
  239. ;; Error conditions.
  240. (define-condition-type &package-error &error
  241. package-error?
  242. (package package-error-package))
  243. (define-condition-type &package-input-error &package-error
  244. package-input-error?
  245. (input package-error-invalid-input))
  246. (define-condition-type &package-cross-build-system-error &package-error
  247. package-cross-build-system-error?)
  248. (define (package-full-name package)
  249. "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
  250. (string-append (package-name package) "-" (package-version package)))
  251. (define (%standard-patch-inputs)
  252. (let ((ref (lambda (module var)
  253. (module-ref (resolve-interface module) var))))
  254. `(("tar" ,(ref '(gnu packages base) 'tar))
  255. ("xz" ,(ref '(gnu packages compression) 'xz))
  256. ("bzip2" ,(ref '(gnu packages compression) 'bzip2))
  257. ("gzip" ,(ref '(gnu packages compression) 'gzip))
  258. ("lzip" ,(ref '(gnu packages compression) 'lzip))
  259. ("patch" ,(ref '(gnu packages base) 'patch)))))
  260. (define (default-guile)
  261. "Return the default Guile package for SYSTEM."
  262. (let ((distro (resolve-interface '(gnu packages commencement))))
  263. (module-ref distro 'guile-final)))
  264. (define* (patch-and-repack store source patches
  265. #:key
  266. (inputs '())
  267. (snippet #f)
  268. (flags '("-p1"))
  269. (modules '())
  270. (imported-modules '())
  271. (guile-for-build (%guile-for-build))
  272. (system (%current-system)))
  273. "Unpack SOURCE (a derivation or store path), apply all of PATCHES, and
  274. repack the tarball using the tools listed in INPUTS. When SNIPPET is true,
  275. it must be an s-expression that will run from within the directory where
  276. SOURCE was unpacked, after all of PATCHES have been applied. MODULES and
  277. IMPORTED-MODULES specify modules to use/import for use by SNIPPET."
  278. (define source-file-name
  279. ;; SOURCE is usually a derivation, but it could be a store file.
  280. (if (derivation? source)
  281. (derivation->output-path source)
  282. source))
  283. (define decompression-type
  284. (cond ((string-suffix? "gz" source-file-name) "gzip")
  285. ((string-suffix? "bz2" source-file-name) "bzip2")
  286. ((string-suffix? "lz" source-file-name) "lzip")
  287. (else "xz")))
  288. (define original-file-name
  289. ;; Remove the store prefix plus the slash, hash, and hyphen.
  290. (let* ((sans (string-drop source-file-name
  291. (+ (string-length (%store-prefix)) 1)))
  292. (dash (string-index sans #\-)))
  293. (string-drop sans (+ 1 dash))))
  294. (define (numeric-extension? file-name)
  295. ;; Return true if FILE-NAME ends with digits.
  296. (and=> (file-extension file-name)
  297. (cut string-every char-set:hex-digit <>)))
  298. (define (tarxz-name file-name)
  299. ;; Return a '.tar.xz' file name based on FILE-NAME.
  300. (let ((base (if (numeric-extension? file-name)
  301. original-file-name
  302. (file-sans-extension file-name))))
  303. (string-append base
  304. (if (equal? (file-extension base) "tar")
  305. ".xz"
  306. ".tar.xz"))))
  307. (define patch-inputs
  308. (map (lambda (number patch)
  309. (list (string-append "patch" (number->string number))
  310. (match patch
  311. ((? string?)
  312. (add-to-store store (basename patch) #t
  313. "sha256" patch))
  314. ((? origin?)
  315. (package-source-derivation store patch)))))
  316. (iota (length patches))
  317. patches))
  318. (define builder
  319. `(begin
  320. (use-modules (ice-9 ftw)
  321. (srfi srfi-1)
  322. (guix build utils))
  323. (let ((out (assoc-ref %outputs "out"))
  324. (xz (assoc-ref %build-inputs "xz"))
  325. (decomp (assoc-ref %build-inputs ,decompression-type))
  326. (source (assoc-ref %build-inputs "source"))
  327. (tar (string-append (assoc-ref %build-inputs "tar")
  328. "/bin/tar"))
  329. (patch (string-append (assoc-ref %build-inputs "patch")
  330. "/bin/patch")))
  331. (define (apply-patch input)
  332. (let ((patch* (assoc-ref %build-inputs input)))
  333. (format (current-error-port) "applying '~a'...~%" patch*)
  334. (zero? (system* patch "--batch" ,@flags "--input" patch*))))
  335. (define (first-file directory)
  336. ;; Return the name of the first file in DIRECTORY.
  337. (car (scandir directory
  338. (lambda (name)
  339. (not (member name '("." "..")))))))
  340. (setenv "PATH" (string-append xz "/bin" ":"
  341. decomp "/bin"))
  342. ;; SOURCE may be either a directory or a tarball.
  343. (and (if (file-is-directory? source)
  344. (let* ((store (or (getenv "NIX_STORE") "/gnu/store"))
  345. (len (+ 1 (string-length store)))
  346. (base (string-drop source len))
  347. (dash (string-index base #\-))
  348. (directory (string-drop base (+ 1 dash))))
  349. (mkdir directory)
  350. (copy-recursively source directory)
  351. #t)
  352. (zero? (system* tar "xvf" source)))
  353. (let ((directory (first-file ".")))
  354. (format (current-error-port)
  355. "source is under '~a'~%" directory)
  356. (chdir directory)
  357. (and (every apply-patch ',(map car patch-inputs))
  358. ,@(if snippet
  359. `((let ((module (make-fresh-user-module)))
  360. (module-use-interfaces! module
  361. (map resolve-interface
  362. ',modules))
  363. (module-define! module '%build-inputs
  364. %build-inputs)
  365. (module-define! module '%outputs %outputs)
  366. ((@ (system base compile) compile)
  367. ',snippet
  368. #:to 'value
  369. #:opts %auto-compilation-options
  370. #:env module)))
  371. '())
  372. (begin (chdir "..") #t)
  373. (zero? (system* tar "cvfa" out directory))))))))
  374. (let ((name (tarxz-name original-file-name))
  375. (inputs (filter-map (match-lambda
  376. ((name (? package? p))
  377. (and (member name (cons decompression-type
  378. '("tar" "xz" "patch")))
  379. (list name
  380. (package-derivation store p
  381. system)))))
  382. (or inputs (%standard-patch-inputs))))
  383. (modules (delete-duplicates (cons '(guix build utils) modules))))
  384. (build-expression->derivation store name builder
  385. #:inputs `(("source" ,source)
  386. ,@inputs
  387. ,@patch-inputs)
  388. #:system system
  389. #:modules modules
  390. #:guile-for-build guile-for-build)))
  391. (define* (package-source-derivation store source
  392. #:optional (system (%current-system)))
  393. "Return the derivation path for SOURCE, a package source, for SYSTEM."
  394. (match source
  395. (($ <origin> uri method sha256 name () #f)
  396. ;; No patches, no snippet: this is a fixed-output derivation.
  397. (method store uri 'sha256 sha256 name
  398. #:system system))
  399. (($ <origin> uri method sha256 name (patches ...) snippet
  400. (flags ...) inputs (modules ...) (imported-modules ...)
  401. guile-for-build)
  402. ;; Patches and/or a snippet.
  403. (let ((source (method store uri 'sha256 sha256 name
  404. #:system system))
  405. (guile (match (or guile-for-build (%guile-for-build)
  406. (default-guile))
  407. ((? package? p)
  408. (package-derivation store p system))
  409. ((? derivation? drv)
  410. drv))))
  411. (patch-and-repack store source patches
  412. #:inputs inputs
  413. #:snippet snippet
  414. #:flags flags
  415. #:system system
  416. #:modules modules
  417. #:imported-modules modules
  418. #:guile-for-build guile)))
  419. ((and (? string?) (? direct-store-path?) file)
  420. file)
  421. ((? string? file)
  422. (add-to-store store (basename file) #t "sha256" file))))
  423. (define (transitive-inputs inputs)
  424. (let loop ((inputs inputs)
  425. (result '()))
  426. (match inputs
  427. (()
  428. (delete-duplicates (reverse result))) ; XXX: efficiency
  429. (((and i (name (? package? p) sub ...)) rest ...)
  430. (let ((t (map (match-lambda
  431. ((dep-name derivation ...)
  432. (cons (string-append name "/" dep-name)
  433. derivation)))
  434. (package-propagated-inputs p))))
  435. (loop (append t rest)
  436. (append t (cons i result)))))
  437. ((input rest ...)
  438. (loop rest (cons input result))))))
  439. (define (package-direct-inputs package)
  440. "Return all the direct inputs of PACKAGE---i.e, its direct inputs along
  441. with their propagated inputs."
  442. (append (package-native-inputs package)
  443. (package-inputs package)
  444. (package-propagated-inputs package)))
  445. (define (package-transitive-inputs package)
  446. "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
  447. with their propagated inputs, recursively."
  448. (transitive-inputs (package-direct-inputs package)))
  449. (define (package-transitive-target-inputs package)
  450. "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
  451. along with their propagated inputs, recursively. This only includes inputs
  452. for the target system, and not native inputs."
  453. (transitive-inputs (append (package-inputs package)
  454. (package-propagated-inputs package))))
  455. (define (package-transitive-native-inputs package)
  456. "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
  457. along with their propagated inputs, recursively. This only includes inputs
  458. for the host system (\"native inputs\"), and not target inputs."
  459. (transitive-inputs (package-native-inputs package)))
  460. (define (package-transitive-propagated-inputs package)
  461. "Return the propagated inputs of PACKAGE, and their propagated inputs,
  462. recursively."
  463. (transitive-inputs (package-propagated-inputs package)))
  464. ;;;
  465. ;;; Package derivations.
  466. ;;;
  467. (define %derivation-cache
  468. ;; Package to derivation-path mapping.
  469. (make-weak-key-hash-table 100))
  470. (define (cache package system thunk)
  471. "Memoize the return values of THUNK as the derivation of PACKAGE on
  472. SYSTEM."
  473. ;; FIXME: This memoization should be associated with the open store, because
  474. ;; otherwise it breaks when switching to a different store.
  475. (let ((vals (call-with-values thunk list)))
  476. ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
  477. ;; same value for all structs (as of Guile 2.0.6), and because pointer
  478. ;; equality is sufficient in practice.
  479. (hashq-set! %derivation-cache package `((,system ,@vals)))
  480. (apply values vals)))
  481. (define-syntax-rule (cached package system body ...)
  482. "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
  483. Return the cached result when available."
  484. (let ((thunk (lambda () body ...)))
  485. (match (hashq-ref %derivation-cache package)
  486. ((alist (... ...))
  487. (match (assoc-ref alist system)
  488. ((vals (... ...))
  489. (apply values vals))
  490. (#f
  491. (cache package system thunk))))
  492. (#f
  493. (cache package system thunk)))))
  494. (define* (expand-input store package input system #:optional cross-system)
  495. "Expand INPUT, an input tuple, such that it contains only references to
  496. derivation paths or store paths. PACKAGE is only used to provide contextual
  497. information in exceptions."
  498. (define (intern file)
  499. ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
  500. ;; file permissions are preserved.
  501. (add-to-store store (basename file) #t "sha256" file))
  502. (define derivation
  503. (if cross-system
  504. (cut package-cross-derivation store <> cross-system system)
  505. (cut package-derivation store <> system)))
  506. (match input
  507. (((? string? name) (? package? package))
  508. (list name (derivation package)))
  509. (((? string? name) (? package? package)
  510. (? string? sub-drv))
  511. (list name (derivation package)
  512. sub-drv))
  513. (((? string? name)
  514. (and (? string?) (? derivation-path?) drv))
  515. (list name drv))
  516. (((? string? name)
  517. (and (? string?) (? file-exists? file)))
  518. ;; Add FILE to the store. When FILE is in the sub-directory of a
  519. ;; store path, it needs to be added anyway, so it can be used as a
  520. ;; source.
  521. (list name (intern file)))
  522. (((? string? name) (? origin? source))
  523. (list name (package-source-derivation store source system)))
  524. (x
  525. (raise (condition (&package-input-error
  526. (package package)
  527. (input x)))))))
  528. (define* (package-derivation store package
  529. #:optional (system (%current-system)))
  530. "Return the <derivation> object of PACKAGE for SYSTEM."
  531. ;; Compute the derivation and cache the result. Caching is important
  532. ;; because some derivations, such as the implicit inputs of the GNU build
  533. ;; system, will be queried many, many times in a row.
  534. (cached package system
  535. ;; Bind %CURRENT-SYSTEM so that thunked field values can refer
  536. ;; to it.
  537. (parameterize ((%current-system system)
  538. (%current-target-system #f))
  539. (match package
  540. (($ <package> name version source (= build-system-builder builder)
  541. args inputs propagated-inputs native-inputs self-native-input?
  542. outputs)
  543. (let* ((inputs (package-transitive-inputs package))
  544. (input-drvs (map (cut expand-input
  545. store package <> system)
  546. inputs))
  547. (paths (delete-duplicates
  548. (append-map (match-lambda
  549. ((_ (? package? p) _ ...)
  550. (package-native-search-paths
  551. p))
  552. (_ '()))
  553. inputs))))
  554. (apply builder
  555. store (package-full-name package)
  556. (and source
  557. (package-source-derivation store source system))
  558. input-drvs
  559. #:search-paths paths
  560. #:outputs outputs #:system system
  561. (args))))))))
  562. (define* (package-cross-derivation store package target
  563. #:optional (system (%current-system)))
  564. "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
  565. system identifying string)."
  566. (cached package (cons system target)
  567. ;; Bind %CURRENT-SYSTEM so that thunked field values can refer
  568. ;; to it.
  569. (parameterize ((%current-system system)
  570. (%current-target-system target))
  571. (match package
  572. (($ <package> name version source
  573. (= build-system-cross-builder builder)
  574. args inputs propagated-inputs native-inputs self-native-input?
  575. outputs)
  576. (unless builder
  577. (raise (condition
  578. (&package-cross-build-system-error
  579. (package package)))))
  580. (let* ((inputs (package-transitive-target-inputs package))
  581. (input-drvs (map (cut expand-input
  582. store package <>
  583. system target)
  584. inputs))
  585. (host (append (if self-native-input?
  586. `(("self" ,package))
  587. '())
  588. (package-transitive-native-inputs package)))
  589. (host-drvs (map (cut expand-input
  590. store package <> system)
  591. host))
  592. (all (append host inputs))
  593. (paths (delete-duplicates
  594. (append-map (match-lambda
  595. ((_ (? package? p) _ ...)
  596. (package-search-paths p))
  597. (_ '()))
  598. all)))
  599. (npaths (delete-duplicates
  600. (append-map (match-lambda
  601. ((_ (? package? p) _ ...)
  602. (package-native-search-paths
  603. p))
  604. (_ '()))
  605. all))))
  606. (apply builder
  607. store (package-full-name package) target
  608. (and source
  609. (package-source-derivation store source system))
  610. input-drvs host-drvs
  611. #:search-paths paths
  612. #:native-search-paths npaths
  613. #:outputs outputs #:system system
  614. (args))))))))
  615. (define* (package-output store package
  616. #:optional (output "out") (system (%current-system)))
  617. "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
  618. symbolic output name, such as \"out\". Note that this procedure calls
  619. `package-derivation', which is costly."
  620. (let ((drv (package-derivation store package system)))
  621. (derivation->output-path drv output)))