build.scm 29 KB

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