gnu.scm 24 KB

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