build-system/{perl,cmake}: Keep the standard search paths of gnu-build-system.
[jackhill/guix/guix.git] / gnu / packages / cross-base.scm
CommitLineData
827d2891
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013 Ludovic Courtès <ludo@gnu.org>
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)
22 #:use-module (gnu packages base)
23 #:use-module (gnu packages linux)
24 #:use-module (guix packages)
25 #:use-module (guix download)
26 #:use-module (guix utils)
27 #:use-module (guix build-system gnu)
28 #:use-module (guix build-system trivial)
29 #:use-module (srfi srfi-1)
30 #:use-module (srfi srfi-26)
31 #:use-module (ice-9 match))
32
33(define (cross p target)
34 (package (inherit p)
35 (location (source-properties->location (current-source-location)))
36 (name (string-append (package-name p) "-cross-" target))
37 (arguments
38 (substitute-keyword-arguments (package-arguments p)
39 ((#:configure-flags flags)
40 `(cons ,(string-append "--target=" target)
41 ,flags))))))
42
43(define cross-binutils
44 (cut cross binutils <>))
45
46(define* (cross-gcc target
47 #:optional (xbinutils (cross-binutils target)) libc)
48 "Return a cross-compiler for TARGET, where TARGET is a GNU triplet. Use
49XBINUTILS as the associated cross-Binutils. If LIBC is false, then build a
50GCC that does not target a libc; otherwise, target that libc."
51 (define args
52 ;; Get the arguments as if we were building for TARGET. In particular, we
53 ;; want `glibc-dynamic-linker' to return the right thing.
54 (parameterize ((%current-system (gnu-triplet->nix-system target)))
55 (package-arguments gcc-4.7)))
56
57 (package (inherit gcc-4.7)
58 (name (string-append "gcc-cross-"
59 (if libc "" "sans-libc-")
60 target))
61 (arguments
62 `(#:implicit-inputs? #f
63 #:modules ((guix build gnu-build-system)
64 (guix build utils)
65 (ice-9 regex)
66 (srfi srfi-1)
67 (srfi srfi-26))
68 #:patches (list (assoc-ref %build-inputs "patch/cross-env-vars"))
69
70 ,@(substitute-keyword-arguments args
71 ((#:configure-flags flags)
72 `(append (list ,(string-append "--target=" target)
73 ,@(if libc
74 '()
75 `( ;; Disable features not needed at this stage.
76 "--disable-shared" "--enable-static"
77
78 ;; Disable C++ because libstdc++'s
79 ;; configure script otherwise fails with
80 ;; "Link tests are not allowed after
81 ;; GCC_NO_EXECUTABLES."
82 "--enable-languages=c"
83
84 "--disable-threads" ; libgcc, would need libc
85 "--disable-libmudflap"
86 "--disable-libgomp"
87 "--disable-libssp"
88 "--disable-libquadmath"
89 "--disable-decimal-float" ; would need libc
90 )))
91
92 ,(if libc
93 flags
94 `(remove (cut string-match "--enable-languages.*" <>)
95 ,flags))))
96 ((#:make-flags flags)
97 (if libc
98 `(let ((libc (assoc-ref %build-inputs "libc")))
99 ;; FLAGS_FOR_TARGET are needed for the target libraries to
100 ;; receive the -Bxxx for the startfiles.
101 (cons (string-append "FLAGS_FOR_TARGET=-B" libc "/lib")
102 ,flags))
103 flags))
104 ((#:phases phases)
105 (let ((phases
106 `(alist-cons-after
107 'install 'make-cross-binutils-visible
108 (lambda* (#:key outputs inputs #:allow-other-keys)
109 (let* ((out (assoc-ref outputs "out"))
110 (libexec (string-append out "/libexec/gcc/"
111 ,target))
112 (binutils (string-append
113 (assoc-ref inputs "binutils-cross")
114 "/bin/" ,target "-")))
115 (for-each (lambda (file)
116 (symlink (string-append binutils file)
117 (string-append libexec "/"
118 file)))
119 '("as" "ld" "nm"))
120 #t))
121 ,phases)))
122 (if libc
123 `(alist-cons-before
124 'configure 'set-cross-path
125 (lambda* (#:key inputs #:allow-other-keys)
126 ;; Add the cross Linux headers to CROSS_CPATH, and remove
127 ;; them from CPATH.
128 (let ((libc (assoc-ref inputs "libc"))
129 (linux (assoc-ref inputs
130 "libc/cross-linux-headers")))
131 (define (cross? x)
132 ;; Return #t if X is a cross-libc or cross Linux.
133 (or (string-prefix? libc x)
134 (string-prefix? linux x)))
135
136 (setenv "CROSS_CPATH"
137 (string-append libc "/include:"
138 linux "/include"))
139 (setenv "CROSS_LIBRARY_PATH"
140 (string-append libc "/lib"))
141
142 (let ((cpath (search-path-as-string->list
143 (getenv "CPATH")))
144 (libpath (search-path-as-string->list
145 (getenv "LIBRARY_PATH"))))
146 (setenv "CPATH"
147 (list->search-path-as-string
148 (remove cross? cpath) ":"))
149 (setenv "LIBRARY_PATH"
150 (list->search-path-as-string
151 (remove cross? libpath) ":"))
152 #t)))
153 ,phases)
154 phases)))
155 ((#:strip-binaries? _)
156 ;; Disable stripping as this can break binaries, with object files
157 ;; of libgcc.a showing up as having an unknown architecture. See
158 ;; <http://lists.fedoraproject.org/pipermail/arm/2010-August/000663.html>
159 ;; for instance.
160 #f))))
161 (inputs
162 `(("patch/cross-env-vars"
163 ,(search-patch "gcc-cross-environment-variables.patch"))
164
165 ("binutils-cross" ,xbinutils)
166
167 ;; Call it differently so that the builder can check whether the "libc"
168 ;; input is #f.
169 ("libc-native" ,@(assoc-ref %final-inputs "libc"))
170
171 ;; Remaining inputs.
172 ,@(let ((inputs (append (package-inputs gcc-4.7)
173 (alist-delete "libc" %final-inputs))))
174 (if libc
175 `(("libc" ,libc)
176 ,@inputs)
177 inputs))))))
178
179(define* (cross-libc target
180 #:optional
181 (xgcc (cross-gcc target))
182 (xbinutils (cross-binutils target)))
183 "Return a libc cross-built for TARGET, a GNU triplet. Use XGCC and
184XBINUTILS and the cross tool chain."
185 (define xlinux-headers
186 (package (inherit linux-libre-headers)
187 (name (string-append (package-name linux-libre-headers)
188 "-cross-" target))
189 (arguments
190 (substitute-keyword-arguments (package-arguments linux-libre-headers)
191 ((#:phases phases)
192 `(alist-replace
193 'build
194 (lambda _
195 (setenv "ARCH" ,(system->linux-architecture target))
196 (format #t "`ARCH' set to `~a' (cross compiling)~%" (getenv "ARCH"))
197
198 (and (zero? (system* "make" "defconfig"))
199 (zero? (system* "make" "mrproper" "headers_check"))))
200 ,phases))))
201 (inputs `(("cross-gcc" ,xgcc)
202 ("cross-binutils" ,xbinutils)
203 ,@(package-inputs linux-libre-headers)))))
204
205 (package (inherit glibc)
206 (name (string-append "glibc-cross-" target))
207 (arguments
208 (substitute-keyword-arguments
209 `(#:strip-binaries? #f ; disable stripping (see above)
210 ,@(package-arguments glibc))
211 ((#:configure-flags flags)
212 `(cons ,(string-append "--host=" target)
213 ,flags))
214 ((#:phases phases)
215 `(alist-cons-before
216 'configure 'set-cross-linux-headers-path
217 (lambda* (#:key inputs #:allow-other-keys)
218 (let ((linux (assoc-ref inputs "cross-linux-headers")))
219 (setenv "CROSS_CPATH"
220 (string-append linux "/include"))
221 #t))
222 ,phases))))
223 (propagated-inputs `(("cross-linux-headers" ,xlinux-headers)))
224 (inputs `(("cross-gcc" ,xgcc)
225 ("cross-binutils" ,xbinutils)
226 ,@(package-inputs glibc)))))
227
228\f
229;;;
230;;; Concrete cross toolchains.
231;;;
232
233(define-public xgcc-mips64el
234 (let ((triplet "mips64el-linux-gnu"))
235 (cross-gcc triplet
236 (cross-binutils triplet)
237 (cross-libc triplet))))
238
239;; (define-public xgcc-armel
240;; (let ((triplet "armel-linux-gnueabi"))
241;; (cross-gcc triplet
242;; (cross-binutils triplet)
243;; (cross-libc triplet))))