build.scm 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2012-2023 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
  4. ;;; Copyright © 2020 Marius Bakke <mbakke@fastmail.com>
  5. ;;; Copyright © 2020 Ricardo Wurmus <rekado@elephly.net>
  6. ;;;
  7. ;;; This file is part of GNU Guix.
  8. ;;;
  9. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  10. ;;; under the terms of the GNU General Public License as published by
  11. ;;; the Free Software Foundation; either version 3 of the License, or (at
  12. ;;; your option) any later version.
  13. ;;;
  14. ;;; GNU Guix is distributed in the hope that it will be useful, but
  15. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;;; GNU General Public License for more details.
  18. ;;;
  19. ;;; You should have received a copy of the GNU General Public License
  20. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  21. (define-module (guix scripts build)
  22. #:use-module (guix ui)
  23. #:use-module (guix colors)
  24. #:use-module (guix scripts)
  25. #:autoload (guix import json) (json->scheme-file)
  26. #:use-module (guix store)
  27. #:use-module (guix derivations)
  28. #:use-module (guix packages)
  29. #:use-module (guix utils)
  30. #:use-module (guix monads)
  31. #:use-module (guix gexp)
  32. #:use-module (guix profiles)
  33. #:use-module (guix diagnostics)
  34. #:autoload (guix http-client) (http-fetch http-get-error?)
  35. #:use-module (ice-9 format)
  36. #:use-module (ice-9 match)
  37. #:use-module (srfi srfi-1)
  38. #:use-module (srfi srfi-9)
  39. #:use-module (srfi srfi-26)
  40. #:use-module (srfi srfi-34)
  41. #:use-module (srfi srfi-35)
  42. #:use-module (srfi srfi-37)
  43. #:use-module (gnu packages)
  44. #:use-module (guix platform)
  45. #:use-module ((guix status) #:select (with-status-verbosity))
  46. #:use-module ((guix progress) #:select (current-terminal-columns))
  47. #:use-module ((guix build syscalls) #:select (terminal-columns))
  48. #:use-module (guix transformations)
  49. #:export (log-url
  50. %standard-build-options
  51. %standard-cross-build-options
  52. %standard-native-build-options
  53. set-build-options-from-command-line
  54. set-build-options-from-command-line*
  55. show-build-options-help
  56. show-cross-build-options-help
  57. show-native-build-options-help
  58. guix-build
  59. register-root
  60. register-root*))
  61. (define %default-log-urls
  62. ;; Default base URLs for build logs.
  63. '("http://ci.guix.gnu.org/log"))
  64. ;; XXX: The following procedure cannot be in (guix store) because of the
  65. ;; dependency on (guix derivations).
  66. (define* (log-url store file #:key (base-urls %default-log-urls))
  67. "Return a URL under one of the BASE-URLS where a build log for FILE can be
  68. found. Return #f if no build log was found."
  69. (define (valid-url? url)
  70. ;; Probe URL and return #t if it is accessible.
  71. (catch #t
  72. (lambda ()
  73. (guard (c ((http-get-error? c) #f))
  74. (close-port (http-fetch url #:buffered? #f))
  75. #t))
  76. (match-lambda*
  77. (('getaddrinfo-error . _)
  78. #f)
  79. (('tls-certificate-error args ...)
  80. (report-error (G_ "cannot access build log at '~a':~%") url)
  81. (print-exception (current-error-port) #f
  82. 'tls-certificate-error args)
  83. (exit 1))
  84. ((key . args)
  85. (apply throw key args)))))
  86. (define (find-url file)
  87. (let ((base (basename file)))
  88. (any (lambda (base-url)
  89. (let ((url (string-append base-url "/" base)))
  90. (and (valid-url? url) url)))
  91. base-urls)))
  92. (cond ((derivation-path? file)
  93. (catch 'system-error
  94. (lambda ()
  95. ;; Usually we'll have more luck with the output file name since
  96. ;; the deriver that was used by the server could be different, so
  97. ;; try one of the output file names.
  98. (let ((drv (read-derivation-from-file file)))
  99. (or (find-url (derivation->output-path drv))
  100. (find-url file))))
  101. (lambda args
  102. ;; As a last resort, try the .drv.
  103. (if (= ENOENT (system-error-errno args))
  104. (find-url file)
  105. (apply throw args)))))
  106. (else
  107. (find-url file))))
  108. (define (register-root store paths root)
  109. "Register ROOT as an indirect GC root for all of PATHS."
  110. (let* ((root (if (string-prefix? "/" root)
  111. root
  112. (string-append (canonicalize-path (dirname root))
  113. "/" (basename root)))))
  114. (catch 'system-error
  115. (lambda ()
  116. (match paths
  117. ((path)
  118. (symlink path root)
  119. (add-indirect-root store root))
  120. ((paths ...)
  121. (fold (lambda (path count)
  122. (let ((root (string-append root
  123. "-"
  124. (number->string count))))
  125. (symlink path root)
  126. (add-indirect-root store root))
  127. (+ 1 count))
  128. 0
  129. paths))))
  130. (lambda args
  131. (leave (G_ "failed to create GC root `~a': ~a~%")
  132. root (strerror (system-error-errno args)))))))
  133. (define register-root*
  134. (store-lift register-root))
  135. ;;;
  136. ;;; Standard command-line build options.
  137. ;;;
  138. (define (show-build-options-help)
  139. "Display on the current output port help about the standard command-line
  140. options handled by 'set-build-options-from-command-line', and listed in
  141. '%standard-build-options'."
  142. (display (G_ "
  143. -L, --load-path=DIR prepend DIR to the package module search path"))
  144. (display (G_ "
  145. -K, --keep-failed keep build tree of failed builds"))
  146. (display (G_ "
  147. -k, --keep-going keep going when some of the derivations fail"))
  148. (display (G_ "
  149. -n, --dry-run do not build the derivations"))
  150. (display (G_ "
  151. --fallback fall back to building when the substituter fails"))
  152. (display (G_ "
  153. --no-substitutes build instead of resorting to pre-built substitutes"))
  154. (display (G_ "
  155. --substitute-urls=URLS
  156. fetch substitute from URLS if they are authorized"))
  157. (display (G_ "
  158. --no-grafts do not graft packages"))
  159. (display (G_ "
  160. --no-offload do not attempt to offload builds"))
  161. (display (G_ "
  162. --max-silent-time=SECONDS
  163. mark the build as failed after SECONDS of silence"))
  164. (display (G_ "
  165. --timeout=SECONDS mark the build as failed after SECONDS of activity"))
  166. (display (G_ "
  167. --rounds=N build N times in a row to detect non-determinism"))
  168. (display (G_ "
  169. -c, --cores=N allow the use of up to N CPU cores for the build"))
  170. (display (G_ "
  171. -M, --max-jobs=N allow at most N build jobs"))
  172. (display (G_ "
  173. --debug=LEVEL produce debugging output at LEVEL")))
  174. (define (show-cross-build-options-help)
  175. (display (G_ "
  176. --list-targets list available targets"))
  177. (display (G_ "
  178. --target=TRIPLET cross-build for TRIPLET--e.g., \"aarch64-linux-gnu\"")))
  179. (define (show-native-build-options-help)
  180. (display (G_ "
  181. --list-systems list available systems"))
  182. (display (G_ "
  183. -s, --system=SYSTEM attempt to build for SYSTEM--e.g., \"i686-linux\"")))
  184. (define (set-build-options-from-command-line store opts)
  185. "Given OPTS, an alist as returned by 'args-fold' given
  186. '%standard-build-options', set the corresponding build options on STORE."
  187. ;; '--keep-failed' has no effect when talking to a remote daemon. Catch the
  188. ;; case where GUIX_DAEMON_SOCKET=guix://….
  189. (when (and (assoc-ref opts 'keep-failed?)
  190. (let* ((socket (store-connection-socket store))
  191. (peer (catch 'system-error
  192. (lambda ()
  193. (and (file-port? socket)
  194. (getpeername socket)))
  195. (const #f))))
  196. (and peer (not (= AF_UNIX (sockaddr:fam peer))))))
  197. (warning (G_ "'--keep-failed' ignored since you are \
  198. talking to a remote daemon\n")))
  199. (set-build-options store
  200. #:keep-failed? (assoc-ref opts 'keep-failed?)
  201. #:keep-going? (assoc-ref opts 'keep-going?)
  202. #:rounds (assoc-ref opts 'rounds)
  203. #:build-cores (assoc-ref opts 'cores)
  204. #:max-build-jobs (assoc-ref opts 'max-jobs)
  205. #:fallback? (assoc-ref opts 'fallback?)
  206. #:use-substitutes? (assoc-ref opts 'substitutes?)
  207. #:substitute-urls (assoc-ref opts 'substitute-urls)
  208. #:offload? (and (assoc-ref opts 'offload?)
  209. (not (assoc-ref opts 'keep-failed?)))
  210. #:max-silent-time (assoc-ref opts 'max-silent-time)
  211. #:timeout (assoc-ref opts 'timeout)
  212. #:print-build-trace (assoc-ref opts 'print-build-trace?)
  213. #:print-extended-build-trace?
  214. (assoc-ref opts 'print-extended-build-trace?)
  215. #:multiplexed-build-output?
  216. (assoc-ref opts 'multiplexed-build-output?)
  217. #:verbosity (assoc-ref opts 'debug)))
  218. (define set-build-options-from-command-line*
  219. (store-lift set-build-options-from-command-line))
  220. (define %standard-build-options
  221. ;; List of standard command-line options for tools that build something.
  222. (list (option '(#\L "load-path") #t #f
  223. (lambda (opt name arg result . rest)
  224. ;; XXX: Imperatively modify the search paths.
  225. (%package-module-path (cons arg (%package-module-path)))
  226. (%patch-path (cons arg (%patch-path)))
  227. (set! %load-path (cons arg %load-path))
  228. (set! %load-compiled-path (cons arg %load-compiled-path))
  229. (apply values (cons result rest))))
  230. (option '(#\K "keep-failed") #f #f
  231. (lambda (opt name arg result . rest)
  232. (apply values
  233. (alist-cons 'keep-failed? #t result)
  234. rest)))
  235. (option '(#\k "keep-going") #f #f
  236. (lambda (opt name arg result . rest)
  237. (apply values
  238. (alist-cons 'keep-going? #t result)
  239. rest)))
  240. (option '("rounds") #t #f
  241. (lambda (opt name arg result . rest)
  242. (apply values
  243. (alist-cons 'rounds (string->number* arg)
  244. result)
  245. rest)))
  246. (option '("fallback") #f #f
  247. (lambda (opt name arg result . rest)
  248. (apply values
  249. (alist-cons 'fallback? #t
  250. (alist-delete 'fallback? result))
  251. rest)))
  252. (option '("no-substitutes") #f #f
  253. (lambda (opt name arg result . rest)
  254. (apply values
  255. (alist-cons 'substitutes? #f
  256. (alist-delete 'substitutes? result))
  257. rest)))
  258. (option '("substitute-urls") #t #f
  259. (lambda (opt name arg result . rest)
  260. (apply values
  261. (alist-cons 'substitute-urls
  262. (string-tokenize arg)
  263. (alist-delete 'substitute-urls result))
  264. rest)))
  265. (option '("no-grafts") #f #f
  266. (lambda (opt name arg result . rest)
  267. (apply values
  268. (alist-cons 'graft? #f
  269. (alist-delete 'graft? result eq?))
  270. rest)))
  271. (option '("no-offload" "no-build-hook") #f #f
  272. (lambda (opt name arg result . rest)
  273. (when (string=? name "no-build-hook")
  274. (warning (G_ "'--no-build-hook' is deprecated; \
  275. use '--no-offload' instead~%")))
  276. (apply values
  277. (alist-cons 'offload? #f
  278. (alist-delete 'offload? result))
  279. rest)))
  280. (option '("max-silent-time") #t #f
  281. (lambda (opt name arg result . rest)
  282. (apply values
  283. (alist-cons 'max-silent-time (string->number* arg)
  284. result)
  285. rest)))
  286. (option '("timeout") #t #f
  287. (lambda (opt name arg result . rest)
  288. (apply values
  289. (alist-cons 'timeout (string->number* arg) result)
  290. rest)))
  291. (option '("debug") #t #f
  292. (lambda (opt name arg result . rest)
  293. (let ((level (string->number* arg)))
  294. (apply values
  295. (alist-cons 'debug level
  296. (alist-delete 'debug result))
  297. rest))))
  298. (option '(#\c "cores") #t #f
  299. (lambda (opt name arg result . rest)
  300. (let ((c (false-if-exception (string->number arg))))
  301. (if c
  302. (apply values (alist-cons 'cores c result) rest)
  303. (leave (G_ "not a number: '~a' option argument: ~a~%")
  304. name arg)))))
  305. (option '(#\M "max-jobs") #t #f
  306. (lambda (opt name arg result . rest)
  307. (let ((c (false-if-exception (string->number arg))))
  308. (if c
  309. (apply values (alist-cons 'max-jobs c result) rest)
  310. (leave (G_ "not a number: '~a' option argument: ~a~%")
  311. name arg)))))))
  312. (define (list-systems)
  313. "Print the available systems."
  314. (display (G_ "The available systems are:\n"))
  315. (newline)
  316. (let ((systems*
  317. (map (lambda (system)
  318. (if (string=? system (%current-system))
  319. (highlight
  320. (string-append system " [current]"))
  321. system))
  322. (systems))))
  323. (format #t "~{ - ~a ~%~}"
  324. (sort systems* string<?))))
  325. (define (list-targets)
  326. "Print the available targets."
  327. (display (G_ "The available targets are:\n"))
  328. (newline)
  329. (format #t "~{ - ~a ~%~}"
  330. (sort (targets) string<?)))
  331. (define %standard-cross-build-options
  332. ;; Build options related to cross builds.
  333. (list
  334. (option '("list-targets") #f #f
  335. (lambda (opt name arg result)
  336. (list-targets)
  337. (exit 0)))
  338. (option '("target") #t #f
  339. (lambda (opt name arg result . rest)
  340. (let ((t (false-if-exception
  341. (first (member arg (targets))))))
  342. (if t
  343. (apply values (alist-cons 'target t result) rest)
  344. (let ((closest (string-closest arg (targets)
  345. #:threshold 5)))
  346. (report-error
  347. (G_ "'~a' is not a supported cross-compilation target~%")
  348. arg)
  349. (if closest
  350. (display-hint
  351. (G_ "Did you mean @code{~a}?
  352. Try @option{--list-targets} to view available targets.~%")
  353. closest)
  354. (display-hint
  355. (G_ "\
  356. Try @option{--list-targets} to view available targets.~%")))
  357. (exit 1))))))))
  358. (define %standard-native-build-options
  359. ;; Build options related to native builds.
  360. (list
  361. (option '("list-systems") #f #f
  362. (lambda (opt name arg result)
  363. (list-systems)
  364. (exit 0)))
  365. (option '(#\s "system") #t #f
  366. (lambda (opt name arg result . rest)
  367. (let ((s (false-if-exception
  368. (first (member arg (systems))))))
  369. (if s
  370. (apply values (alist-cons 'system s result) rest)
  371. (let ((closest (string-closest arg (systems)
  372. #:threshold 5)))
  373. (report-error (G_ "'~a' is not a supported system~%")
  374. arg)
  375. (if closest
  376. (display-hint
  377. (G_ "Did you mean @code{~a}?
  378. Try @option{--list-systems} to view available system types.~%")
  379. closest)
  380. (display-hint
  381. (G_ "\
  382. Try @option{--list-systems} to view available system types.~%")))
  383. (exit 1))))))))
  384. ;;;
  385. ;;; Command-line options.
  386. ;;;
  387. (define %default-options
  388. ;; Alist of default option values.
  389. `((build-mode . ,(build-mode normal))
  390. (graft? . #t)
  391. (substitutes? . #t)
  392. (offload? . #t)
  393. (print-build-trace? . #t)
  394. (print-extended-build-trace? . #t)
  395. (multiplexed-build-output? . #t)
  396. (verbosity . 3)
  397. (debug . 0)))
  398. (define (show-help)
  399. (display (G_ "Usage: guix build [OPTION]... PACKAGE-OR-DERIVATION...
  400. Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
  401. (display (G_ "
  402. -e, --expression=EXPR build the package or derivation EXPR evaluates to"))
  403. (display (G_ "
  404. -f, --file=FILE build the package or derivation that the code within
  405. FILE evaluates to"))
  406. (display (G_ "
  407. -m, --manifest=FILE build the packages that the manifest given in FILE
  408. evaluates to"))
  409. (display (G_ "
  410. -S, --source build the packages' source derivations"))
  411. (display (G_ "
  412. --sources[=TYPE] build source derivations; TYPE may optionally be one
  413. of \"package\", \"all\" (default), or \"transitive\""))
  414. (display (G_ "
  415. -d, --derivations return the derivation paths of the given packages"))
  416. (display (G_ "
  417. --check rebuild items to check for non-determinism issues"))
  418. (display (G_ "
  419. --repair repair the specified items"))
  420. (display (G_ "
  421. -r, --root=FILE make FILE a symlink to the result, and register it
  422. as a garbage collector root"))
  423. (display (G_ "
  424. -v, --verbosity=LEVEL use the given verbosity LEVEL"))
  425. (display (G_ "
  426. -q, --quiet do not show the build log"))
  427. (display (G_ "
  428. --log-file return the log file names for the given derivations"))
  429. (newline)
  430. (show-build-options-help)
  431. (newline)
  432. (show-cross-build-options-help)
  433. (newline)
  434. (show-native-build-options-help)
  435. (newline)
  436. (show-transformation-options-help)
  437. (newline)
  438. (display (G_ "
  439. -h, --help display this help and exit"))
  440. (display (G_ "
  441. -V, --version display version information and exit"))
  442. (newline)
  443. (show-bug-report-information))
  444. (define %options
  445. ;; Specifications of the command-line options.
  446. (cons* (option '(#\h "help") #f #f
  447. (lambda args
  448. (show-help)
  449. (exit 0)))
  450. (option '(#\V "version") #f #f
  451. (lambda args
  452. (show-version-and-exit "guix build")))
  453. (option '(#\S "source") #f #f
  454. (lambda (opt name arg result)
  455. (alist-cons 'source #t result)))
  456. (option '("sources") #f #t
  457. (lambda (opt name arg result)
  458. (match arg
  459. ("package"
  460. (alist-cons 'source #t result))
  461. ((or "all" #f)
  462. (alist-cons 'source package-direct-sources result))
  463. ("transitive"
  464. (alist-cons 'source package-transitive-sources result))
  465. (else
  466. (leave (G_ "invalid argument: '~a' option argument: ~a, ~
  467. must be one of 'package', 'all', or 'transitive'~%")
  468. name arg)))))
  469. (option '("check") #f #f
  470. (lambda (opt name arg result . rest)
  471. (apply values
  472. (alist-cons 'build-mode (build-mode check)
  473. result)
  474. rest)))
  475. (option '("repair") #f #f
  476. (lambda (opt name arg result . rest)
  477. (apply values
  478. (alist-cons 'build-mode (build-mode repair)
  479. result)
  480. rest)))
  481. (option '(#\d "derivations") #f #f
  482. (lambda (opt name arg result)
  483. (alist-cons 'derivations-only? #t result)))
  484. (option '(#\e "expression") #t #f
  485. (lambda (opt name arg result)
  486. (alist-cons 'expression arg result)))
  487. (option '(#\f "file") #t #f
  488. (lambda (opt name arg result)
  489. (alist-cons 'file arg result)))
  490. (option '(#\m "manifest") #t #f
  491. (lambda (opt name arg result)
  492. (alist-cons 'manifest arg result)))
  493. (option '(#\n "dry-run") #f #f
  494. (lambda (opt name arg result)
  495. (alist-cons 'dry-run? #t result)))
  496. (option '(#\r "root") #t #f
  497. (lambda (opt name arg result)
  498. (alist-cons 'gc-root arg result)))
  499. (option '(#\v "verbosity") #t #f
  500. (lambda (opt name arg result)
  501. (let ((level (string->number* arg)))
  502. (alist-cons 'verbosity level
  503. (alist-delete 'verbosity result)))))
  504. (option '(#\q "quiet") #f #f
  505. (lambda (opt name arg result)
  506. (alist-cons 'verbosity 0
  507. (alist-delete 'verbosity result))))
  508. (option '("log-file") #f #f
  509. (lambda (opt name arg result)
  510. (alist-cons 'log-file? #t result)))
  511. (append %transformation-options
  512. %standard-build-options
  513. %standard-cross-build-options
  514. %standard-native-build-options)))
  515. (define (options->things-to-build opts)
  516. "Read the arguments from OPTS and return a list of high-level objects to
  517. build---packages, gexps, derivations, and so on."
  518. (define (validate-type x)
  519. (unless (or (derivation? x) (file-like? x) (gexp? x) (procedure? x))
  520. (raise (make-compound-condition
  521. (formatted-message (G_ "~s: not something we can build~%") x)
  522. (condition
  523. (&fix-hint
  524. (hint
  525. (if (unspecified? x)
  526. (G_ "If you build from a file, make sure the last Scheme
  527. expression returns a package value. @code{define-public} defines a variable,
  528. but returns @code{#<unspecified>}. To fix this, add a Scheme expression at
  529. the end of the file that consists only of the package's variable name you
  530. defined, as in this example:
  531. @example
  532. (define-public my-package
  533. (package
  534. ...))
  535. my-package
  536. @end example")
  537. (G_ "If you build from a file, make sure the last
  538. Scheme expression returns a package, gexp, derivation or a list of such
  539. values.")))))))))
  540. (define (ensure-list x)
  541. (let ((lst (match x
  542. ((x ...) x)
  543. (x (list x)))))
  544. (for-each validate-type lst)
  545. lst))
  546. (append-map (match-lambda
  547. (('argument . (? string? spec))
  548. (cond ((derivation-path? spec)
  549. (catch 'system-error
  550. (lambda ()
  551. ;; Ask for absolute file names so that .drv file
  552. ;; names passed from the user to 'read-derivation'
  553. ;; are absolute when it returns.
  554. (let ((spec (canonicalize-path spec)))
  555. (list (read-derivation-from-file spec))))
  556. (lambda args
  557. ;; Non-existent .drv files can be substituted down
  558. ;; the road, so don't error out.
  559. (if (= ENOENT (system-error-errno args))
  560. '()
  561. (apply throw args)))))
  562. ((store-path? spec)
  563. ;; Nothing to do; maybe for --log-file.
  564. '())
  565. (else
  566. (list (specification->package spec)))))
  567. (('file . file)
  568. (let ((file (or (and (string-suffix? ".json" file)
  569. (json->scheme-file file))
  570. file)))
  571. (ensure-list (load* file (make-user-module '())))))
  572. (('manifest . manifest)
  573. (map manifest-entry-item
  574. (manifest-entries
  575. (load* manifest
  576. (make-user-module '((guix profiles) (gnu)))))))
  577. (('expression . str)
  578. (ensure-list (read/eval str)))
  579. (('argument . (? derivation? drv))
  580. drv)
  581. (_ '()))
  582. opts))
  583. (define (options->derivations store opts)
  584. "Given OPTS, the result of 'args-fold', return a list of derivations to
  585. build."
  586. (define transform
  587. (options->transformation opts))
  588. (define package->derivation
  589. (match (assoc-ref opts 'target)
  590. (#f package-derivation)
  591. (triplet
  592. (cut package-cross-derivation <> <> triplet <>))))
  593. (define src (assoc-ref opts 'source))
  594. (define graft? (assoc-ref opts 'graft?))
  595. (define systems
  596. (match (filter-map (match-lambda
  597. (('system . system) system)
  598. (_ #f))
  599. opts)
  600. (() (list (%current-system)))
  601. (systems systems)))
  602. (define things-to-build
  603. (map transform (options->things-to-build opts)))
  604. (define warn-if-unsupported
  605. (let ((target (assoc-ref opts 'target)))
  606. (if target
  607. (lambda (package system)
  608. ;; We cannot tell whether PACKAGE supports TARGET.
  609. package)
  610. (lambda (package system)
  611. (match package
  612. ((? package? package)
  613. (unless (supported-package? package system)
  614. (warning (package-location package)
  615. (G_ "package ~a does not support ~a~%")
  616. (package-full-name package) system))
  617. package)
  618. (x x))))))
  619. (define (compute-derivation obj system)
  620. ;; Compute the derivation of OBJ for SYSTEM.
  621. (match obj
  622. ((? package? p)
  623. (let ((p (warn-if-unsupported
  624. (or (and graft? (package-replacement p)) p)
  625. system)))
  626. (match src
  627. (#f
  628. (list (package->derivation store p system)))
  629. (#t
  630. (match (package-source p)
  631. (#f
  632. (warning (package-location p)
  633. (G_ "package '~a' has no source~%")
  634. (package-name p))
  635. '())
  636. (s
  637. (list (package-source-derivation store s)))))
  638. (proc
  639. (map (cut package-source-derivation store <>)
  640. (proc p))))))
  641. ((? derivation? drv)
  642. (list drv))
  643. ((? procedure? proc)
  644. (list (run-with-store store
  645. (mbegin %store-monad
  646. (set-guile-for-build (default-guile))
  647. (proc))
  648. #:system system)))
  649. ((? file-like? obj)
  650. (list (run-with-store store
  651. (lower-object obj system
  652. #:target (assoc-ref opts 'target))
  653. #:system system)))
  654. ((? gexp? gexp)
  655. (list (run-with-store store
  656. (mbegin %store-monad
  657. (set-guile-for-build (default-guile))
  658. (gexp->derivation "gexp" gexp
  659. #:system system))
  660. #:system system)))))
  661. ;; We may get 'unbound-variable' errors while evaluating the 'inputs' fields
  662. ;; of user packages. Since 'guix build' is the primary tool for people
  663. ;; testing new packages, report such errors gracefully.
  664. (with-unbound-variable-handling
  665. (parameterize ((%graft? graft?))
  666. (append-map (lambda (system)
  667. (concatenate
  668. (map/accumulate-builds store
  669. (cut compute-derivation <> system)
  670. things-to-build)))
  671. systems))))
  672. (define (show-build-log store file urls)
  673. "Show the build log for FILE, falling back to remote logs from URLS if
  674. needed."
  675. (let ((log (or (log-file store file)
  676. (log-url store file #:base-urls urls))))
  677. (if log
  678. (format #t "~a~%" log)
  679. (leave (G_ "no build log for '~a'~%") file))))
  680. ;;;
  681. ;;; Entry point.
  682. ;;;
  683. (define-command (guix-build . args)
  684. (category packaging)
  685. (synopsis "build packages or derivations without installing them")
  686. (define opts
  687. (parse-command-line args %options
  688. (list %default-options)))
  689. (define graft?
  690. (assoc-ref opts 'graft?))
  691. (with-error-handling
  692. (with-status-verbosity (assoc-ref opts 'verbosity)
  693. (with-store store
  694. ;; Set the build options before we do anything else.
  695. (set-build-options-from-command-line store opts)
  696. (with-build-handler (build-notifier #:use-substitutes?
  697. (assoc-ref opts 'substitutes?)
  698. #:verbosity
  699. (assoc-ref opts 'verbosity)
  700. #:dry-run?
  701. (assoc-ref opts 'dry-run?))
  702. (parameterize ((current-terminal-columns (terminal-columns))
  703. ;; Set grafting upfront in case the user's input
  704. ;; depends on it (e.g., a manifest or code snippet that
  705. ;; calls 'gexp->derivation').
  706. (%graft? graft?))
  707. (let* ((mode (assoc-ref opts 'build-mode))
  708. (drv (options->derivations store opts))
  709. (urls (map (cut string-append <> "/log")
  710. (if (assoc-ref opts 'substitutes?)
  711. (or (assoc-ref opts 'substitute-urls)
  712. ;; XXX: This does not necessarily match the
  713. ;; daemon's substitute URLs.
  714. %default-substitute-urls)
  715. '())))
  716. (items (filter-map (match-lambda
  717. (('argument . (? store-path? file))
  718. ;; If FILE is a .drv that's not in
  719. ;; store, keep it so that it can be
  720. ;; substituted.
  721. (and (or (not (derivation-path? file))
  722. (not (file-exists? file)))
  723. file))
  724. (_ #f))
  725. opts))
  726. (roots (filter-map (match-lambda
  727. (('gc-root . root) root)
  728. (_ #f))
  729. opts)))
  730. (when (and (null? drv) (null? items))
  731. (warning (G_ "no arguments specified, nothing to do~%")))
  732. (cond ((assoc-ref opts 'log-file?)
  733. ;; Pass 'show-build-log' the output file names, not the
  734. ;; derivation file names, because there can be several
  735. ;; derivations leading to the same output.
  736. (for-each (cut show-build-log store <> urls)
  737. (delete-duplicates
  738. (append (map derivation->output-path drv)
  739. items))))
  740. ((assoc-ref opts 'derivations-only?)
  741. (format #t "~{~a~%~}" (map derivation-file-name drv))
  742. (for-each (cut register-root store <> <>)
  743. (map (compose list derivation-file-name) drv)
  744. roots))
  745. (else
  746. (and (build-derivations store (append drv items)
  747. mode)
  748. (for-each show-derivation-outputs drv)
  749. (for-each (cut register-root store <> <>)
  750. (map (lambda (drv)
  751. (map cdr
  752. (derivation->output-paths drv)))
  753. drv)
  754. roots)))))))))))