gnu: packages: Use 'search-patches' everywhere.
[jackhill/guix/guix.git] / gnu / packages / cross-base.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016 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
20 (define-module (gnu packages cross-base)
21 #:use-module (guix licenses)
22 #:use-module (gnu packages)
23 #:use-module (gnu packages gcc)
24 #:use-module (gnu packages base)
25 #:use-module (gnu packages commencement)
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)
34 #:use-module (ice-9 match)
35 #:export (cross-binutils
36 cross-libc
37 cross-gcc))
38
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
44 (define (cross p target)
45 (package (inherit p)
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
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
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.
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)))))))
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)))
86
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.)"
90 ;; Set the current target system so that 'glibc-dynamic-linker' returns the
91 ;; right name.
92 (parameterize ((%current-target-system target))
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
98 ,@(package-arguments %xgcc))))
99 (substitute-keyword-arguments args
100 ((#:configure-flags flags)
101 `(append (list ,(string-append "--target=" target)
102 ,@(if libc
103 `( ;; Disable libcilkrts because it is not
104 ;; ported to GNU/Hurd.
105 "--disable-libcilkrts")
106 `( ;; Disable features not needed at this stage.
107 "--disable-shared" "--enable-static"
108 "--enable-languages=c,c++"
109
110 ;; libstdc++ cannot be built at this stage
111 ;; ("Link tests are not allowed after
112 ;; GCC_NO_EXECUTABLES.").
113 "--disable-libstdc++-v3"
114
115 "--disable-threads" ;libgcc, would need libc
116 "--disable-libatomic"
117 "--disable-libmudflap"
118 "--disable-libgomp"
119 "--disable-libssp"
120 "--disable-libquadmath"
121 "--disable-decimal-float" ;would need libc
122 "--disable-libcilkrts"
123 )))
124
125 ,(if libc
126 flags
127 `(remove (cut string-match "--enable-languages.*" <>)
128 ,flags))))
129 ((#:make-flags flags)
130 (if libc
131 `(let ((libc (assoc-ref %build-inputs "libc")))
132 ;; FLAGS_FOR_TARGET are needed for the target libraries to receive
133 ;; the -Bxxx for the startfiles.
134 (cons (string-append "FLAGS_FOR_TARGET=-B" libc "/lib")
135 ,flags))
136 flags))
137 ((#:phases phases)
138 (let ((phases
139 `(alist-cons-after
140 'install 'make-cross-binutils-visible
141 (lambda* (#:key outputs inputs #:allow-other-keys)
142 (let* ((out (assoc-ref outputs "out"))
143 (libexec (string-append out "/libexec/gcc/"
144 ,target))
145 (binutils (string-append
146 (assoc-ref inputs "binutils-cross")
147 "/bin/" ,target "-"))
148 (wrapper (string-append
149 (assoc-ref inputs "ld-wrapper-cross")
150 "/bin/" ,target "-ld")))
151 (for-each (lambda (file)
152 (symlink (string-append binutils file)
153 (string-append libexec "/"
154 file)))
155 '("as" "nm"))
156 (symlink wrapper (string-append libexec "/ld"))
157 #t))
158 (alist-replace
159 'install
160 (lambda _
161 ;; Unlike our 'strip' phase, this will do the right thing
162 ;; for cross-compilers.
163 (zero? (system* "make" "install-strip")))
164 ,phases))))
165 (if libc
166 `(alist-cons-before
167 'configure 'set-cross-path
168 (lambda* (#:key inputs #:allow-other-keys)
169 ;; Add the cross Linux headers to CROSS_CPATH, and remove them
170 ;; from CPATH.
171 (let ((libc (assoc-ref inputs "libc"))
172 (linux (assoc-ref inputs "xlinux-headers")))
173 (define (cross? x)
174 ;; Return #t if X is a cross-libc or cross Linux.
175 (or (string-prefix? libc x)
176 (string-prefix? linux x)))
177
178 (setenv "CROSS_CPATH"
179 (string-append libc "/include:"
180 linux "/include"))
181 (setenv "CROSS_LIBRARY_PATH"
182 (string-append libc "/lib"))
183
184 (let ((cpath (search-path-as-string->list
185 (getenv "C_INCLUDE_PATH")))
186 (libpath (search-path-as-string->list
187 (getenv "LIBRARY_PATH"))))
188 (setenv "CPATH"
189 (list->search-path-as-string
190 (remove cross? cpath) ":"))
191 (for-each unsetenv
192 '("C_INCLUDE_PATH" "CPLUS_INCLUDE_PATH"))
193 (setenv "LIBRARY_PATH"
194 (list->search-path-as-string
195 (remove cross? libpath) ":"))
196 #t)))
197 ,phases)
198 phases)))))))
199
200 (define (cross-gcc-patches target)
201 "Return GCC patches needed for TARGET."
202 (cond ((string-prefix? "xtensa-" target)
203 ;; Patch by Qualcomm needed to build the ath9k-htc firmware.
204 (search-patches "ath9k-htc-firmware-gcc.patch"))
205 (else '())))
206
207 (define* (cross-gcc target
208 #:optional (xbinutils (cross-binutils target)) libc)
209 "Return a cross-compiler for TARGET, where TARGET is a GNU triplet. Use
210 XBINUTILS as the associated cross-Binutils. If LIBC is false, then build a
211 GCC that does not target a libc; otherwise, target that libc."
212 (package (inherit %xgcc)
213 (name (string-append "gcc-cross-"
214 (if libc "" "sans-libc-")
215 target))
216 (source (origin (inherit (package-source %xgcc))
217 (patches
218 (append
219 (origin-patches (package-source %xgcc))
220 (cons (search-patch "gcc-cross-environment-variables.patch")
221 (cross-gcc-patches target))))))
222
223 ;; For simplicity, use a single output. Otherwise libgcc_s & co. are not
224 ;; found by default, etc.
225 (outputs '("out"))
226
227 (arguments
228 `(#:implicit-inputs? #f
229 #:modules ((guix build gnu-build-system)
230 (guix build utils)
231 (ice-9 regex)
232 (srfi srfi-1)
233 (srfi srfi-26))
234
235 ,@(cross-gcc-arguments target libc)))
236
237 (native-inputs
238 `(("ld-wrapper-cross" ,(make-ld-wrapper
239 (string-append "ld-wrapper-" target)
240 #:target target
241 #:binutils xbinutils))
242 ("binutils-cross" ,xbinutils)
243
244 ;; Call it differently so that the builder can check whether the "libc"
245 ;; input is #f.
246 ("libc-native" ,@(assoc-ref %final-inputs "libc"))
247
248 ;; Remaining inputs.
249 ,@(let ((inputs (append (package-inputs %xgcc)
250 (alist-delete "libc" %final-inputs))))
251 (if libc
252 `(("libc" ,libc)
253 ("xlinux-headers" ;the target headers
254 ,@(assoc-ref (package-propagated-inputs libc)
255 "linux-headers"))
256 ,@inputs)
257 inputs))))
258
259 (inputs '())
260
261 ;; Only search target inputs, not host inputs.
262 (search-paths
263 (list (search-path-specification
264 (variable "CROSS_CPATH")
265 (files '("include")))
266 (search-path-specification
267 (variable "CROSS_LIBRARY_PATH")
268 (files '("lib" "lib64")))))
269 (native-search-paths '())))
270
271 (define* (cross-libc target
272 #:optional
273 (xgcc (cross-gcc target))
274 (xbinutils (cross-binutils target)))
275 "Return a libc cross-built for TARGET, a GNU triplet. Use XGCC and
276 XBINUTILS and the cross tool chain."
277 (define xlinux-headers
278 (package (inherit linux-libre-headers)
279 (name (string-append (package-name linux-libre-headers)
280 "-cross-" target))
281 (arguments
282 (substitute-keyword-arguments
283 `(#:implicit-cross-inputs? #f
284 ,@(package-arguments linux-libre-headers))
285 ((#:phases phases)
286 `(alist-replace
287 'build
288 (lambda _
289 (setenv "ARCH" ,(system->linux-architecture target))
290 (format #t "`ARCH' set to `~a' (cross compiling)~%" (getenv "ARCH"))
291
292 (and (zero? (system* "make" "defconfig"))
293 (zero? (system* "make" "mrproper" "headers_check"))))
294 ,phases))))
295 (native-inputs `(("cross-gcc" ,xgcc)
296 ("cross-binutils" ,xbinutils)
297 ,@(package-native-inputs linux-libre-headers)))))
298
299 (package (inherit glibc)
300 (name (string-append "glibc-cross-" target))
301 (arguments
302 (substitute-keyword-arguments
303 `(;; Disable stripping (see above.)
304 #:strip-binaries? #f
305
306 ;; This package is used as a target input, but it should not have
307 ;; the usual cross-compilation inputs since that would include
308 ;; itself.
309 #:implicit-cross-inputs? #f
310
311 ,@(package-arguments glibc))
312 ((#:configure-flags flags)
313 `(cons ,(string-append "--host=" target)
314 ,flags))
315 ((#:phases phases)
316 `(alist-cons-before
317 'configure 'set-cross-linux-headers-path
318 (lambda* (#:key inputs #:allow-other-keys)
319 (let ((linux (assoc-ref inputs "linux-headers")))
320 (setenv "CROSS_CPATH"
321 (string-append linux "/include"))
322 #t))
323 ,phases))))
324
325 ;; Shadow the native "linux-headers" because glibc's recipe expects the
326 ;; "linux-headers" input to point to the right thing.
327 (propagated-inputs `(("linux-headers" ,xlinux-headers)))
328
329 ;; FIXME: 'static-bash' should really be an input, not a native input, but
330 ;; to do that will require building an intermediate cross libc.
331 (inputs '())
332
333 (native-inputs `(("cross-gcc" ,xgcc)
334 ("cross-binutils" ,xbinutils)
335 ,@(package-inputs glibc) ;FIXME: static-bash
336 ,@(package-native-inputs glibc)))))
337
338 \f
339 ;;;
340 ;;; Concrete cross toolchains.
341 ;;;
342
343 (define-public xgcc-mips64el
344 (let* ((triplet "mips64el-linux-gnuabi64") ;N64 ABI
345 (xgcc (cross-gcc triplet
346 (cross-binutils triplet)
347 (cross-libc triplet))))
348 ;; Don't attempt to build this cross-compiler on i686;
349 ;; see <http://bugs.gnu.org/19598>.
350 (package (inherit xgcc)
351 (supported-systems (fold delete
352 (package-supported-systems xgcc)
353 '("mips64el-linux" "i686-linux"))))))
354
355 (define-public xgcc-avr
356 ;; AVR cross-compiler, used to build AVR-Libc.
357 (let ((triplet "avr"))
358 (cross-gcc triplet
359 (cross-binutils triplet))))
360
361 (define-public xgcc-xtensa
362 ;; Bare-bones Xtensa cross-compiler, used to build the Atheros firmware.
363 (cross-gcc "xtensa-elf"))
364
365 (define-public xgcc-armhf
366 (let* ((triplet "arm-linux-gnueabihf")
367 (xgcc (cross-gcc triplet
368 (cross-binutils triplet)
369 (cross-libc triplet))))
370 (package (inherit xgcc)
371 (supported-systems (delete "armhf-linux" %supported-systems)))))
372
373 ;; (define-public xgcc-armel
374 ;; (let ((triplet "armel-linux-gnueabi"))
375 ;; (cross-gcc triplet
376 ;; (cross-binutils triplet)
377 ;; (cross-libc triplet))))