packages.scm 70 KB

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