You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

478 lines
19 KiB

  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (gnu packages bootstrap)
  20. #:use-module (guix licenses)
  21. #:use-module (gnu packages)
  22. #:use-module (guix packages)
  23. #:use-module (guix download)
  24. #:use-module (guix build-system)
  25. #:use-module (guix build-system gnu)
  26. #:use-module (guix build-system trivial)
  27. #:use-module ((guix store) #:select (add-to-store add-text-to-store))
  28. #:use-module ((guix derivations) #:select (derivation))
  29. #:use-module (guix utils)
  30. #:use-module (srfi srfi-1)
  31. #:use-module (srfi srfi-26)
  32. #:use-module (ice-9 match)
  33. #:export (bootstrap-origin
  34. package-with-bootstrap-guile
  35. glibc-dynamic-linker
  36. %bootstrap-guile
  37. %bootstrap-coreutils&co
  38. %bootstrap-binutils
  39. %bootstrap-gcc
  40. %bootstrap-glibc
  41. %bootstrap-inputs))
  42. ;;; Commentary:
  43. ;;;
  44. ;;; Pre-built packages that are used to bootstrap the
  45. ;;; distribution--i.e., to build all the core packages from scratch.
  46. ;;;
  47. ;;; Code:
  48. ;;;
  49. ;;; Helper procedures.
  50. ;;;
  51. (define (bootstrap-origin source)
  52. "Return a variant of SOURCE, an <origin> instance, whose method uses
  53. %BOOTSTRAP-GUILE to do its job."
  54. (define (boot fetch)
  55. (lambda* (store url hash-algo hash
  56. #:optional name #:key system)
  57. (fetch store url hash-algo hash
  58. #:guile %bootstrap-guile
  59. #:system system)))
  60. (define %bootstrap-patch-inputs
  61. ;; Packages used when an <origin> has a non-empty 'patches' field.
  62. `(("tar" ,%bootstrap-coreutils&co)
  63. ("xz" ,%bootstrap-coreutils&co)
  64. ("bzip2" ,%bootstrap-coreutils&co)
  65. ("gzip" ,%bootstrap-coreutils&co)
  66. ("patch" ,%bootstrap-coreutils&co)))
  67. (let ((orig-method (origin-method source)))
  68. (origin (inherit source)
  69. (method (cond ((eq? orig-method url-fetch)
  70. (boot url-fetch))
  71. (else orig-method)))
  72. (patch-guile %bootstrap-guile)
  73. (patch-inputs %bootstrap-patch-inputs)
  74. ;; Patches can be origins as well, so process them.
  75. (patches (map (match-lambda
  76. ((? origin? patch)
  77. (bootstrap-origin patch))
  78. (patch patch))
  79. (origin-patches source))))))
  80. (define* (package-from-tarball name source program-to-test description
  81. #:key snippet)
  82. "Return a package that correspond to the extraction of SOURCE.
  83. PROGRAM-TO-TEST is a program to run after extraction of SOURCE, to
  84. check whether everything is alright. If SNIPPET is provided, it is
  85. evaluated after extracting SOURCE. SNIPPET should return true if
  86. successful, or false to signal an error."
  87. (package
  88. (name name)
  89. (version "0")
  90. (build-system trivial-build-system)
  91. (arguments
  92. `(#:guile ,%bootstrap-guile
  93. #:modules ((guix build utils))
  94. #:builder
  95. (let ((out (assoc-ref %outputs "out"))
  96. (tar (assoc-ref %build-inputs "tar"))
  97. (xz (assoc-ref %build-inputs "xz"))
  98. (tarball (assoc-ref %build-inputs "tarball")))
  99. (use-modules (guix build utils))
  100. (mkdir out)
  101. (copy-file tarball "binaries.tar.xz")
  102. (system* xz "-d" "binaries.tar.xz")
  103. (let ((builddir (getcwd)))
  104. (with-directory-excursion out
  105. (and (zero? (system* tar "xvf"
  106. (string-append builddir "/binaries.tar")))
  107. ,@(if snippet (list snippet) '())
  108. (zero? (system* (string-append "bin/" ,program-to-test)
  109. "--version"))))))))
  110. (inputs
  111. `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
  112. ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
  113. ("tarball" ,(bootstrap-origin (source (%current-system))))))
  114. (source #f)
  115. (synopsis description)
  116. (description #f)
  117. (home-page #f)
  118. (license #f)))
  119. (define package-with-bootstrap-guile
  120. (memoize
  121. (lambda (p)
  122. "Return a variant of P such that all its origins are fetched with
  123. %BOOTSTRAP-GUILE."
  124. (define rewritten-input
  125. (match-lambda
  126. ((name (? origin? o))
  127. `(,name ,(bootstrap-origin o)))
  128. ((name (? package? p) sub-drvs ...)
  129. `(,name ,(package-with-bootstrap-guile p) ,@sub-drvs))
  130. (x x)))
  131. (package (inherit p)
  132. (source (match (package-source p)
  133. ((? origin? o) (bootstrap-origin o))
  134. (s s)))
  135. (inputs (map rewritten-input
  136. (package-inputs p)))
  137. (native-inputs (map rewritten-input
  138. (package-native-inputs p)))
  139. (propagated-inputs (map rewritten-input
  140. (package-propagated-inputs p)))
  141. (replacement (and=> (package-replacement p)
  142. package-with-bootstrap-guile))))))
  143. (define* (glibc-dynamic-linker
  144. #:optional (system (or (and=> (%current-target-system)
  145. gnu-triplet->nix-system)
  146. (%current-system))))
  147. "Return the name of Glibc's dynamic linker for SYSTEM."
  148. (cond ((string=? system "x86_64-linux") "/lib/ld-linux-x86-64.so.2")
  149. ((string=? system "i686-linux") "/lib/ld-linux.so.2")
  150. ((string=? system "armhf-linux") "/lib/ld-linux-armhf.so.3")
  151. ((string=? system "mips64el-linux") "/lib/ld.so.1")
  152. ;; XXX: This one is used bare-bones, without a libc, so add a case
  153. ;; here just so we can keep going.
  154. ((string=? system "xtensa-elf") "no-ld.so")
  155. ((string=? system "avr") "no-ld.so")
  156. (else (error "dynamic linker name not known for this system"
  157. system))))
  158. ;;;
  159. ;;; Bootstrap packages.
  160. ;;;
  161. (define* (raw-build store name inputs
  162. #:key outputs system search-paths
  163. #:allow-other-keys)
  164. (define (->store file)
  165. (add-to-store store file #t "sha256"
  166. (or (search-bootstrap-binary file
  167. system)
  168. (error "bootstrap binary not found"
  169. file system))))
  170. (let* ((tar (->store "tar"))
  171. (xz (->store "xz"))
  172. (mkdir (->store "mkdir"))
  173. (bash (->store "bash"))
  174. (guile (->store (match system
  175. ("armhf-linux"
  176. "guile-2.0.11.tar.xz")
  177. (_
  178. "guile-2.0.9.tar.xz"))))
  179. (builder
  180. (add-text-to-store store
  181. "build-bootstrap-guile.sh"
  182. (format #f "
  183. echo \"unpacking bootstrap Guile to '$out'...\"
  184. ~a $out
  185. cd $out
  186. ~a -dc < ~a | ~a xv
  187. # Sanity check.
  188. $out/bin/guile --version~%"
  189. mkdir xz guile tar)
  190. (list mkdir xz guile tar))))
  191. (derivation store name
  192. bash `(,builder)
  193. #:system system
  194. #:inputs `((,bash) (,builder)))))
  195. (define* (make-raw-bag name
  196. #:key source inputs native-inputs outputs
  197. system target)
  198. (bag
  199. (name name)
  200. (system system)
  201. (build-inputs inputs)
  202. (build raw-build)))
  203. (define %bootstrap-guile
  204. ;; The Guile used to run the build scripts of the initial derivations.
  205. ;; It is just unpacked from a tarball containing a pre-built binary.
  206. ;; This is typically built using %GUILE-BOOTSTRAP-TARBALL below.
  207. ;;
  208. ;; XXX: Would need libc's `libnss_files2.so' for proper `getaddrinfo'
  209. ;; support (for /etc/services).
  210. (let ((raw (build-system
  211. (name 'raw)
  212. (description "Raw build system with direct store access")
  213. (lower make-raw-bag))))
  214. (package
  215. (name "guile-bootstrap")
  216. (version "2.0")
  217. (source #f)
  218. (build-system raw)
  219. (synopsis "Bootstrap Guile")
  220. (description "Pre-built Guile for bootstrapping purposes.")
  221. (home-page #f)
  222. (license lgpl3+))))
  223. (define %bootstrap-base-urls
  224. ;; This is where the initial binaries come from.
  225. '("http://alpha.gnu.org/gnu/guix/bootstrap"
  226. "http://www.fdn.fr/~lcourtes/software/guix/packages"))
  227. (define %bootstrap-coreutils&co
  228. (package-from-tarball "bootstrap-binaries"
  229. (lambda (system)
  230. (origin
  231. (method url-fetch)
  232. (uri (map (cut string-append <> "/" system
  233. (match system
  234. ("armhf-linux"
  235. "/20150101/static-binaries.tar.xz")
  236. (_
  237. "/20131110/static-binaries.tar.xz")))
  238. %bootstrap-base-urls))
  239. (sha256
  240. (match system
  241. ("x86_64-linux"
  242. (base32
  243. "0c533p9dhczzcsa1117gmfq3pc8w362g4mx84ik36srpr7cx2bg4"))
  244. ("i686-linux"
  245. (base32
  246. "0s5b3jb315n13m1k8095l0a5hfrsz8g0fv1b6riyc5hnxqyphlak"))
  247. ("armhf-linux"
  248. (base32
  249. "0gf0fn2kbpxkjixkmx5f4z6hv6qpmgixl69zgg74dbsfdfj8jdv5"))
  250. ("mips64el-linux"
  251. (base32
  252. "072y4wyfsj1bs80r6vbybbafy8ya4vfy7qj25dklwk97m6g71753"))))))
  253. "fgrep" ; the program to test
  254. "Bootstrap binaries of Coreutils, Awk, etc."
  255. #:snippet
  256. '(let ((path (list (string-append (getcwd) "/bin"))))
  257. (chmod "bin" #o755)
  258. (patch-shebang "bin/egrep" path)
  259. (patch-shebang "bin/fgrep" path)
  260. (chmod "bin" #o555)
  261. #t)))
  262. (define %bootstrap-binutils
  263. (package-from-tarball "binutils-bootstrap"
  264. (lambda (system)
  265. (origin
  266. (method url-fetch)
  267. (uri (map (cut string-append <> "/" system
  268. (match system
  269. ("armhf-linux"
  270. "/20150101/binutils-2.25.tar.xz")
  271. (_
  272. "/20131110/binutils-2.23.2.tar.xz")))
  273. %bootstrap-base-urls))
  274. (sha256
  275. (match system
  276. ("x86_64-linux"
  277. (base32
  278. "1j5yivz7zkjqfsfmxzrrrffwyayjqyfxgpi89df0w4qziqs2dg20"))
  279. ("i686-linux"
  280. (base32
  281. "14jgwf9gscd7l2pnz610b1zia06dvcm2qyzvni31b8zpgmcai2v9"))
  282. ("armhf-linux"
  283. (base32
  284. "1v7dj6bzn6m36f20gw31l99xaabq4xrhrx3gwqkhhig0mdlmr69q"))
  285. ("mips64el-linux"
  286. (base32
  287. "1x8kkhcxmfyzg1ddpz2pxs6fbdl6412r7x0nzbmi5n7mj8zw2gy7"))))))
  288. "ld" ; the program to test
  289. "Bootstrap binaries of the GNU Binutils"))
  290. (define %bootstrap-glibc
  291. ;; The initial libc.
  292. (package
  293. (name "glibc-bootstrap")
  294. (version "0")
  295. (source #f)
  296. (build-system trivial-build-system)
  297. (arguments
  298. `(#:guile ,%bootstrap-guile
  299. #:modules ((guix build utils))
  300. #:builder
  301. (let ((out (assoc-ref %outputs "out"))
  302. (tar (assoc-ref %build-inputs "tar"))
  303. (xz (assoc-ref %build-inputs "xz"))
  304. (tarball (assoc-ref %build-inputs "tarball")))
  305. (use-modules (guix build utils))
  306. (mkdir out)
  307. (copy-file tarball "binaries.tar.xz")
  308. (system* xz "-d" "binaries.tar.xz")
  309. (let ((builddir (getcwd)))
  310. (with-directory-excursion out
  311. (system* tar "xvf"
  312. (string-append builddir
  313. "/binaries.tar"))
  314. (chmod "lib" #o755)
  315. ;; Patch libc.so so it refers to the right path.
  316. (substitute* "lib/libc.so"
  317. (("/[^ ]+/lib/(libc|ld)" _ prefix)
  318. (string-append out "/lib/" prefix))))))))
  319. (inputs
  320. `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
  321. ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
  322. ("tarball" ,(bootstrap-origin
  323. (origin
  324. (method url-fetch)
  325. (uri (map (cut string-append <> "/" (%current-system)
  326. (match (%current-system)
  327. ("armhf-linux"
  328. "/20150101/glibc-2.20.tar.xz")
  329. (_
  330. "/20131110/glibc-2.18.tar.xz")))
  331. %bootstrap-base-urls))
  332. (sha256
  333. (match (%current-system)
  334. ("x86_64-linux"
  335. (base32
  336. "0jlqrgavvnplj1b083s20jj9iddr4lzfvwybw5xrcis9spbfzk7v"))
  337. ("i686-linux"
  338. (base32
  339. "1hgrccw1zqdc7lvgivwa54d9l3zsim5pqm0dykxg0z522h6gr05w"))
  340. ("armhf-linux"
  341. (base32
  342. "18cmgvpllqfpn6khsmivqib7ys8ymnq0hdzi3qp24prik0ykz8gn"))
  343. ("mips64el-linux"
  344. (base32
  345. "0k97a3whzx3apsi9n2cbsrr79ad6lh00klxph9hw4fqyp1abkdsg")))))))))
  346. (synopsis "Bootstrap binaries and headers of the GNU C Library")
  347. (description #f)
  348. (home-page #f)
  349. (license lgpl2.1+)))
  350. (define %bootstrap-gcc
  351. ;; The initial GCC. Uses binaries from a tarball typically built by
  352. ;; %GCC-BOOTSTRAP-TARBALL.
  353. (package
  354. (name "gcc-bootstrap")
  355. (version "0")
  356. (source #f)
  357. (build-system trivial-build-system)
  358. (arguments
  359. `(#:guile ,%bootstrap-guile
  360. #:modules ((guix build utils))
  361. #:builder
  362. (let ((out (assoc-ref %outputs "out"))
  363. (tar (assoc-ref %build-inputs "tar"))
  364. (xz (assoc-ref %build-inputs "xz"))
  365. (bash (assoc-ref %build-inputs "bash"))
  366. (libc (assoc-ref %build-inputs "libc"))
  367. (tarball (assoc-ref %build-inputs "tarball")))
  368. (use-modules (guix build utils)
  369. (ice-9 popen))
  370. (mkdir out)
  371. (copy-file tarball "binaries.tar.xz")
  372. (system* xz "-d" "binaries.tar.xz")
  373. (let ((builddir (getcwd))
  374. (bindir (string-append out "/bin")))
  375. (with-directory-excursion out
  376. (system* tar "xvf"
  377. (string-append builddir "/binaries.tar")))
  378. (with-directory-excursion bindir
  379. (chmod "." #o755)
  380. (rename-file "gcc" ".gcc-wrapped")
  381. (call-with-output-file "gcc"
  382. (lambda (p)
  383. (format p "#!~a
  384. exec ~a/bin/.gcc-wrapped -B~a/lib \
  385. -Wl,-rpath -Wl,~a/lib \
  386. -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%"
  387. bash
  388. out libc libc libc
  389. ,(glibc-dynamic-linker))))
  390. (chmod "gcc" #o555))))))
  391. (inputs
  392. `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
  393. ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
  394. ("bash" ,(search-bootstrap-binary "bash" (%current-system)))
  395. ("libc" ,%bootstrap-glibc)
  396. ("tarball" ,(bootstrap-origin
  397. (origin
  398. (method url-fetch)
  399. (uri (map (cut string-append <> "/" (%current-system)
  400. (match (%current-system)
  401. ("armhf-linux"
  402. "/20150101/gcc-4.8.4.tar.xz")
  403. (_
  404. "/20131110/gcc-4.8.2.tar.xz")))
  405. %bootstrap-base-urls))
  406. (sha256
  407. (match (%current-system)
  408. ("x86_64-linux"
  409. (base32
  410. "17ga4m6195n4fnbzdkmik834znkhs53nkypp6557pl1ps7dgqbls"))
  411. ("i686-linux"
  412. (base32
  413. "150c1arrf2k8vfy6dpxh59vcgs4p1bgiz2av5m19dynpks7rjnyw"))
  414. ("armhf-linux"
  415. (base32
  416. "0ghz825yzp43fxw53kd6afm8nkz16f7dxi9xi40bfwc8x3nbbr8v"))
  417. ("mips64el-linux"
  418. (base32
  419. "1m5miqkyng45l745n0sfafdpjkqv9225xf44jqkygwsipj2cv9ks")))))))))
  420. (native-search-paths
  421. (list (search-path-specification
  422. (variable "CPATH")
  423. (files '("include")))
  424. (search-path-specification
  425. (variable "LIBRARY_PATH")
  426. (files '("lib" "lib64")))))
  427. (synopsis "Bootstrap binaries of the GNU Compiler Collection")
  428. (description #f)
  429. (home-page #f)
  430. (license gpl3+)))
  431. (define %bootstrap-inputs
  432. ;; The initial, pre-built inputs. From now on, we can start building our
  433. ;; own packages.
  434. `(("libc" ,%bootstrap-glibc)
  435. ("gcc" ,%bootstrap-gcc)
  436. ("binutils" ,%bootstrap-binutils)
  437. ("coreutils&co" ,%bootstrap-coreutils&co)
  438. ;; In gnu-build-system.scm, we rely on the availability of Bash.
  439. ("bash" ,%bootstrap-coreutils&co)))
  440. ;;; bootstrap.scm ends here