Commit | Line | Data |
---|---|---|
827d2891 | 1 | ;;; GNU Guix --- Functional package management for GNU |
a49c57a7 | 2 | ;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> |
827d2891 LC |
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 | ||
19 | (define-module (gnu packages cross-base) | |
20 | #:use-module (guix licenses) | |
21 | #:use-module (gnu packages) | |
f594028a | 22 | #:use-module (gnu packages gcc) |
827d2891 | 23 | #:use-module (gnu packages base) |
bdb36958 | 24 | #:use-module (gnu packages commencement) |
827d2891 LC |
25 | #:use-module (gnu packages linux) |
26 | #:use-module (guix packages) | |
27 | #:use-module (guix download) | |
28 | #:use-module (guix utils) | |
29 | #:use-module (guix build-system gnu) | |
30 | #:use-module (guix build-system trivial) | |
31 | #:use-module (srfi srfi-1) | |
32 | #:use-module (srfi srfi-26) | |
264218a4 LC |
33 | #:use-module (ice-9 match) |
34 | #:export (cross-binutils | |
35 | cross-libc | |
36 | cross-gcc)) | |
827d2891 LC |
37 | |
38 | (define (cross p target) | |
39 | (package (inherit p) | |
40 | (location (source-properties->location (current-source-location))) | |
41 | (name (string-append (package-name p) "-cross-" target)) | |
42 | (arguments | |
43 | (substitute-keyword-arguments (package-arguments p) | |
44 | ((#:configure-flags flags) | |
45 | `(cons ,(string-append "--target=" target) | |
46 | ,flags)))))) | |
47 | ||
47e74d6e LC |
48 | (define (cross-binutils target) |
49 | "Return a cross-Binutils for TARGET." | |
50 | (let ((binutils (package (inherit binutils) | |
51 | (arguments | |
52 | (substitute-keyword-arguments (package-arguments | |
53 | binutils) | |
54 | ((#:configure-flags flags) | |
55 | ;; Build with `--with-sysroot' so that ld honors | |
56 | ;; DT_RUNPATH entries when searching for a needed | |
57 | ;; library. This works because as a side effect | |
58 | ;; `genscripts.sh' sets `USE_LIBPATH=yes', which tells | |
59 | ;; elf32.em to use DT_RUNPATH in its search list. | |
c8fa51f2 LC |
60 | ;; See <http://sourceware.org/ml/binutils/2013-05/msg00312.html>. |
61 | ;; | |
62 | ;; In theory choosing / as the sysroot could lead ld | |
63 | ;; to pick up native libs instead of target ones. In | |
64 | ;; practice the RUNPATH of target libs only refers to | |
65 | ;; target libs, not native libs, so this is safe. | |
66 | `(cons "--with-sysroot=/" ,flags))))))) | |
47e74d6e | 67 | (cross binutils target))) |
827d2891 LC |
68 | |
69 | (define* (cross-gcc target | |
70 | #:optional (xbinutils (cross-binutils target)) libc) | |
71 | "Return a cross-compiler for TARGET, where TARGET is a GNU triplet. Use | |
72 | XBINUTILS as the associated cross-Binutils. If LIBC is false, then build a | |
73 | GCC that does not target a libc; otherwise, target that libc." | |
9ae7cee3 | 74 | (package (inherit gcc-4.8) |
827d2891 LC |
75 | (name (string-append "gcc-cross-" |
76 | (if libc "" "sans-libc-") | |
77 | target)) | |
9ae7cee3 | 78 | (source (origin (inherit (package-source gcc-4.8)) |
01eafd38 | 79 | (patches |
a49c57a7 LC |
80 | (list (search-patch |
81 | "gcc-cross-environment-variables.patch"))))) | |
82 | ||
83 | ;; For simplicity, use a single output. Otherwise libgcc_s & co. are not | |
84 | ;; found by default, etc. | |
85 | (outputs '("out")) | |
86 | ||
827d2891 LC |
87 | (arguments |
88 | `(#:implicit-inputs? #f | |
89 | #:modules ((guix build gnu-build-system) | |
90 | (guix build utils) | |
91 | (ice-9 regex) | |
92 | (srfi srfi-1) | |
93 | (srfi srfi-26)) | |
827d2891 | 94 | |
9ae7cee3 | 95 | ,@(substitute-keyword-arguments (package-arguments gcc-4.8) |
827d2891 LC |
96 | ((#:configure-flags flags) |
97 | `(append (list ,(string-append "--target=" target) | |
beda99e8 | 98 | ,@(gcc-configure-flags-for-triplet target) |
827d2891 LC |
99 | ,@(if libc |
100 | '() | |
101 | `( ;; Disable features not needed at this stage. | |
102 | "--disable-shared" "--enable-static" | |
103 | ||
104 | ;; Disable C++ because libstdc++'s | |
105 | ;; configure script otherwise fails with | |
106 | ;; "Link tests are not allowed after | |
107 | ;; GCC_NO_EXECUTABLES." | |
108 | "--enable-languages=c" | |
109 | ||
110 | "--disable-threads" ; libgcc, would need libc | |
08928e57 | 111 | "--disable-libatomic" |
827d2891 LC |
112 | "--disable-libmudflap" |
113 | "--disable-libgomp" | |
114 | "--disable-libssp" | |
115 | "--disable-libquadmath" | |
116 | "--disable-decimal-float" ; would need libc | |
117 | ))) | |
118 | ||
119 | ,(if libc | |
120 | flags | |
121 | `(remove (cut string-match "--enable-languages.*" <>) | |
122 | ,flags)))) | |
123 | ((#:make-flags flags) | |
124 | (if libc | |
125 | `(let ((libc (assoc-ref %build-inputs "libc"))) | |
126 | ;; FLAGS_FOR_TARGET are needed for the target libraries to | |
127 | ;; receive the -Bxxx for the startfiles. | |
128 | (cons (string-append "FLAGS_FOR_TARGET=-B" libc "/lib") | |
129 | ,flags)) | |
130 | flags)) | |
131 | ((#:phases phases) | |
132 | (let ((phases | |
133 | `(alist-cons-after | |
134 | 'install 'make-cross-binutils-visible | |
135 | (lambda* (#:key outputs inputs #:allow-other-keys) | |
136 | (let* ((out (assoc-ref outputs "out")) | |
137 | (libexec (string-append out "/libexec/gcc/" | |
138 | ,target)) | |
139 | (binutils (string-append | |
140 | (assoc-ref inputs "binutils-cross") | |
141 | "/bin/" ,target "-"))) | |
142 | (for-each (lambda (file) | |
143 | (symlink (string-append binutils file) | |
144 | (string-append libexec "/" | |
145 | file))) | |
146 | '("as" "ld" "nm")) | |
147 | #t)) | |
148 | ,phases))) | |
149 | (if libc | |
150 | `(alist-cons-before | |
151 | 'configure 'set-cross-path | |
152 | (lambda* (#:key inputs #:allow-other-keys) | |
153 | ;; Add the cross Linux headers to CROSS_CPATH, and remove | |
154 | ;; them from CPATH. | |
155 | (let ((libc (assoc-ref inputs "libc")) | |
156 | (linux (assoc-ref inputs | |
0d5a559f | 157 | "libc/linux-headers"))) |
827d2891 LC |
158 | (define (cross? x) |
159 | ;; Return #t if X is a cross-libc or cross Linux. | |
160 | (or (string-prefix? libc x) | |
161 | (string-prefix? linux x))) | |
162 | ||
163 | (setenv "CROSS_CPATH" | |
164 | (string-append libc "/include:" | |
165 | linux "/include")) | |
166 | (setenv "CROSS_LIBRARY_PATH" | |
167 | (string-append libc "/lib")) | |
168 | ||
169 | (let ((cpath (search-path-as-string->list | |
170 | (getenv "CPATH"))) | |
171 | (libpath (search-path-as-string->list | |
172 | (getenv "LIBRARY_PATH")))) | |
173 | (setenv "CPATH" | |
174 | (list->search-path-as-string | |
175 | (remove cross? cpath) ":")) | |
176 | (setenv "LIBRARY_PATH" | |
177 | (list->search-path-as-string | |
178 | (remove cross? libpath) ":")) | |
179 | #t))) | |
180 | ,phases) | |
181 | phases))) | |
182 | ((#:strip-binaries? _) | |
183 | ;; Disable stripping as this can break binaries, with object files | |
184 | ;; of libgcc.a showing up as having an unknown architecture. See | |
185 | ;; <http://lists.fedoraproject.org/pipermail/arm/2010-August/000663.html> | |
186 | ;; for instance. | |
187 | #f)))) | |
0de71c23 LC |
188 | |
189 | (native-inputs | |
01eafd38 | 190 | `(("binutils-cross" ,xbinutils) |
827d2891 LC |
191 | |
192 | ;; Call it differently so that the builder can check whether the "libc" | |
193 | ;; input is #f. | |
194 | ("libc-native" ,@(assoc-ref %final-inputs "libc")) | |
195 | ||
196 | ;; Remaining inputs. | |
9ae7cee3 | 197 | ,@(let ((inputs (append (package-inputs gcc-4.8) |
827d2891 LC |
198 | (alist-delete "libc" %final-inputs)))) |
199 | (if libc | |
200 | `(("libc" ,libc) | |
201 | ,@inputs) | |
17bb886f LC |
202 | inputs)))) |
203 | ||
0de71c23 LC |
204 | (inputs '()) |
205 | ||
17bb886f LC |
206 | ;; Only search target inputs, not host inputs. |
207 | (search-paths | |
208 | (list (search-path-specification | |
209 | (variable "CROSS_CPATH") | |
210 | (directories '("include"))) | |
211 | (search-path-specification | |
212 | (variable "CROSS_LIBRARY_PATH") | |
213 | (directories '("lib" "lib64"))))) | |
214 | (native-search-paths '()))) | |
827d2891 LC |
215 | |
216 | (define* (cross-libc target | |
217 | #:optional | |
218 | (xgcc (cross-gcc target)) | |
219 | (xbinutils (cross-binutils target))) | |
220 | "Return a libc cross-built for TARGET, a GNU triplet. Use XGCC and | |
221 | XBINUTILS and the cross tool chain." | |
222 | (define xlinux-headers | |
223 | (package (inherit linux-libre-headers) | |
224 | (name (string-append (package-name linux-libre-headers) | |
225 | "-cross-" target)) | |
226 | (arguments | |
0d5a559f LC |
227 | (substitute-keyword-arguments |
228 | `(#:implicit-cross-inputs? #f | |
229 | ,@(package-arguments linux-libre-headers)) | |
827d2891 LC |
230 | ((#:phases phases) |
231 | `(alist-replace | |
232 | 'build | |
233 | (lambda _ | |
234 | (setenv "ARCH" ,(system->linux-architecture target)) | |
235 | (format #t "`ARCH' set to `~a' (cross compiling)~%" (getenv "ARCH")) | |
236 | ||
237 | (and (zero? (system* "make" "defconfig")) | |
238 | (zero? (system* "make" "mrproper" "headers_check")))) | |
239 | ,phases)))) | |
0de71c23 LC |
240 | (native-inputs `(("cross-gcc" ,xgcc) |
241 | ("cross-binutils" ,xbinutils) | |
242 | ,@(package-native-inputs linux-libre-headers))))) | |
827d2891 LC |
243 | |
244 | (package (inherit glibc) | |
245 | (name (string-append "glibc-cross-" target)) | |
246 | (arguments | |
247 | (substitute-keyword-arguments | |
0d5a559f LC |
248 | `(;; Disable stripping (see above.) |
249 | #:strip-binaries? #f | |
250 | ||
251 | ;; This package is used as a target input, but it should not have | |
252 | ;; the usual cross-compilation inputs since that would include | |
253 | ;; itself. | |
254 | #:implicit-cross-inputs? #f | |
255 | ||
827d2891 LC |
256 | ,@(package-arguments glibc)) |
257 | ((#:configure-flags flags) | |
258 | `(cons ,(string-append "--host=" target) | |
259 | ,flags)) | |
260 | ((#:phases phases) | |
261 | `(alist-cons-before | |
262 | 'configure 'set-cross-linux-headers-path | |
263 | (lambda* (#:key inputs #:allow-other-keys) | |
0d5a559f | 264 | (let ((linux (assoc-ref inputs "linux-headers"))) |
827d2891 LC |
265 | (setenv "CROSS_CPATH" |
266 | (string-append linux "/include")) | |
267 | #t)) | |
268 | ,phases)))) | |
a4627d49 | 269 | |
0d5a559f LC |
270 | ;; Shadow the native "linux-headers" because glibc's recipe expect the |
271 | ;; "linux-headers" input to point to the right thing. | |
272 | (propagated-inputs `(("linux-headers" ,xlinux-headers))) | |
273 | ||
0de71c23 LC |
274 | (native-inputs `(("cross-gcc" ,xgcc) |
275 | ("cross-binutils" ,xbinutils) | |
276 | ,@(package-native-inputs glibc))))) | |
827d2891 LC |
277 | |
278 | \f | |
279 | ;;; | |
280 | ;;; Concrete cross toolchains. | |
281 | ;;; | |
282 | ||
283 | (define-public xgcc-mips64el | |
beda99e8 | 284 | (let ((triplet "mips64el-linux-gnuabi64")) ; N64 ABI |
827d2891 LC |
285 | (cross-gcc triplet |
286 | (cross-binutils triplet) | |
287 | (cross-libc triplet)))) | |
288 | ||
289 | ;; (define-public xgcc-armel | |
290 | ;; (let ((triplet "armel-linux-gnueabi")) | |
291 | ;; (cross-gcc triplet | |
292 | ;; (cross-binutils triplet) | |
293 | ;; (cross-libc triplet)))) |