gnu.scm 24 KB

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