Commit | Line | Data |
---|---|---|
827d2891 | 1 | ;;; GNU Guix --- Functional package management for GNU |
6ee01481 | 2 | ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> |
3f00ff8b | 3 | ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org> |
827d2891 LC |
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 | ||
20 | (define-module (gnu packages cross-base) | |
21 | #:use-module (guix licenses) | |
22 | #:use-module (gnu packages) | |
f594028a | 23 | #:use-module (gnu packages gcc) |
827d2891 | 24 | #:use-module (gnu packages base) |
bdb36958 | 25 | #:use-module (gnu packages commencement) |
827d2891 LC |
26 | #:use-module (gnu packages linux) |
27 | #:use-module (guix packages) | |
28 | #:use-module (guix download) | |
29 | #:use-module (guix utils) | |
30 | #:use-module (guix build-system gnu) | |
31 | #:use-module (guix build-system trivial) | |
32 | #:use-module (srfi srfi-1) | |
33 | #:use-module (srfi srfi-26) | |
264218a4 LC |
34 | #:use-module (ice-9 match) |
35 | #:export (cross-binutils | |
36 | cross-libc | |
37 | cross-gcc)) | |
827d2891 | 38 | |
c92f1c0a LC |
39 | (define %xgcc |
40 | ;; GCC package used as the basis for cross-compilation. It doesn't have to | |
41 | ;; be 'gcc' and can be a specific variant such as 'gcc-4.8'. | |
42 | gcc) | |
43 | ||
827d2891 LC |
44 | (define (cross p target) |
45 | (package (inherit p) | |
827d2891 LC |
46 | (name (string-append (package-name p) "-cross-" target)) |
47 | (arguments | |
48 | (substitute-keyword-arguments (package-arguments p) | |
49 | ((#:configure-flags flags) | |
50 | `(cons ,(string-append "--target=" target) | |
51 | ,flags)))))) | |
52 | ||
1306b0b0 LC |
53 | (define (package-with-patch original patch) |
54 | "Return package ORIGINAL with PATCH applied." | |
55 | (package (inherit original) | |
56 | (source (origin (inherit (package-source original)) | |
57 | (patches (list patch)))))) | |
58 | ||
47e74d6e LC |
59 | (define (cross-binutils target) |
60 | "Return a cross-Binutils for TARGET." | |
61 | (let ((binutils (package (inherit binutils) | |
62 | (arguments | |
63 | (substitute-keyword-arguments (package-arguments | |
64 | binutils) | |
65 | ((#:configure-flags flags) | |
66 | ;; Build with `--with-sysroot' so that ld honors | |
67 | ;; DT_RUNPATH entries when searching for a needed | |
68 | ;; library. This works because as a side effect | |
69 | ;; `genscripts.sh' sets `USE_LIBPATH=yes', which tells | |
70 | ;; elf32.em to use DT_RUNPATH in its search list. | |
c8fa51f2 LC |
71 | ;; See <http://sourceware.org/ml/binutils/2013-05/msg00312.html>. |
72 | ;; | |
73 | ;; In theory choosing / as the sysroot could lead ld | |
74 | ;; to pick up native libs instead of target ones. In | |
75 | ;; practice the RUNPATH of target libs only refers to | |
76 | ;; target libs, not native libs, so this is safe. | |
77 | `(cons "--with-sysroot=/" ,flags))))))) | |
1306b0b0 LC |
78 | |
79 | ;; For Xtensa, apply Qualcomm's patch. | |
80 | (cross (if (string-prefix? "xtensa-" target) | |
81 | (package-with-patch binutils | |
82 | (search-patch | |
83 | "ath9k-htc-firmware-binutils.patch")) | |
84 | binutils) | |
85 | target))) | |
827d2891 | 86 | |
cdb4b4b3 LC |
87 | (define (cross-gcc-arguments target libc) |
88 | "Return build system arguments for a cross-gcc for TARGET, using LIBC (which | |
89 | may be either a libc package or #f.)" | |
b4469d8c LC |
90 | ;; Set the current target system so that 'glibc-dynamic-linker' returns the |
91 | ;; right name. | |
92 | (parameterize ((%current-target-system target)) | |
2a1552c6 LC |
93 | ;; Disable stripping as this can break binaries, with object files of |
94 | ;; libgcc.a showing up as having an unknown architecture. See | |
95 | ;; <http://lists.fedoraproject.org/pipermail/arm/2010-August/000663.html> | |
96 | ;; for instance. | |
97 | (let ((args `(#:strip-binaries? #f | |
c92f1c0a | 98 | ,@(package-arguments %xgcc)))) |
2a1552c6 LC |
99 | (substitute-keyword-arguments args |
100 | ((#:configure-flags flags) | |
101 | `(append (list ,(string-append "--target=" target) | |
102 | ,@(if libc | |
8fd857f5 MR |
103 | `( ;; Disable libcilkrts because it is not |
104 | ;; ported to GNU/Hurd. | |
105 | "--disable-libcilkrts") | |
2a1552c6 LC |
106 | `( ;; Disable features not needed at this stage. |
107 | "--disable-shared" "--enable-static" | |
cdb4b4b3 | 108 | |
2a1552c6 LC |
109 | ;; Disable C++ because libstdc++'s configure |
110 | ;; script otherwise fails with "Link tests are not | |
111 | ;; allowed after GCC_NO_EXECUTABLES." | |
112 | "--enable-languages=c" | |
cdb4b4b3 | 113 | |
2a1552c6 LC |
114 | "--disable-threads" ;libgcc, would need libc |
115 | "--disable-libatomic" | |
116 | "--disable-libmudflap" | |
117 | "--disable-libgomp" | |
118 | "--disable-libssp" | |
119 | "--disable-libquadmath" | |
120 | "--disable-decimal-float" ;would need libc | |
8fd857f5 | 121 | "--disable-libcilkrts" |
2a1552c6 | 122 | ))) |
cdb4b4b3 | 123 | |
2a1552c6 LC |
124 | ,(if libc |
125 | flags | |
126 | `(remove (cut string-match "--enable-languages.*" <>) | |
127 | ,flags)))) | |
128 | ((#:make-flags flags) | |
129 | (if libc | |
130 | `(let ((libc (assoc-ref %build-inputs "libc"))) | |
131 | ;; FLAGS_FOR_TARGET are needed for the target libraries to receive | |
132 | ;; the -Bxxx for the startfiles. | |
133 | (cons (string-append "FLAGS_FOR_TARGET=-B" libc "/lib") | |
134 | ,flags)) | |
135 | flags)) | |
136 | ((#:phases phases) | |
137 | (let ((phases | |
138 | `(alist-cons-after | |
139 | 'install 'make-cross-binutils-visible | |
140 | (lambda* (#:key outputs inputs #:allow-other-keys) | |
141 | (let* ((out (assoc-ref outputs "out")) | |
142 | (libexec (string-append out "/libexec/gcc/" | |
143 | ,target)) | |
144 | (binutils (string-append | |
145 | (assoc-ref inputs "binutils-cross") | |
146 | "/bin/" ,target "-")) | |
147 | (wrapper (string-append | |
148 | (assoc-ref inputs "ld-wrapper-cross") | |
149 | "/bin/" ,target "-ld"))) | |
150 | (for-each (lambda (file) | |
151 | (symlink (string-append binutils file) | |
152 | (string-append libexec "/" | |
153 | file))) | |
154 | '("as" "nm")) | |
155 | (symlink wrapper (string-append libexec "/ld")) | |
156 | #t)) | |
157 | (alist-replace | |
158 | 'install | |
159 | (lambda _ | |
160 | ;; Unlike our 'strip' phase, this will do the right thing | |
161 | ;; for cross-compilers. | |
162 | (zero? (system* "make" "install-strip"))) | |
163 | ,phases)))) | |
164 | (if libc | |
165 | `(alist-cons-before | |
166 | 'configure 'set-cross-path | |
167 | (lambda* (#:key inputs #:allow-other-keys) | |
168 | ;; Add the cross Linux headers to CROSS_CPATH, and remove them | |
169 | ;; from CPATH. | |
170 | (let ((libc (assoc-ref inputs "libc")) | |
aa27987f | 171 | (linux (assoc-ref inputs "xlinux-headers"))) |
2a1552c6 LC |
172 | (define (cross? x) |
173 | ;; Return #t if X is a cross-libc or cross Linux. | |
174 | (or (string-prefix? libc x) | |
175 | (string-prefix? linux x))) | |
cdb4b4b3 | 176 | |
2a1552c6 LC |
177 | (setenv "CROSS_CPATH" |
178 | (string-append libc "/include:" | |
179 | linux "/include")) | |
180 | (setenv "CROSS_LIBRARY_PATH" | |
181 | (string-append libc "/lib")) | |
cdb4b4b3 | 182 | |
2a1552c6 LC |
183 | (let ((cpath (search-path-as-string->list |
184 | (getenv "CPATH"))) | |
185 | (libpath (search-path-as-string->list | |
186 | (getenv "LIBRARY_PATH")))) | |
187 | (setenv "CPATH" | |
188 | (list->search-path-as-string | |
189 | (remove cross? cpath) ":")) | |
190 | (setenv "LIBRARY_PATH" | |
191 | (list->search-path-as-string | |
192 | (remove cross? libpath) ":")) | |
193 | #t))) | |
194 | ,phases) | |
195 | phases))))))) | |
cdb4b4b3 | 196 | |
1306b0b0 LC |
197 | (define (cross-gcc-patches target) |
198 | "Return GCC patches needed for TARGET." | |
199 | (cond ((string-prefix? "xtensa-" target) | |
200 | ;; Patch by Qualcomm needed to build the ath9k-htc firmware. | |
201 | (list (search-patch "ath9k-htc-firmware-gcc.patch"))) | |
202 | (else '()))) | |
203 | ||
827d2891 LC |
204 | (define* (cross-gcc target |
205 | #:optional (xbinutils (cross-binutils target)) libc) | |
206 | "Return a cross-compiler for TARGET, where TARGET is a GNU triplet. Use | |
207 | XBINUTILS as the associated cross-Binutils. If LIBC is false, then build a | |
208 | GCC that does not target a libc; otherwise, target that libc." | |
c92f1c0a | 209 | (package (inherit %xgcc) |
827d2891 LC |
210 | (name (string-append "gcc-cross-" |
211 | (if libc "" "sans-libc-") | |
212 | target)) | |
c92f1c0a | 213 | (source (origin (inherit (package-source %xgcc)) |
01eafd38 | 214 | (patches |
1421afa9 | 215 | (append |
c92f1c0a | 216 | (origin-patches (package-source %xgcc)) |
1421afa9 MW |
217 | (cons (search-patch "gcc-cross-environment-variables.patch") |
218 | (cross-gcc-patches target)))))) | |
a49c57a7 LC |
219 | |
220 | ;; For simplicity, use a single output. Otherwise libgcc_s & co. are not | |
221 | ;; found by default, etc. | |
222 | (outputs '("out")) | |
223 | ||
827d2891 LC |
224 | (arguments |
225 | `(#:implicit-inputs? #f | |
226 | #:modules ((guix build gnu-build-system) | |
227 | (guix build utils) | |
228 | (ice-9 regex) | |
229 | (srfi srfi-1) | |
230 | (srfi srfi-26)) | |
827d2891 | 231 | |
cdb4b4b3 | 232 | ,@(cross-gcc-arguments target libc))) |
0de71c23 LC |
233 | |
234 | (native-inputs | |
4a740d0f LC |
235 | `(("ld-wrapper-cross" ,(make-ld-wrapper |
236 | (string-append "ld-wrapper-" target) | |
237 | #:target target | |
238 | #:binutils xbinutils)) | |
239 | ("binutils-cross" ,xbinutils) | |
827d2891 LC |
240 | |
241 | ;; Call it differently so that the builder can check whether the "libc" | |
242 | ;; input is #f. | |
243 | ("libc-native" ,@(assoc-ref %final-inputs "libc")) | |
244 | ||
245 | ;; Remaining inputs. | |
c92f1c0a | 246 | ,@(let ((inputs (append (package-inputs %xgcc) |
827d2891 LC |
247 | (alist-delete "libc" %final-inputs)))) |
248 | (if libc | |
249 | `(("libc" ,libc) | |
aa27987f LC |
250 | ("xlinux-headers" ;the target headers |
251 | ,@(assoc-ref (package-propagated-inputs libc) | |
252 | "linux-headers")) | |
827d2891 | 253 | ,@inputs) |
17bb886f LC |
254 | inputs)))) |
255 | ||
0de71c23 LC |
256 | (inputs '()) |
257 | ||
17bb886f LC |
258 | ;; Only search target inputs, not host inputs. |
259 | (search-paths | |
260 | (list (search-path-specification | |
261 | (variable "CROSS_CPATH") | |
af070955 | 262 | (files '("include"))) |
17bb886f LC |
263 | (search-path-specification |
264 | (variable "CROSS_LIBRARY_PATH") | |
af070955 | 265 | (files '("lib" "lib64"))))) |
17bb886f | 266 | (native-search-paths '()))) |
827d2891 LC |
267 | |
268 | (define* (cross-libc target | |
269 | #:optional | |
270 | (xgcc (cross-gcc target)) | |
271 | (xbinutils (cross-binutils target))) | |
272 | "Return a libc cross-built for TARGET, a GNU triplet. Use XGCC and | |
273 | XBINUTILS and the cross tool chain." | |
274 | (define xlinux-headers | |
275 | (package (inherit linux-libre-headers) | |
276 | (name (string-append (package-name linux-libre-headers) | |
277 | "-cross-" target)) | |
278 | (arguments | |
0d5a559f LC |
279 | (substitute-keyword-arguments |
280 | `(#:implicit-cross-inputs? #f | |
281 | ,@(package-arguments linux-libre-headers)) | |
827d2891 LC |
282 | ((#:phases phases) |
283 | `(alist-replace | |
284 | 'build | |
285 | (lambda _ | |
286 | (setenv "ARCH" ,(system->linux-architecture target)) | |
287 | (format #t "`ARCH' set to `~a' (cross compiling)~%" (getenv "ARCH")) | |
288 | ||
289 | (and (zero? (system* "make" "defconfig")) | |
290 | (zero? (system* "make" "mrproper" "headers_check")))) | |
291 | ,phases)))) | |
0de71c23 LC |
292 | (native-inputs `(("cross-gcc" ,xgcc) |
293 | ("cross-binutils" ,xbinutils) | |
294 | ,@(package-native-inputs linux-libre-headers))))) | |
827d2891 LC |
295 | |
296 | (package (inherit glibc) | |
297 | (name (string-append "glibc-cross-" target)) | |
298 | (arguments | |
299 | (substitute-keyword-arguments | |
0d5a559f LC |
300 | `(;; Disable stripping (see above.) |
301 | #:strip-binaries? #f | |
302 | ||
303 | ;; This package is used as a target input, but it should not have | |
304 | ;; the usual cross-compilation inputs since that would include | |
305 | ;; itself. | |
306 | #:implicit-cross-inputs? #f | |
307 | ||
827d2891 LC |
308 | ,@(package-arguments glibc)) |
309 | ((#:configure-flags flags) | |
310 | `(cons ,(string-append "--host=" target) | |
311 | ,flags)) | |
312 | ((#:phases phases) | |
313 | `(alist-cons-before | |
314 | 'configure 'set-cross-linux-headers-path | |
315 | (lambda* (#:key inputs #:allow-other-keys) | |
0d5a559f | 316 | (let ((linux (assoc-ref inputs "linux-headers"))) |
827d2891 LC |
317 | (setenv "CROSS_CPATH" |
318 | (string-append linux "/include")) | |
319 | #t)) | |
320 | ,phases)))) | |
a4627d49 | 321 | |
c6d33a9d | 322 | ;; Shadow the native "linux-headers" because glibc's recipe expects the |
0d5a559f LC |
323 | ;; "linux-headers" input to point to the right thing. |
324 | (propagated-inputs `(("linux-headers" ,xlinux-headers))) | |
325 | ||
12b0dbd4 LC |
326 | ;; FIXME: 'static-bash' should really be an input, not a native input, but |
327 | ;; to do that will require building an intermediate cross libc. | |
328 | (inputs '()) | |
329 | ||
0de71c23 LC |
330 | (native-inputs `(("cross-gcc" ,xgcc) |
331 | ("cross-binutils" ,xbinutils) | |
12b0dbd4 | 332 | ,@(package-inputs glibc) ;FIXME: static-bash |
0de71c23 | 333 | ,@(package-native-inputs glibc))))) |
827d2891 LC |
334 | |
335 | \f | |
336 | ;;; | |
337 | ;;; Concrete cross toolchains. | |
338 | ;;; | |
339 | ||
340 | (define-public xgcc-mips64el | |
6ee01481 LC |
341 | (let* ((triplet "mips64el-linux-gnuabi64") ;N64 ABI |
342 | (xgcc (cross-gcc triplet | |
343 | (cross-binutils triplet) | |
344 | (cross-libc triplet)))) | |
345 | ;; Don't attempt to build this cross-compiler on i686; | |
346 | ;; see <http://bugs.gnu.org/19598>. | |
347 | (package (inherit xgcc) | |
9fdd80e8 LC |
348 | (supported-systems (fold delete |
349 | (package-supported-systems xgcc) | |
350 | '("mips64el-linux" "i686-linux")))))) | |
827d2891 | 351 | |
a5b60e3c MR |
352 | (define-public xgcc-avr |
353 | ;; AVR cross-compiler, used to build AVR-Libc. | |
354 | (let ((triplet "avr")) | |
355 | (cross-gcc triplet | |
356 | (cross-binutils triplet)))) | |
357 | ||
9d307460 LC |
358 | (define-public xgcc-xtensa |
359 | ;; Bare-bones Xtensa cross-compiler, used to build the Atheros firmware. | |
360 | (cross-gcc "xtensa-elf")) | |
361 | ||
3f00ff8b | 362 | (define-public xgcc-armhf |
9fdd80e8 LC |
363 | (let* ((triplet "arm-linux-gnueabihf") |
364 | (xgcc (cross-gcc triplet | |
365 | (cross-binutils triplet) | |
366 | (cross-libc triplet)))) | |
367 | (package (inherit xgcc) | |
368 | (supported-systems (delete "armhf-linux" %supported-systems))))) | |
3f00ff8b | 369 | |
827d2891 LC |
370 | ;; (define-public xgcc-armel |
371 | ;; (let ((triplet "armel-linux-gnueabi")) | |
372 | ;; (cross-gcc triplet | |
373 | ;; (cross-binutils triplet) | |
374 | ;; (cross-libc triplet)))) |