packages.scm 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2014, 2015, 2017, 2018 Mark H Weaver <mhw@netris.org>
  4. ;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org>
  5. ;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
  6. ;;; Copyright © 2017, 2019, 2020 Efraim Flashner <efraim@flashner.co.il>
  7. ;;; Copyright © 2019 Marius Bakke <mbakke@fastmail.com>
  8. ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
  9. ;;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
  10. ;;;
  11. ;;; This file is part of GNU Guix.
  12. ;;;
  13. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  14. ;;; under the terms of the GNU General Public License as published by
  15. ;;; the Free Software Foundation; either version 3 of the License, or (at
  16. ;;; your option) any later version.
  17. ;;;
  18. ;;; GNU Guix is distributed in the hope that it will be useful, but
  19. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. ;;; GNU General Public License for more details.
  22. ;;;
  23. ;;; You should have received a copy of the GNU General Public License
  24. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  25. (define-module (guix packages)
  26. #:use-module ((guix build utils) #:select (compressor tarball?
  27. strip-store-file-name))
  28. #:use-module (guix utils)
  29. #:use-module (guix records)
  30. #:use-module (guix store)
  31. #:use-module (guix monads)
  32. #:use-module (guix gexp)
  33. #:use-module (guix base32)
  34. #:autoload (guix base64) (base64-decode)
  35. #:use-module (guix grafts)
  36. #:use-module (guix derivations)
  37. #:use-module (guix memoization)
  38. #:use-module (guix build-system)
  39. #:use-module (guix search-paths)
  40. #:use-module (guix sets)
  41. #:use-module (guix deprecation)
  42. #:use-module (guix i18n)
  43. #:use-module (ice-9 match)
  44. #:use-module (ice-9 vlist)
  45. #:use-module (ice-9 regex)
  46. #:use-module (srfi srfi-1)
  47. #:use-module (srfi srfi-9 gnu)
  48. #:use-module (srfi srfi-11)
  49. #:use-module (srfi srfi-26)
  50. #:use-module (srfi srfi-34)
  51. #:use-module (srfi srfi-35)
  52. #:use-module (rnrs bytevectors)
  53. #:use-module (web uri)
  54. #:re-export (%current-system
  55. %current-target-system
  56. search-path-specification) ;for convenience
  57. #:export (content-hash
  58. content-hash?
  59. content-hash-algorithm
  60. content-hash-value
  61. origin
  62. origin?
  63. this-origin
  64. origin-uri
  65. origin-method
  66. origin-hash
  67. origin-sha256 ;deprecated
  68. origin-file-name
  69. origin-actual-file-name
  70. origin-patches
  71. origin-patch-flags
  72. origin-patch-inputs
  73. origin-patch-guile
  74. origin-snippet
  75. origin-modules
  76. base32
  77. base64
  78. package
  79. package?
  80. this-package
  81. package-name
  82. package-upstream-name
  83. package-version
  84. package-full-name
  85. package-source
  86. package-build-system
  87. package-arguments
  88. package-inputs
  89. package-native-inputs
  90. package-propagated-inputs
  91. package-outputs
  92. package-native-search-paths
  93. package-search-paths
  94. package-replacement
  95. package-synopsis
  96. package-description
  97. package-license
  98. package-home-page
  99. package-supported-systems
  100. package-properties
  101. package-location
  102. hidden-package
  103. hidden-package?
  104. package-superseded
  105. deprecated-package
  106. package-field-location
  107. package-direct-sources
  108. package-transitive-sources
  109. package-direct-inputs
  110. package-transitive-inputs
  111. package-transitive-target-inputs
  112. package-transitive-native-inputs
  113. package-transitive-propagated-inputs
  114. package-transitive-native-search-paths
  115. package-transitive-supported-systems
  116. package-mapping
  117. package-input-rewriting
  118. package-input-rewriting/spec
  119. package-source-derivation
  120. package-derivation
  121. package-cross-derivation
  122. package-output
  123. package-grafts
  124. package-patched-vulnerabilities
  125. package-with-patches
  126. package-with-extra-patches
  127. package-with-c-toolchain
  128. package/inherit
  129. transitive-input-references
  130. %supported-systems
  131. %hurd-systems
  132. %cuirass-supported-systems
  133. supported-package?
  134. &package-error
  135. package-error?
  136. package-error-package
  137. &package-input-error
  138. package-input-error?
  139. package-error-invalid-input
  140. &package-cross-build-system-error
  141. package-cross-build-system-error?
  142. package->bag
  143. bag->derivation
  144. bag-direct-inputs
  145. bag-transitive-inputs
  146. bag-transitive-host-inputs
  147. bag-transitive-build-inputs
  148. bag-transitive-target-inputs
  149. package-closure
  150. default-guile
  151. default-guile-derivation
  152. set-guile-for-build
  153. package-file
  154. package->derivation
  155. package->cross-derivation
  156. origin->derivation))
  157. ;;; Commentary:
  158. ;;;
  159. ;;; This module provides a high-level mechanism to define packages in a
  160. ;;; Guix-based distribution.
  161. ;;;
  162. ;;; Code:
  163. (define-syntax-rule (define-compile-time-decoder name string->bytevector)
  164. "Define NAME as a macro that runs STRING->BYTEVECTOR at macro expansion time
  165. if possible."
  166. (define-syntax name
  167. (lambda (s)
  168. "Return the bytevector corresponding to the given textual
  169. representation."
  170. (syntax-case s ()
  171. ((_ str)
  172. (string? (syntax->datum #'str))
  173. ;; A literal string: do the conversion at expansion time.
  174. (with-syntax ((bv (string->bytevector (syntax->datum #'str))))
  175. #''bv))
  176. ((_ str)
  177. #'(string->bytevector str))))))
  178. (define-compile-time-decoder base32 nix-base32-string->bytevector)
  179. (define-compile-time-decoder base64 base64-decode)
  180. ;; Crytographic content hash.
  181. (define-immutable-record-type <content-hash>
  182. (%content-hash algorithm value)
  183. content-hash?
  184. (algorithm content-hash-algorithm) ;symbol
  185. (value content-hash-value)) ;bytevector
  186. (define-syntax-rule (define-content-hash-constructor name
  187. (algorithm size) ...)
  188. "Define NAME as a <content-hash> constructor that ensures that (1) its
  189. second argument is among the listed ALGORITHM, and (2), when possible, that
  190. its first argument has the right size for the chosen algorithm."
  191. (define-syntax name
  192. (lambda (s)
  193. (syntax-case s (algorithm ...)
  194. ((_ bv algorithm)
  195. (let ((bv* (syntax->datum #'bv)))
  196. (when (and (bytevector? bv*)
  197. (not (= size (bytevector-length bv*))))
  198. (syntax-violation 'content-hash "invalid content hash length" s))
  199. #'(%content-hash 'algorithm bv)))
  200. ...))))
  201. (define-content-hash-constructor build-content-hash
  202. (sha256 32)
  203. (sha512 64)
  204. (sha3-256 32)
  205. (sha3-512 64)
  206. (blake2s-256 64))
  207. (define-syntax content-hash
  208. (lambda (s)
  209. "Return a content hash with the given parameters. The default hash
  210. algorithm is sha256. If the first argument is a literal string, it is decoded
  211. as base32. Otherwise, it must be a bytevector."
  212. ;; What we'd really want here is something like C++ 'constexpr'.
  213. (syntax-case s ()
  214. ((_ str)
  215. (string? (syntax->datum #'str))
  216. #'(content-hash str sha256))
  217. ((_ str algorithm)
  218. (string? (syntax->datum #'str))
  219. (with-syntax ((bv (base32 (syntax->datum #'str))))
  220. #'(content-hash bv algorithm)))
  221. ((_ (id str) algorithm)
  222. (and (string? (syntax->datum #'str))
  223. (free-identifier=? #'id #'base32))
  224. (with-syntax ((bv (nix-base32-string->bytevector (syntax->datum #'str))))
  225. #'(content-hash bv algorithm)))
  226. ((_ (id str) algorithm)
  227. (and (string? (syntax->datum #'str))
  228. (free-identifier=? #'id #'base64))
  229. (with-syntax ((bv (base64-decode (syntax->datum #'str))))
  230. #'(content-hash bv algorithm)))
  231. ((_ bv)
  232. #'(content-hash bv sha256))
  233. ((_ bv hash)
  234. #'(build-content-hash bv hash)))))
  235. (define (print-content-hash hash port)
  236. (format port "#<content-hash ~a:~a>"
  237. (content-hash-algorithm hash)
  238. (and=> (content-hash-value hash)
  239. bytevector->nix-base32-string)))
  240. (set-record-type-printer! <content-hash> print-content-hash)
  241. ;; The source of a package, such as a tarball URL and fetcher---called
  242. ;; "origin" to avoid name clash with `package-source', `source', etc.
  243. (define-record-type* <origin>
  244. %origin make-origin
  245. origin?
  246. this-origin
  247. (uri origin-uri) ; string
  248. (method origin-method) ; procedure
  249. (hash origin-hash) ; <content-hash>
  250. (file-name origin-file-name (default #f)) ; optional file name
  251. ;; Patches are delayed so that the 'search-patch' calls are made lazily,
  252. ;; which reduces I/O on startup and allows patch-not-found errors to be
  253. ;; gracefully handled at run time.
  254. (patches origin-patches ; list of file names
  255. (default '()) (delayed))
  256. (snippet origin-snippet (default #f)) ; sexp or #f
  257. (patch-flags origin-patch-flags ; string-list gexp
  258. (default %default-patch-flags))
  259. ;; Patching requires Guile, GNU Patch, and a few more. These two fields are
  260. ;; used to specify these dependencies when needed.
  261. (patch-inputs origin-patch-inputs ; input list or #f
  262. (default #f))
  263. (modules origin-modules ; list of module names
  264. (default '()))
  265. (patch-guile origin-patch-guile ; package or #f
  266. (default #f)))
  267. (define-syntax origin-compatibility-helper
  268. (syntax-rules (sha256)
  269. ((_ () (fields ...))
  270. (%origin fields ...))
  271. ((_ ((sha256 exp) rest ...) (others ...))
  272. (%origin others ...
  273. (hash (content-hash exp sha256))
  274. rest ...))
  275. ((_ (field rest ...) (others ...))
  276. (origin-compatibility-helper (rest ...)
  277. (others ... field)))))
  278. (define-syntax-rule (origin fields ...)
  279. "Build an <origin> record, automatically converting 'sha256' field
  280. specifications to 'hash'."
  281. (origin-compatibility-helper (fields ...) ()))
  282. (define-deprecated (origin-sha256 origin)
  283. origin-hash
  284. (let ((hash (origin-hash origin)))
  285. (unless (eq? (content-hash-algorithm hash) 'sha256)
  286. (raise (condition (&message
  287. (message (G_ "no SHA256 hash for origin"))))))
  288. (content-hash-value hash)))
  289. (define (print-origin origin port)
  290. "Write a concise representation of ORIGIN to PORT."
  291. (match origin
  292. (($ <origin> uri method hash file-name patches)
  293. (simple-format port "#<origin ~s ~a ~s ~a>"
  294. uri hash
  295. (force patches)
  296. (number->string (object-address origin) 16)))))
  297. (set-record-type-printer! <origin> print-origin)
  298. (define %default-patch-flags
  299. #~("-p1"))
  300. (define (origin-actual-file-name origin)
  301. "Return the file name of ORIGIN, either its 'file-name' field or the file
  302. name of its URI."
  303. (define (uri->file-name uri)
  304. ;; Return the 'base name' of URI or URI itself, where URI is a string.
  305. (let ((path (and=> (string->uri uri) uri-path)))
  306. (if path
  307. (basename path)
  308. uri)))
  309. (or (origin-file-name origin)
  310. (match (origin-uri origin)
  311. ((head . tail)
  312. (uri->file-name head))
  313. ((? string? uri)
  314. (uri->file-name uri))
  315. (else
  316. ;; git, svn, cvs, etc. reference
  317. #f))))
  318. (define %supported-systems
  319. ;; This is the list of system types that are supported. By default, we
  320. ;; expect all packages to build successfully here.
  321. '("x86_64-linux" "i686-linux" "armhf-linux" "aarch64-linux" "mips64el-linux" "i586-gnu"
  322. "powerpc64le-linux"))
  323. (define %hurd-systems
  324. ;; The GNU/Hurd systems for which support is being developed.
  325. '("i586-gnu" "i686-gnu"))
  326. (define %cuirass-supported-systems
  327. ;; This is the list of system types for which build machines are available.
  328. ;;
  329. ;; XXX: MIPS is unavailable in CI:
  330. ;; <https://lists.gnu.org/archive/html/guix-devel/2017-03/msg00790.html>.
  331. (fold delete %supported-systems '("mips64el-linux")))
  332. ;; A package.
  333. (define-record-type* <package>
  334. package make-package
  335. package?
  336. this-package
  337. (name package-name) ; string
  338. (version package-version) ; string
  339. (source package-source) ; <origin> instance
  340. (build-system package-build-system) ; build system
  341. (arguments package-arguments ; arguments for the build method
  342. (default '()) (thunked))
  343. (inputs package-inputs ; input packages or derivations
  344. (default '()) (thunked))
  345. (propagated-inputs package-propagated-inputs ; same, but propagated
  346. (default '()) (thunked))
  347. (native-inputs package-native-inputs ; native input packages/derivations
  348. (default '()) (thunked))
  349. (outputs package-outputs ; list of strings
  350. (default '("out")))
  351. ; lists of
  352. ; <search-path-specification>,
  353. ; for native and cross
  354. ; inputs
  355. (native-search-paths package-native-search-paths (default '()))
  356. (search-paths package-search-paths (default '()))
  357. ;; The 'replacement' field is marked as "innate" because it never makes
  358. ;; sense to inherit a replacement as is. See the 'package/inherit' macro.
  359. (replacement package-replacement ; package | #f
  360. (default #f) (thunked) (innate))
  361. (synopsis package-synopsis) ; one-line description
  362. (description package-description) ; one or two paragraphs
  363. (license package-license)
  364. (home-page package-home-page)
  365. (supported-systems package-supported-systems ; list of strings
  366. (default %supported-systems))
  367. (properties package-properties (default '())) ; alist for anything else
  368. (location package-location
  369. (default (and=> (current-source-location)
  370. source-properties->location))
  371. (innate)))
  372. (set-record-type-printer! <package>
  373. (lambda (package port)
  374. (let ((loc (package-location package))
  375. (format simple-format))
  376. (format port "#<package ~a@~a ~a~a>"
  377. (package-name package)
  378. (package-version package)
  379. (if loc
  380. (format #f "~a:~a "
  381. (location-file loc)
  382. (location-line loc))
  383. "")
  384. (number->string (object-address
  385. package)
  386. 16)))))
  387. (define-syntax-rule (package/inherit p overrides ...)
  388. "Like (package (inherit P) OVERRIDES ...), except that the same
  389. transformation is done to the package P's replacement, if any. P must be a bare
  390. identifier, and will be bound to either P or its replacement when evaluating
  391. OVERRIDES."
  392. (let loop ((p p))
  393. (package (inherit p)
  394. overrides ...
  395. (replacement (and=> (package-replacement p) loop)))))
  396. (define (package-upstream-name package)
  397. "Return the upstream name of PACKAGE, which could be different from the name
  398. it has in Guix."
  399. (or (assq-ref (package-properties package) 'upstream-name)
  400. (package-name package)))
  401. (define (hidden-package p)
  402. "Return a \"hidden\" version of P--i.e., one that 'fold-packages' and thus,
  403. user interfaces, ignores."
  404. (package
  405. (inherit p)
  406. (properties `((hidden? . #t)
  407. ,@(package-properties p)))))
  408. (define (hidden-package? p)
  409. "Return true if P is \"hidden\"--i.e., must not be visible to user
  410. interfaces."
  411. (assoc-ref (package-properties p) 'hidden?))
  412. (define (package-superseded p)
  413. "Return the package the supersedes P, or #f if P is still current."
  414. (assoc-ref (package-properties p) 'superseded))
  415. (define (deprecated-package old-name p)
  416. "Return a package called OLD-NAME and marked as superseded by P, a package
  417. object."
  418. (package
  419. (inherit p)
  420. (name old-name)
  421. (properties `((superseded . ,p)))))
  422. (define (package-field-location package field)
  423. "Return the source code location of the definition of FIELD for PACKAGE, or
  424. #f if it could not be determined."
  425. (define (goto port line column)
  426. (unless (and (= (port-column port) (- column 1))
  427. (= (port-line port) (- line 1)))
  428. (unless (eof-object? (read-char port))
  429. (goto port line column))))
  430. (match (package-location package)
  431. (($ <location> file line column)
  432. (match (search-path %load-path file)
  433. ((? string? file-found)
  434. (catch 'system-error
  435. (lambda ()
  436. ;; In general we want to keep relative file names for modules.
  437. (call-with-input-file file-found
  438. (lambda (port)
  439. (goto port line column)
  440. (match (read port)
  441. (('package inits ...)
  442. (let ((field (assoc field inits)))
  443. (match field
  444. ((_ value)
  445. (let ((loc (and=> (source-properties value)
  446. source-properties->location)))
  447. (and loc
  448. ;; Preserve the original file name, which may be a
  449. ;; relative file name.
  450. (set-field loc (location-file) file))))
  451. (_
  452. #f))))
  453. (_
  454. #f)))))
  455. (lambda _
  456. #f)))
  457. (#f
  458. ;; FILE could not be found in %LOAD-PATH.
  459. #f)))
  460. (_ #f)))
  461. ;; Error conditions.
  462. (define-condition-type &package-error &error
  463. package-error?
  464. (package package-error-package))
  465. (define-condition-type &package-input-error &package-error
  466. package-input-error?
  467. (input package-error-invalid-input))
  468. (define-condition-type &package-cross-build-system-error &package-error
  469. package-cross-build-system-error?)
  470. (define* (package-full-name package #:optional (delimiter "@"))
  471. "Return the full name of PACKAGE--i.e., `NAME@VERSION'. By specifying
  472. DELIMITER (a string), you can customize what will appear between the name and
  473. the version. By default, DELIMITER is \"@\"."
  474. (string-append (package-name package) delimiter (package-version package)))
  475. (define (patch-file-name patch)
  476. "Return the basename of PATCH's file name, or #f if the file name could not
  477. be determined."
  478. (match patch
  479. ((? string?)
  480. (basename patch))
  481. ((? origin?)
  482. (and=> (origin-actual-file-name patch) basename))))
  483. (define %vulnerability-regexp
  484. ;; Regexp matching a CVE identifier in patch file names.
  485. (make-regexp "CVE-[0-9]{4}-[0-9]+"))
  486. (define (package-patched-vulnerabilities package)
  487. "Return the list of patched vulnerabilities of PACKAGE as a list of CVE
  488. identifiers. The result is inferred from the file names of patches."
  489. (define (patch-vulnerabilities patch)
  490. (map (cut match:substring <> 0)
  491. (list-matches %vulnerability-regexp patch)))
  492. (let ((patches (filter-map patch-file-name
  493. (or (and=> (package-source package)
  494. origin-patches)
  495. '()))))
  496. (append-map patch-vulnerabilities patches)))
  497. (define (%standard-patch-inputs)
  498. (let* ((canonical (module-ref (resolve-interface '(gnu packages base))
  499. 'canonical-package))
  500. (ref (lambda (module var)
  501. ;; Make sure 'canonical-package' is not influenced by
  502. ;; '%current-target-system' since we're going to use the
  503. ;; native package anyway.
  504. (parameterize ((%current-target-system #f))
  505. (canonical
  506. (module-ref (resolve-interface module) var))))))
  507. `(("tar" ,(ref '(gnu packages base) 'tar))
  508. ("xz" ,(ref '(gnu packages compression) 'xz))
  509. ("bzip2" ,(ref '(gnu packages compression) 'bzip2))
  510. ("gzip" ,(ref '(gnu packages compression) 'gzip))
  511. ("lzip" ,(ref '(gnu packages compression) 'lzip))
  512. ("unzip" ,(ref '(gnu packages compression) 'unzip))
  513. ("patch" ,(ref '(gnu packages base) 'patch))
  514. ("locales" ,(ref '(gnu packages base) 'glibc-utf8-locales)))))
  515. (define (default-guile)
  516. "Return the default Guile package used to run the build code of
  517. derivations."
  518. (let ((distro (resolve-interface '(gnu packages commencement))))
  519. (module-ref distro 'guile-final)))
  520. (define (guile-for-grafts)
  521. "Return the Guile package used to build grafting derivations."
  522. ;; Guile 2.2 would not work due to <https://bugs.gnu.org/28211> when
  523. ;; grafting packages.
  524. (let ((distro (resolve-interface '(gnu packages guile))))
  525. (module-ref distro 'guile-2.0)))
  526. (define* (default-guile-derivation #:optional (system (%current-system)))
  527. "Return the derivation for SYSTEM of the default Guile package used to run
  528. the build code of derivation."
  529. (package->derivation (default-guile) system
  530. #:graft? #f))
  531. (define* (patch-and-repack source patches
  532. #:key
  533. inputs
  534. (snippet #f)
  535. (flags %default-patch-flags)
  536. (modules '())
  537. (guile-for-build (%guile-for-build))
  538. (system (%current-system)))
  539. "Unpack SOURCE (a derivation or store path), apply all of PATCHES, and
  540. repack the tarball using the tools listed in INPUTS. When SNIPPET is true,
  541. it must be an s-expression that will run from within the directory where
  542. SOURCE was unpacked, after all of PATCHES have been applied. MODULES
  543. specifies modules in scope when evaluating SNIPPET."
  544. (define source-file-name
  545. ;; SOURCE is usually a derivation, but it could be a store file.
  546. (if (derivation? source)
  547. (derivation->output-path source)
  548. source))
  549. (define lookup-input
  550. ;; The default value of the 'patch-inputs' field, and thus INPUTS is #f,
  551. ;; so deal with that.
  552. (let ((inputs (or inputs (%standard-patch-inputs))))
  553. (lambda (name)
  554. (match (assoc-ref inputs name)
  555. ((package) package)
  556. (#f #f)))))
  557. (define original-file-name (strip-store-file-name source-file-name))
  558. (define (numeric-extension? file-name)
  559. ;; Return true if FILE-NAME ends with digits.
  560. (and=> (file-extension file-name)
  561. (cut string-every char-set:hex-digit <>)))
  562. (define (checkout? directory)
  563. ;; Return true if DIRECTORY is a checkout (git, svn, etc).
  564. (string-suffix? "-checkout" directory))
  565. (define (tarxz-name file-name)
  566. ;; Return a '.tar.xz' file name based on FILE-NAME.
  567. (let ((base (if (numeric-extension? file-name)
  568. original-file-name
  569. (file-sans-extension file-name))))
  570. (string-append base
  571. (if (equal? (file-extension base) "tar")
  572. ".xz"
  573. ".tar.xz"))))
  574. (define instantiate-patch
  575. (match-lambda
  576. ((? string? patch) ;deprecated
  577. (local-file patch #:recursive? #t))
  578. ((? struct? patch) ;origin, local-file, etc.
  579. patch)))
  580. (let ((tar (lookup-input "tar"))
  581. (gzip (lookup-input "gzip"))
  582. (bzip2 (lookup-input "bzip2"))
  583. (lzip (lookup-input "lzip"))
  584. (xz (lookup-input "xz"))
  585. (patch (lookup-input "patch"))
  586. (locales (lookup-input "locales"))
  587. (comp (and=> (compressor source-file-name) lookup-input))
  588. (patches (map instantiate-patch patches)))
  589. (define build
  590. (with-imported-modules '((guix build utils))
  591. #~(begin
  592. (use-modules (ice-9 ftw)
  593. (ice-9 match)
  594. (ice-9 regex)
  595. (srfi srfi-1)
  596. (srfi srfi-26)
  597. (guix build utils))
  598. ;; The --sort option was added to GNU tar in version 1.28, released
  599. ;; 2014-07-28. During bootstrap we must cope with older versions.
  600. (define tar-supports-sort?
  601. (zero? (system* (string-append #+tar "/bin/tar")
  602. "cf" "/dev/null" "--files-from=/dev/null"
  603. "--sort=name")))
  604. (define (apply-patch patch)
  605. (format (current-error-port) "applying '~a'...~%" patch)
  606. ;; Use '--force' so that patches that do not apply perfectly are
  607. ;; rejected. Use '--no-backup-if-mismatch' to prevent making
  608. ;; "*.orig" file if a patch is applied with offset.
  609. (invoke (string-append #+patch "/bin/patch")
  610. "--force" "--no-backup-if-mismatch"
  611. #+@flags "--input" patch))
  612. (define (first-file directory)
  613. ;; Return the name of the first file in DIRECTORY.
  614. (car (scandir directory
  615. (lambda (name)
  616. (not (member name '("." "..")))))))
  617. (define (repack directory output)
  618. ;; Write to OUTPUT a compressed tarball containing DIRECTORY.
  619. (unless tar-supports-sort?
  620. (call-with-output-file ".file_list"
  621. (lambda (port)
  622. (for-each (lambda (name)
  623. (format port "~a~%" name))
  624. (find-files directory
  625. #:directories? #t
  626. #:fail-on-error? #t)))))
  627. (apply invoke #+(file-append tar "/bin/tar")
  628. "cvfa" output
  629. ;; Avoid non-determinism in the archive. Set the mtime
  630. ;; to 1 as is the case in the store (software like gzip
  631. ;; behaves differently when it stumbles upon mtime = 0).
  632. "--mtime=@1"
  633. "--owner=root:0" "--group=root:0"
  634. (if tar-supports-sort?
  635. `("--sort=name" ,directory)
  636. '("--no-recursion"
  637. "--files-from=.file_list"))))
  638. ;; Encoding/decoding errors shouldn't be silent.
  639. (fluid-set! %default-port-conversion-strategy 'error)
  640. (when #+locales
  641. ;; First of all, install a UTF-8 locale so that UTF-8 file names
  642. ;; are correctly interpreted. During bootstrap, LOCALES is #f.
  643. (setenv "LOCPATH"
  644. (string-append #+locales "/lib/locale/"
  645. #+(and locales
  646. (version-major+minor
  647. (package-version locales)))))
  648. (setlocale LC_ALL "en_US.utf8"))
  649. (setenv "PATH"
  650. (string-append #+xz "/bin"
  651. (if #+comp
  652. (string-append ":" #+comp "/bin")
  653. "")))
  654. (setenv "XZ_DEFAULTS" (string-join (%xz-parallel-args)))
  655. ;; SOURCE may be either a directory, a tarball or a simple file.
  656. (let ((name (strip-store-file-name #+source))
  657. (command (and=> #+comp (cut string-append <> "/bin/"
  658. (compressor #+source)))))
  659. (if (file-is-directory? #+source)
  660. (copy-recursively #+source name)
  661. (cond
  662. ((tarball? #+source)
  663. (invoke (string-append #+tar "/bin/tar") "xvf" #+source))
  664. ((and=> (compressor #+source) (cut string= "unzip" <>))
  665. ;; Note: Referring to the store unzip here (#+unzip)
  666. ;; would introduce a cycle.
  667. ("unzip" (invoke "unzip" #+source)))
  668. (else
  669. (copy-file #+source name)
  670. (when command
  671. (invoke command "--decompress" name))))))
  672. (let* ((file (first-file "."))
  673. (directory (if (file-is-directory? file)
  674. file
  675. ".")))
  676. (format (current-error-port) "source is at '~a'~%" file)
  677. (with-directory-excursion directory
  678. (for-each apply-patch '#+patches)
  679. #+(if snippet
  680. #~(let ((module (make-fresh-user-module)))
  681. (module-use-interfaces!
  682. module
  683. (map resolve-interface '#+modules))
  684. ((@ (system base compile) compile)
  685. '#+(if (pair? snippet)
  686. (sexp->gexp snippet)
  687. snippet)
  688. #:to 'value
  689. #:opts %auto-compilation-options
  690. #:env module))
  691. #~#t))
  692. ;; If SOURCE is a directory (such as a checkout), return a
  693. ;; directory. Otherwise create a tarball.
  694. (cond
  695. ((file-is-directory? #+source)
  696. (copy-recursively directory #$output
  697. #:log (%make-void-port "w")))
  698. ((not #+comp)
  699. (copy-file file #$output))
  700. (else
  701. (repack directory #$output)))))))
  702. (let ((name (if (or (checkout? original-file-name)
  703. (not (compressor original-file-name)))
  704. original-file-name
  705. (tarxz-name original-file-name))))
  706. (gexp->derivation name build
  707. #:graft? #f
  708. #:system system
  709. #:guile-for-build guile-for-build
  710. #:properties `((type . origin)
  711. (patches . ,(length patches)))))))
  712. (define (package-with-patches original patches)
  713. "Return package ORIGINAL with PATCHES applied."
  714. (package (inherit original)
  715. (source (origin (inherit (package-source original))
  716. (patches patches)))))
  717. (define (package-with-extra-patches original patches)
  718. "Return package ORIGINAL with all PATCHES appended to its list of patches."
  719. (package-with-patches original
  720. (append (origin-patches (package-source original))
  721. patches)))
  722. (define (package-with-c-toolchain package toolchain)
  723. "Return a variant of PACKAGE that uses TOOLCHAIN instead of the default GNU
  724. C/C++ toolchain. TOOLCHAIN must be a list of inputs (label/package tuples)
  725. providing equivalent functionality, such as the 'gcc-toolchain' package."
  726. (let ((bs (package-build-system package)))
  727. (package/inherit package
  728. (build-system (build-system-with-c-toolchain bs toolchain)))))
  729. (define (transitive-inputs inputs)
  730. "Return the closure of INPUTS when considering the 'propagated-inputs'
  731. edges. Omit duplicate inputs, except for those already present in INPUTS
  732. itself.
  733. This is implemented as a breadth-first traversal such that INPUTS is
  734. preserved, and only duplicate propagated inputs are removed."
  735. (define (seen? seen item outputs)
  736. ;; FIXME: We're using pointer identity here, which is extremely sensitive
  737. ;; to memoization in package-producing procedures; see
  738. ;; <https://bugs.gnu.org/30155>.
  739. (match (vhash-assq item seen)
  740. ((_ . o) (equal? o outputs))
  741. (_ #f)))
  742. (let loop ((inputs inputs)
  743. (result '())
  744. (propagated '())
  745. (first? #t)
  746. (seen vlist-null))
  747. (match inputs
  748. (()
  749. (if (null? propagated)
  750. (reverse result)
  751. (loop (reverse (concatenate propagated)) result '() #f seen)))
  752. (((and input (label (? package? package) outputs ...)) rest ...)
  753. (if (and (not first?) (seen? seen package outputs))
  754. (loop rest result propagated first? seen)
  755. (loop rest
  756. (cons input result)
  757. (cons (package-propagated-inputs package) propagated)
  758. first?
  759. (vhash-consq package outputs seen))))
  760. ((input rest ...)
  761. (loop rest (cons input result) propagated first? seen)))))
  762. (define (package-direct-sources package)
  763. "Return all source origins associated with PACKAGE; including origins in
  764. PACKAGE's inputs."
  765. `(,@(or (and=> (package-source package) list) '())
  766. ,@(filter-map (match-lambda
  767. ((_ (? origin? orig) _ ...)
  768. orig)
  769. (_ #f))
  770. (package-direct-inputs package))))
  771. (define (package-transitive-sources package)
  772. "Return PACKAGE's direct sources, and their direct sources, recursively."
  773. (delete-duplicates
  774. (concatenate (filter-map (match-lambda
  775. ((_ (? origin? orig) _ ...)
  776. (list orig))
  777. ((_ (? package? p) _ ...)
  778. (package-direct-sources p))
  779. (_ #f))
  780. (bag-transitive-inputs
  781. (package->bag package))))))
  782. (define (package-direct-inputs package)
  783. "Return all the direct inputs of PACKAGE---i.e, its direct inputs along
  784. with their propagated inputs."
  785. (append (package-native-inputs package)
  786. (package-inputs package)
  787. (package-propagated-inputs package)))
  788. (define (package-transitive-inputs package)
  789. "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
  790. with their propagated inputs, recursively."
  791. (transitive-inputs (package-direct-inputs package)))
  792. (define (package-transitive-target-inputs package)
  793. "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
  794. along with their propagated inputs, recursively. This only includes inputs
  795. for the target system, and not native inputs."
  796. (transitive-inputs (append (package-inputs package)
  797. (package-propagated-inputs package))))
  798. (define (package-transitive-native-inputs package)
  799. "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
  800. along with their propagated inputs, recursively. This only includes inputs
  801. for the host system (\"native inputs\"), and not target inputs."
  802. (transitive-inputs (package-native-inputs package)))
  803. (define (package-transitive-propagated-inputs package)
  804. "Return the propagated inputs of PACKAGE, and their propagated inputs,
  805. recursively."
  806. (transitive-inputs (package-propagated-inputs package)))
  807. (define (package-transitive-native-search-paths package)
  808. "Return the list of search paths for PACKAGE and its propagated inputs,
  809. recursively."
  810. (append (package-native-search-paths package)
  811. (append-map (match-lambda
  812. ((label (? package? p) _ ...)
  813. (package-native-search-paths p))
  814. (_
  815. '()))
  816. (package-transitive-propagated-inputs package))))
  817. (define (transitive-input-references alist inputs)
  818. "Return a list of (assoc-ref ALIST <label>) for each (<label> <package> . _)
  819. in INPUTS and their transitive propagated inputs."
  820. (define label
  821. (match-lambda
  822. ((label . _)
  823. label)))
  824. (map (lambda (input)
  825. `(assoc-ref ,alist ,(label input)))
  826. (transitive-inputs inputs)))
  827. (define package-transitive-supported-systems
  828. (let ()
  829. (define supported-systems
  830. (mlambda (package system)
  831. (parameterize ((%current-system system))
  832. (fold (lambda (input systems)
  833. (match input
  834. ((label (? package? package) . _)
  835. (lset-intersection string=? systems
  836. (supported-systems package system)))
  837. (_
  838. systems)))
  839. (package-supported-systems package)
  840. (bag-direct-inputs (package->bag package))))))
  841. (lambda* (package #:optional (system (%current-system)))
  842. "Return the intersection of the systems supported by PACKAGE and those
  843. supported by its dependencies."
  844. (supported-systems package system))))
  845. (define* (supported-package? package #:optional (system (%current-system)))
  846. "Return true if PACKAGE is supported on SYSTEM--i.e., if PACKAGE and all its
  847. dependencies are known to build on SYSTEM."
  848. (member system (package-transitive-supported-systems package system)))
  849. (define (bag-direct-inputs bag)
  850. "Same as 'package-direct-inputs', but applied to a bag."
  851. (append (bag-build-inputs bag)
  852. (bag-host-inputs bag)
  853. (bag-target-inputs bag)))
  854. (define (bag-transitive-inputs bag)
  855. "Same as 'package-transitive-inputs', but applied to a bag."
  856. (parameterize ((%current-target-system #f)
  857. (%current-system (bag-system bag)))
  858. (transitive-inputs (bag-direct-inputs bag))))
  859. (define (bag-transitive-build-inputs bag)
  860. "Same as 'package-transitive-native-inputs', but applied to a bag."
  861. (parameterize ((%current-target-system #f)
  862. (%current-system (bag-system bag)))
  863. (transitive-inputs (bag-build-inputs bag))))
  864. (define (bag-transitive-host-inputs bag)
  865. "Same as 'package-transitive-target-inputs', but applied to a bag."
  866. (parameterize ((%current-target-system (bag-target bag))
  867. (%current-system (bag-system bag)))
  868. (transitive-inputs (bag-host-inputs bag))))
  869. (define (bag-transitive-target-inputs bag)
  870. "Return the \"target inputs\" of BAG, recursively."
  871. (parameterize ((%current-target-system (bag-target bag))
  872. (%current-system (bag-system bag)))
  873. (transitive-inputs (bag-target-inputs bag))))
  874. (define* (package-closure packages #:key (system (%current-system)))
  875. "Return the closure of PACKAGES on SYSTEM--i.e., PACKAGES and the list of
  876. packages they depend on, recursively."
  877. (let loop ((packages packages)
  878. (visited vlist-null)
  879. (closure (list->setq packages)))
  880. (match packages
  881. (()
  882. (set->list closure))
  883. ((package . rest)
  884. (if (vhash-assq package visited)
  885. (loop rest visited closure)
  886. (let* ((bag (package->bag package system))
  887. (dependencies (filter-map (match-lambda
  888. ((label (? package? package) . _)
  889. package)
  890. (_ #f))
  891. (bag-direct-inputs bag))))
  892. (loop (append dependencies rest)
  893. (vhash-consq package #t visited)
  894. (fold set-insert closure dependencies))))))))
  895. (define (build-system-with-package-mapping bs rewrite)
  896. "Return a variant of BS, a build system, that rewrites a bag's inputs by
  897. passing them through REWRITE, a procedure that takes an input tuplet and
  898. returns a \"rewritten\" input tuplet."
  899. (define lower
  900. (build-system-lower bs))
  901. (define (lower* . args)
  902. (let ((lowered (apply lower args)))
  903. (bag
  904. (inherit lowered)
  905. (build-inputs (map rewrite (bag-build-inputs lowered)))
  906. (host-inputs (map rewrite (bag-host-inputs lowered)))
  907. (target-inputs (map rewrite (bag-target-inputs lowered))))))
  908. (build-system
  909. (inherit bs)
  910. (lower lower*)))
  911. (define* (package-mapping proc #:optional (cut? (const #f))
  912. #:key deep?)
  913. "Return a procedure that, given a package, applies PROC to all the packages
  914. depended on and returns the resulting package. The procedure stops recursion
  915. when CUT? returns true for a given package. When DEEP? is true, PROC is
  916. applied to implicit inputs as well."
  917. (define (rewrite input)
  918. (match input
  919. ((label (? package? package) outputs ...)
  920. (cons* label (replace package) outputs))
  921. (_
  922. input)))
  923. (define mapping-property
  924. ;; Property indicating whether the package has already been processed.
  925. (gensym " package-mapping-done"))
  926. (define replace
  927. (mlambdaq (p)
  928. ;; If P is the result of a previous call, return it.
  929. (cond ((assq-ref (package-properties p) mapping-property)
  930. p)
  931. ((cut? p)
  932. ;; Since P's propagated inputs are really inputs of its dependents,
  933. ;; rewrite them as well, unless we're doing a "shallow" rewrite.
  934. (let ((p (proc p)))
  935. (if (or (not deep?)
  936. (null? (package-propagated-inputs p)))
  937. p
  938. (package
  939. (inherit p)
  940. (location (package-location p))
  941. (replacement (package-replacement p))
  942. (propagated-inputs (map rewrite (package-propagated-inputs p)))
  943. (properties `((,mapping-property . #t)
  944. ,@(package-properties p)))))))
  945. (else
  946. ;; Return a variant of P with PROC applied to P and its explicit
  947. ;; dependencies, recursively. Memoize the transformations. Failing
  948. ;; to do that, we would build a huge object graph with lots of
  949. ;; duplicates, which in turns prevents us from benefiting from
  950. ;; memoization in 'package-derivation'.
  951. (let ((p (proc p)))
  952. (package
  953. (inherit p)
  954. (location (package-location p))
  955. (build-system (if deep?
  956. (build-system-with-package-mapping
  957. (package-build-system p) rewrite)
  958. (package-build-system p)))
  959. (inputs (map rewrite (package-inputs p)))
  960. (native-inputs (map rewrite (package-native-inputs p)))
  961. (propagated-inputs (map rewrite (package-propagated-inputs p)))
  962. (replacement (and=> (package-replacement p) replace))
  963. (properties `((,mapping-property . #t)
  964. ,@(package-properties p)))))))))
  965. replace)
  966. (define* (package-input-rewriting replacements
  967. #:optional (rewrite-name identity)
  968. #:key (deep? #t))
  969. "Return a procedure that, when passed a package, replaces its direct and
  970. indirect dependencies, including implicit inputs when DEEP? is true, according
  971. to REPLACEMENTS. REPLACEMENTS is a list of package pairs; the first element
  972. of each pair is the package to replace, and the second one is the replacement.
  973. Optionally, REWRITE-NAME is a one-argument procedure that takes the name of a
  974. package and returns its new name after rewrite."
  975. (define replacement-property
  976. ;; Property to tag right-hand sides in REPLACEMENTS.
  977. (gensym " package-replacement"))
  978. (define (rewrite p)
  979. (if (assq-ref (package-properties p) replacement-property)
  980. p
  981. (match (assq-ref replacements p)
  982. (#f (package/inherit p
  983. (name (rewrite-name (package-name p)))))
  984. (new (if deep?
  985. (package/inherit new
  986. (properties `((,replacement-property . #t)
  987. ,@(package-properties new))))
  988. new)))))
  989. (define (cut? p)
  990. (or (assq-ref (package-properties p) replacement-property)
  991. (assq-ref replacements p)))
  992. (package-mapping rewrite cut?
  993. #:deep? deep?))
  994. (define* (package-input-rewriting/spec replacements #:key (deep? #t))
  995. "Return a procedure that, given a package, applies the given REPLACEMENTS to
  996. all the package graph, including implicit inputs unless DEEP? is false.
  997. REPLACEMENTS is a list of spec/procedures pair; each spec is a package
  998. specification such as \"gcc\" or \"guile@2\", and each procedure takes a
  999. matching package and returns a replacement for that package."
  1000. (define table
  1001. (fold (lambda (replacement table)
  1002. (match replacement
  1003. ((spec . proc)
  1004. (let-values (((name version)
  1005. (package-name->name+version spec)))
  1006. (vhash-cons name (list version proc) table)))))
  1007. vlist-null
  1008. replacements))
  1009. (define (find-replacement package)
  1010. (vhash-fold* (lambda (item proc)
  1011. (or proc
  1012. (match item
  1013. ((#f proc)
  1014. proc)
  1015. ((version proc)
  1016. (and (version-prefix? version
  1017. (package-version package))
  1018. proc)))))
  1019. #f
  1020. (package-name package)
  1021. table))
  1022. (define replacement-property
  1023. (gensym " package-replacement"))
  1024. (define (rewrite p)
  1025. (if (assq-ref (package-properties p) replacement-property)
  1026. p
  1027. (match (find-replacement p)
  1028. (#f p)
  1029. (proc
  1030. (let ((new (proc p)))
  1031. ;; Mark NEW as already processed.
  1032. (package/inherit new
  1033. (properties `((,replacement-property . #t)
  1034. ,@(package-properties new)))))))))
  1035. (define (cut? p)
  1036. (or (assq-ref (package-properties p) replacement-property)
  1037. (find-replacement p)))
  1038. (package-mapping rewrite cut?
  1039. #:deep? deep?))
  1040. ;;;
  1041. ;;; Package derivations.
  1042. ;;;
  1043. (define (cache! cache package system thunk)
  1044. "Memoize in CACHE the return values of THUNK as the derivation of PACKAGE on
  1045. SYSTEM."
  1046. ;; FIXME: This memoization should be associated with the open store, because
  1047. ;; otherwise it breaks when switching to a different store.
  1048. (let ((result (thunk)))
  1049. ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
  1050. ;; same value for all structs (as of Guile 2.0.6), and because pointer
  1051. ;; equality is sufficient in practice.
  1052. (hashq-set! cache package
  1053. `((,system . ,result)
  1054. ,@(or (hashq-ref cache package) '())))
  1055. result))
  1056. (define-syntax cached
  1057. (syntax-rules (=>)
  1058. "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
  1059. Return the cached result when available."
  1060. ((_ (=> cache) package system body ...)
  1061. (let ((thunk (lambda () body ...))
  1062. (key system))
  1063. (match (hashq-ref cache package)
  1064. ((alist (... ...))
  1065. (match (assoc-ref alist key)
  1066. (#f (cache! cache package key thunk))
  1067. (value value)))
  1068. (#f
  1069. (cache! cache package key thunk)))))))
  1070. (define* (expand-input package input #:key target)
  1071. "Expand INPUT, an input tuple, to a name/<gexp-input> tuple. PACKAGE is
  1072. only used to provide contextual information in exceptions."
  1073. (with-monad %store-monad
  1074. (match input
  1075. ;; INPUT doesn't need to be lowered here because it'll be lowered down
  1076. ;; the road in the gexp that refers to it. However, packages need to be
  1077. ;; special-cased to pass #:graft? #f (only the "tip" of the package
  1078. ;; graph needs to have #:graft? #t). Lowering them here also allows
  1079. ;; 'bag->derivation' to delete non-eq? packages that lead to the same
  1080. ;; derivation.
  1081. (((? string? name) (? package? package))
  1082. (mlet %store-monad ((drv (if target
  1083. (package->cross-derivation package target
  1084. #:graft? #f)
  1085. (package->derivation package #:graft? #f))))
  1086. (return (list name (gexp-input drv #:native? (not target))))))
  1087. (((? string? name) (? package? package) (? string? output))
  1088. (mlet %store-monad ((drv (if target
  1089. (package->cross-derivation package target
  1090. #:graft? #f)
  1091. (package->derivation package #:graft? #f))))
  1092. (return (list name (gexp-input drv output #:native? (not target))))))
  1093. (((? string? name) (? file-like? thing))
  1094. (return (list name (gexp-input thing #:native? (not target)))))
  1095. (((? string? name) (? file-like? thing) (? string? output))
  1096. (return (list name (gexp-input thing output #:native? (not target)))))
  1097. (((? string? name)
  1098. (and (? string?) (? file-exists? file)))
  1099. ;; Add FILE to the store. When FILE is in the sub-directory of a
  1100. ;; store path, it needs to be added anyway, so it can be used as a
  1101. ;; source.
  1102. (return (list name (gexp-input (local-file file #:recursive? #t)
  1103. #:native? (not target)))))
  1104. (x
  1105. (raise (condition (&package-input-error
  1106. (package package)
  1107. (input x))))))))
  1108. (define %bag-cache
  1109. ;; 'eq?' cache mapping packages to system+target+graft?-dependent bags.
  1110. ;; It significantly speeds things up when doing repeated calls to
  1111. ;; 'package->bag' as is the case when building a profile.
  1112. (make-weak-key-hash-table 200))
  1113. (define* (package->bag package #:optional
  1114. (system (%current-system))
  1115. (target (%current-target-system))
  1116. #:key (graft? (%graft?)))
  1117. "Compile PACKAGE into a bag for SYSTEM, possibly cross-compiled to TARGET,
  1118. and return it."
  1119. (let ((package (or (and graft? (package-replacement package))
  1120. package)))
  1121. (cached (=> %bag-cache)
  1122. package (list system target)
  1123. ;; Bind %CURRENT-SYSTEM and %CURRENT-TARGET-SYSTEM so that thunked
  1124. ;; field values can refer to it.
  1125. (parameterize ((%current-system system)
  1126. (%current-target-system target))
  1127. (match package
  1128. ((and self
  1129. ($ <package> name version source build-system
  1130. args inputs propagated-inputs native-inputs
  1131. outputs))
  1132. ;; Even though we prefer to use "@" to separate the package
  1133. ;; name from the package version in various user-facing parts
  1134. ;; of Guix, checkStoreName (in nix/libstore/store-api.cc)
  1135. ;; prohibits the use of "@", so use "-" instead.
  1136. (or (make-bag build-system (string-append name "-" version)
  1137. #:system system
  1138. #:target target
  1139. #:source source
  1140. #:inputs (append (inputs self)
  1141. (propagated-inputs self))
  1142. #:outputs outputs
  1143. #:native-inputs (native-inputs self)
  1144. #:arguments (args self))
  1145. (raise (if target
  1146. (condition
  1147. (&package-cross-build-system-error
  1148. (package package)))
  1149. (condition
  1150. (&package-error
  1151. (package package))))))))))))
  1152. (define (input-graft system)
  1153. "Return a monadic procedure that, given a package with a graft, returns a
  1154. graft, and #f otherwise."
  1155. (with-monad %store-monad
  1156. (match-lambda*
  1157. (((? package? package) output)
  1158. (let ((replacement (package-replacement package)))
  1159. (if replacement
  1160. ;; XXX: We should use a separate cache instead of abusing the
  1161. ;; object cache.
  1162. (mcached (mlet %store-monad ((orig (package->derivation package system
  1163. #:graft? #f))
  1164. (new (package->derivation replacement system
  1165. #:graft? #t)))
  1166. (return (graft
  1167. (origin orig)
  1168. (origin-output output)
  1169. (replacement new)
  1170. (replacement-output output))))
  1171. package 'graft output system)
  1172. (return #f))))
  1173. (_
  1174. (return #f)))))
  1175. (define (input-cross-graft target system)
  1176. "Same as 'input-graft', but for cross-compilation inputs."
  1177. (with-monad %store-monad
  1178. (match-lambda*
  1179. (((? package? package) output)
  1180. (let ((replacement (package-replacement package)))
  1181. (if replacement
  1182. (mlet %store-monad ((orig (package->cross-derivation package
  1183. target system
  1184. #:graft? #f))
  1185. (new (package->cross-derivation replacement
  1186. target system
  1187. #:graft? #t)))
  1188. (return (graft
  1189. (origin orig)
  1190. (origin-output output)
  1191. (replacement new)
  1192. (replacement-output output))))
  1193. (return #f))))
  1194. (_
  1195. (return #f)))))
  1196. (define* (fold-bag-dependencies proc seed bag
  1197. #:key (native? #t))
  1198. "Fold PROC over the packages BAG depends on. Each package is visited only
  1199. once, in depth-first order. If NATIVE? is true, restrict to native
  1200. dependencies; otherwise, restrict to target dependencies."
  1201. (define bag-direct-inputs*
  1202. (if native?
  1203. (lambda (bag)
  1204. (append (bag-build-inputs bag)
  1205. (bag-target-inputs bag)
  1206. (if (bag-target bag)
  1207. '()
  1208. (bag-host-inputs bag))))
  1209. bag-host-inputs))
  1210. (let loop ((inputs (bag-direct-inputs* bag))
  1211. (result seed)
  1212. (visited vlist-null))
  1213. (match inputs
  1214. (()
  1215. result)
  1216. (((label (? package? head) . rest) . tail)
  1217. (let ((output (match rest (() "out") ((output) output)))
  1218. (outputs (vhash-foldq* cons '() head visited)))
  1219. (if (member output outputs)
  1220. (loop tail result visited)
  1221. (let ((inputs (bag-direct-inputs* (package->bag head))))
  1222. (loop (append inputs tail)
  1223. (proc head output result)
  1224. (vhash-consq head output visited))))))
  1225. ((head . tail)
  1226. (loop tail result visited)))))
  1227. (define* (bag-grafts bag)
  1228. "Return the list of grafts potentially applicable to BAG. Potentially
  1229. applicable grafts are collected by looking at direct or indirect dependencies
  1230. of BAG that have a 'replacement'. Whether a graft is actually applicable
  1231. depends on whether the outputs of BAG depend on the items the grafts refer
  1232. to (see 'graft-derivation'.)"
  1233. (define system (bag-system bag))
  1234. (define target (bag-target bag))
  1235. (mlet %store-monad
  1236. ((native-grafts
  1237. (let ((->graft (input-graft system)))
  1238. (parameterize ((%current-system system)
  1239. (%current-target-system #f))
  1240. (fold-bag-dependencies (lambda (package output grafts)
  1241. (mlet %store-monad ((grafts grafts))
  1242. (>>= (->graft package output)
  1243. (match-lambda
  1244. (#f (return grafts))
  1245. (graft (return (cons graft grafts)))))))
  1246. (return '())
  1247. bag))))
  1248. (target-grafts
  1249. (if target
  1250. (let ((->graft (input-cross-graft target system)))
  1251. (parameterize ((%current-system system)
  1252. (%current-target-system target))
  1253. (fold-bag-dependencies
  1254. (lambda (package output grafts)
  1255. (mlet %store-monad ((grafts grafts))
  1256. (>>= (->graft package output)
  1257. (match-lambda
  1258. (#f (return grafts))
  1259. (graft (return (cons graft grafts)))))))
  1260. (return '())
  1261. bag
  1262. #:native? #f)))
  1263. (return '()))))
  1264. ;; We can end up with several identical grafts if we stumble upon packages
  1265. ;; that are not 'eq?' but map to the same derivation (this can happen when
  1266. ;; using things like 'package-with-explicit-inputs'.) Hence the
  1267. ;; 'delete-duplicates' call.
  1268. (return (delete-duplicates
  1269. (append native-grafts target-grafts)))))
  1270. (define* (package-grafts* package
  1271. #:optional (system (%current-system))
  1272. #:key target)
  1273. "Return the list of grafts applicable to PACKAGE as built for SYSTEM and
  1274. TARGET."
  1275. (let* ((package (or (package-replacement package) package))
  1276. (bag (package->bag package system target)))
  1277. (bag-grafts bag)))
  1278. (define package-grafts
  1279. (store-lower package-grafts*))
  1280. (define-inlinable (derivation=? drv1 drv2)
  1281. "Return true if DRV1 and DRV2 are equal."
  1282. (or (eq? drv1 drv2)
  1283. (string=? (derivation-file-name drv1)
  1284. (derivation-file-name drv2))))
  1285. (define (input=? input1 input2)
  1286. "Return true if INPUT1 and INPUT2 are equivalent."
  1287. (match input1
  1288. ((label1 obj1 . outputs1)
  1289. (match input2
  1290. ((label2 obj2 . outputs2)
  1291. (and (string=? label1 label2)
  1292. (equal? outputs1 outputs2)
  1293. (or (and (derivation? obj1) (derivation? obj2)
  1294. (derivation=? obj1 obj2))
  1295. (equal? obj1 obj2))))))))
  1296. (define* (bag->derivation bag #:optional context)
  1297. "Return the derivation to build BAG for SYSTEM. Optionally, CONTEXT can be
  1298. a package object describing the context in which the call occurs, for improved
  1299. error reporting."
  1300. (if (bag-target bag)
  1301. (bag->cross-derivation bag)
  1302. (mlet* %store-monad ((system -> (bag-system bag))
  1303. (inputs -> (bag-transitive-inputs bag))
  1304. (input-drvs (mapm %store-monad
  1305. (cut expand-input context <>)
  1306. inputs))
  1307. (paths -> (delete-duplicates
  1308. (append-map (match-lambda
  1309. ((_ (? package? p) _ ...)
  1310. (package-native-search-paths
  1311. p))
  1312. (_ '()))
  1313. inputs))))
  1314. ;; It's possible that INPUTS contains packages that are not 'eq?' but
  1315. ;; that lead to the same derivation. Delete those duplicates to avoid
  1316. ;; issues down the road, such as duplicate entries in '%build-inputs'.
  1317. (apply (bag-build bag) (bag-name bag)
  1318. (delete-duplicates input-drvs input=?)
  1319. #:search-paths paths
  1320. #:outputs (bag-outputs bag) #:system system
  1321. (bag-arguments bag)))))
  1322. (define* (bag->cross-derivation bag #:optional context)
  1323. "Return the derivation to build BAG, which is actually a cross build.
  1324. Optionally, CONTEXT can be a package object denoting the context of the call.
  1325. This is an internal procedure."
  1326. (mlet* %store-monad ((system -> (bag-system bag))
  1327. (target -> (bag-target bag))
  1328. (host -> (bag-transitive-host-inputs bag))
  1329. (host-drvs (mapm %store-monad
  1330. (cut expand-input context <>
  1331. #:target target)
  1332. host))
  1333. (target* -> (bag-transitive-target-inputs bag))
  1334. (target-drvs (mapm %store-monad
  1335. (cut expand-input context <>)
  1336. target*))
  1337. (build -> (bag-transitive-build-inputs bag))
  1338. (build-drvs (mapm %store-monad
  1339. (cut expand-input context <>)
  1340. build))
  1341. (all -> (append build target* host))
  1342. (paths -> (delete-duplicates
  1343. (append-map (match-lambda
  1344. ((_ (? package? p) _ ...)
  1345. (package-search-paths p))
  1346. (_ '()))
  1347. all)))
  1348. (npaths -> (delete-duplicates
  1349. (append-map (match-lambda
  1350. ((_ (? package? p) _ ...)
  1351. (package-native-search-paths
  1352. p))
  1353. (_ '()))
  1354. all))))
  1355. (apply (bag-build bag) (bag-name bag)
  1356. #:build-inputs (delete-duplicates build-drvs input=?)
  1357. #:host-inputs (delete-duplicates host-drvs input=?)
  1358. #:target-inputs (delete-duplicates target-drvs input=?)
  1359. #:search-paths paths
  1360. #:native-search-paths npaths
  1361. #:outputs (bag-outputs bag)
  1362. #:system system #:target target
  1363. (bag-arguments bag))))
  1364. (define bag->derivation*
  1365. (store-lower bag->derivation))
  1366. (define graft-derivation*
  1367. (store-lift graft-derivation))
  1368. (define* (package->derivation package
  1369. #:optional (system (%current-system))
  1370. #:key (graft? (%graft?)))
  1371. "Return the <derivation> object of PACKAGE for SYSTEM."
  1372. ;; Compute the derivation and cache the result. Caching is important
  1373. ;; because some derivations, such as the implicit inputs of the GNU build
  1374. ;; system, will be queried many, many times in a row.
  1375. (mcached (mlet* %store-monad ((bag -> (package->bag package system #f
  1376. #:graft? graft?))
  1377. (drv (bag->derivation bag package)))
  1378. (if graft?
  1379. (>>= (bag-grafts bag)
  1380. (match-lambda
  1381. (()
  1382. (return drv))
  1383. (grafts
  1384. (mlet %store-monad ((guile (package->derivation
  1385. (default-guile)
  1386. system #:graft? #f)))
  1387. (graft-derivation* drv grafts
  1388. #:system system
  1389. #:guile guile)))))
  1390. (return drv)))
  1391. package system #f graft?))
  1392. (define* (package->cross-derivation package target
  1393. #:optional (system (%current-system))
  1394. #:key (graft? (%graft?)))
  1395. "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
  1396. system identifying string)."
  1397. (mcached (mlet* %store-monad ((bag -> (package->bag package system target
  1398. #:graft? graft?))
  1399. (drv (bag->derivation bag package)))
  1400. (if graft?
  1401. (>>= (bag-grafts bag)
  1402. (match-lambda
  1403. (()
  1404. (return drv))
  1405. (grafts
  1406. (mlet %store-monad ((guile (package->derivation
  1407. (default-guile)
  1408. system #:graft? #f)))
  1409. (graft-derivation* drv grafts
  1410. #:system system
  1411. #:guile guile)))))
  1412. (return drv)))
  1413. package system target graft?))
  1414. (define* (package-output store package
  1415. #:optional (output "out") (system (%current-system)))
  1416. "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
  1417. symbolic output name, such as \"out\". Note that this procedure calls
  1418. `package-derivation', which is costly."
  1419. (let ((drv (package-derivation store package system)))
  1420. (derivation->output-path drv output)))
  1421. ;;;
  1422. ;;; Monadic interface.
  1423. ;;;
  1424. (define (set-guile-for-build guile)
  1425. "This monadic procedure changes the Guile currently used to run the build
  1426. code of derivations to GUILE, a package object."
  1427. (lambda (store)
  1428. (let ((guile (package-derivation store guile)))
  1429. (values (%guile-for-build guile) store))))
  1430. (define* (package-file package
  1431. #:optional file
  1432. #:key
  1433. system (output "out") target)
  1434. "Return as a monadic value the absolute file name of FILE within the
  1435. OUTPUT directory of PACKAGE. When FILE is omitted, return the name of the
  1436. OUTPUT directory of PACKAGE. When TARGET is true, use it as a
  1437. cross-compilation target triplet.
  1438. Note that this procedure does _not_ build PACKAGE. Thus, the result might or
  1439. might not designate an existing file. We recommend not using this procedure
  1440. unless you know what you are doing."
  1441. (lambda (store)
  1442. (define compute-derivation
  1443. (if target
  1444. (cut package-cross-derivation <> <> target <>)
  1445. package-derivation))
  1446. (let* ((system (or system (%current-system)))
  1447. (drv (compute-derivation store package system))
  1448. (out (derivation->output-path drv output)))
  1449. (values (if file
  1450. (string-append out "/" file)
  1451. out)
  1452. store))))
  1453. (define package-derivation
  1454. (store-lower package->derivation))
  1455. (define package-cross-derivation
  1456. (store-lower package->cross-derivation))
  1457. (define-gexp-compiler (package-compiler (package <package>) system target)
  1458. ;; Compile PACKAGE to a derivation for SYSTEM, optionally cross-compiled for
  1459. ;; TARGET. This is used when referring to a package from within a gexp.
  1460. (if target
  1461. (package->cross-derivation package target system)
  1462. (package->derivation package system)))
  1463. (define* (origin->derivation origin
  1464. #:optional (system (%current-system)))
  1465. "Return the derivation corresponding to ORIGIN."
  1466. (match origin
  1467. (($ <origin> uri method hash name (= force ()) #f)
  1468. ;; No patches, no snippet: this is a fixed-output derivation.
  1469. (method uri
  1470. (content-hash-algorithm hash)
  1471. (content-hash-value hash)
  1472. name #:system system))
  1473. (($ <origin> uri method hash name (= force (patches ...)) snippet
  1474. flags inputs (modules ...) guile-for-build)
  1475. ;; Patches and/or a snippet.
  1476. (mlet %store-monad ((source (method uri
  1477. (content-hash-algorithm hash)
  1478. (content-hash-value hash)
  1479. name #:system system))
  1480. (guile (package->derivation (or guile-for-build
  1481. (default-guile))
  1482. system
  1483. #:graft? #f)))
  1484. (patch-and-repack source patches
  1485. #:inputs inputs
  1486. #:snippet snippet
  1487. #:flags flags
  1488. #:system system
  1489. #:modules modules
  1490. #:guile-for-build guile)))))
  1491. (define-gexp-compiler (origin-compiler (origin <origin>) system target)
  1492. ;; Compile ORIGIN to a derivation for SYSTEM. This is used when referring
  1493. ;; to an origin from within a gexp.
  1494. (origin->derivation origin system))
  1495. (define package-source-derivation ;somewhat deprecated
  1496. (let ((lower (store-lower lower-object)))
  1497. (lambda* (store source #:optional (system (%current-system)))
  1498. "Return the derivation or file corresponding to SOURCE, which can be an
  1499. a file name or any object handled by 'lower-object', such as an <origin>.
  1500. When SOURCE is a file name, return either the interned file name (if SOURCE is
  1501. outside of the store) or SOURCE itself (if SOURCE is already a store item.)"
  1502. (match source
  1503. ((and (? string?) (? direct-store-path?) file)
  1504. file)
  1505. ((? string? file)
  1506. (add-to-store store (basename file) #t "sha256" file))
  1507. (_
  1508. (lower store source system))))))