gnu.scm 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  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. (gexp->derivation name builder
  389. #:system system
  390. #:target #f
  391. #:substitutable? substitutable?
  392. #:allowed-references allowed-references
  393. #:disallowed-references disallowed-references
  394. #:guile-for-build guile)))
  395. ;;;
  396. ;;; Cross-compilation.
  397. ;;;
  398. (define standard-cross-packages
  399. (mlambda (target kind)
  400. "Return the list of name/package tuples to cross-build for TARGET. KIND
  401. is one of `host' or `target'."
  402. (let* ((cross (resolve-interface '(gnu packages cross-base)))
  403. (gcc (module-ref cross 'cross-gcc))
  404. (binutils (module-ref cross 'cross-binutils))
  405. (libc (module-ref cross 'cross-libc)))
  406. (case kind
  407. ((host)
  408. ;; Cross-GCC appears once here, so that it's in $PATH...
  409. `(("cross-gcc" ,(gcc target
  410. #:xbinutils (binutils target)
  411. #:libc (libc target)))
  412. ("cross-binutils" ,(binutils target))))
  413. ((target)
  414. (let ((libc (libc target)))
  415. ;; ... and once here, so that libstdc++ & co. are in
  416. ;; CROSS_CPLUS_INCLUDE_PATH, etc.
  417. `(("cross-gcc" ,(gcc target
  418. #:xbinutils (binutils target)
  419. #:libc libc))
  420. ("cross-libc" ,libc)
  421. ;; MinGW's libc doesn't have a "static" output.
  422. ,@(if (member "static" (package-outputs libc))
  423. `(("cross-libc:static" ,libc "static"))
  424. '()))))))))
  425. (define* (gnu-cross-build name
  426. #:key
  427. target
  428. build-inputs target-inputs host-inputs
  429. guile source
  430. (outputs '("out"))
  431. (search-paths '())
  432. (native-search-paths '())
  433. (bootstrap-scripts %bootstrap-scripts)
  434. (configure-flags ''())
  435. (make-flags ''())
  436. (out-of-source? #f)
  437. (tests? #f) ; nothing can be done
  438. (test-target "check")
  439. (parallel-build? #t) (parallel-tests? #t)
  440. (patch-shebangs? #t)
  441. (strip-binaries? #t)
  442. (strip-flags %strip-flags)
  443. (strip-directories %strip-directories)
  444. (validate-runpath? #t)
  445. ;; We run 'ldconfig' to generate ld.so.cache and it
  446. ;; generally can't do that for cross-built binaries
  447. ;; ("ldconfig: foo.so is for unknown machine 40.").
  448. (make-dynamic-linker-cache? #f)
  449. (license-file-regexp %license-file-regexp)
  450. (phases '%standard-phases)
  451. (locale "en_US.utf8")
  452. (system (%current-system))
  453. (build (nix-system->gnu-triplet system))
  454. (imported-modules %gnu-build-system-modules)
  455. (modules %default-modules)
  456. (substitutable? #t)
  457. allowed-references
  458. disallowed-references)
  459. "Cross-build NAME for TARGET, where TARGET is a GNU triplet. INPUTS are
  460. cross-built inputs, and NATIVE-INPUTS are inputs that run on the build
  461. platform."
  462. (define builder
  463. #~(begin
  464. (use-modules #$@(sexp->gexp modules))
  465. (define %build-host-inputs
  466. #+(input-tuples->gexp build-inputs))
  467. (define %build-target-inputs
  468. (append #$(input-tuples->gexp host-inputs)
  469. #+(input-tuples->gexp target-inputs)))
  470. (define %outputs
  471. #$(outputs->gexp outputs))
  472. (gnu-build #:source #+source
  473. #:system #$system
  474. #:build #$build
  475. #:target #$target
  476. #:outputs %outputs
  477. #:inputs %build-target-inputs
  478. #:native-inputs %build-host-inputs
  479. #:search-paths '#$(sexp->gexp
  480. (map search-path-specification->sexp
  481. search-paths))
  482. #:native-search-paths '#$(sexp->gexp
  483. (map
  484. search-path-specification->sexp
  485. native-search-paths))
  486. #:phases #$phases
  487. #:locale #$locale
  488. #:bootstrap-scripts #$bootstrap-scripts
  489. #:configure-flags #$configure-flags
  490. #:make-flags #$make-flags
  491. #:out-of-source? #$out-of-source?
  492. #:tests? #$tests?
  493. #:test-target #$test-target
  494. #:parallel-build? #$parallel-build?
  495. #:parallel-tests? #$parallel-tests?
  496. #:patch-shebangs? #$patch-shebangs?
  497. #:license-file-regexp #$license-file-regexp
  498. #:strip-binaries? #$strip-binaries?
  499. #:validate-runpath? #$validate-runpath?
  500. #:make-dynamic-linker-cache? #$make-dynamic-linker-cache?
  501. #:license-file-regexp #$license-file-regexp
  502. #:strip-flags #$strip-flags
  503. #:strip-directories #$strip-directories)))
  504. (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
  505. system #:graft? #f)))
  506. (gexp->derivation name builder
  507. #:system system
  508. #:target target
  509. #:modules imported-modules
  510. #:substitutable? substitutable?
  511. #:allowed-references allowed-references
  512. #:disallowed-references disallowed-references
  513. #:guile-for-build guile)))
  514. (define gnu-build-system
  515. (build-system
  516. (name 'gnu)
  517. (description
  518. "The GNU Build System—i.e., ./configure && make && make install")
  519. (lower lower)))