;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
-;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2014, 2015, 2018 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2016 Manolis Fragkiskos Ragkousis <manolis837@gmail.com>
+;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2019 Carl Dong <contact@carldong.me>
;;;
;;; This file is part of GNU Guix.
;;;
#:export (cross-binutils
cross-libc
cross-gcc
- cross-newlib?))
+ cross-newlib?
+ cross-kernel-headers))
(define-syntax %xgcc
;; GCC package used as the basis for cross-compilation. It doesn't have to
(define (cross-gcc-snippet target)
"Return GCC snippet needed for TARGET."
(cond ((target-mingw? target)
- '(copy-recursively "libstdc++-v3/config/os/mingw32-w64"
- "libstdc++-v3/config/os/newlib"))
+ '(begin
+ (copy-recursively "libstdc++-v3/config/os/mingw32-w64"
+ "libstdc++-v3/config/os/newlib")
+ #t))
(else #f)))
(define* (cross-gcc target
(patches
(append
(origin-patches (package-source xgcc))
- (cons (search-patch "gcc-cross-environment-variables.patch")
+ (cons (cond
+ ((version>=? (package-version xgcc) "8.0") (search-patch "gcc-8-cross-environment-variables.patch"))
+ ((version>=? (package-version xgcc) "6.0") (search-patch "gcc-6-cross-environment-variables.patch"))
+ (else (search-patch "gcc-cross-environment-variables.patch")))
(cross-gcc-patches target))))
(modules '((guix build utils)))
(snippet
(cond
((target-mingw? target)
(if libc
- `(("libc" ,mingw-w64)
+ `(("libc" ,libc)
,@inputs)
`(("mingw-source" ,(package-source mingw-w64))
,@inputs)))
(define* (cross-kernel-headers target
#:optional
+ (linux-headers linux-libre-headers)
(xgcc (cross-gcc target))
(xbinutils (cross-binutils target)))
"Return headers depending on TARGET."
(define xlinux-headers
- (package (inherit linux-libre-headers)
- (name (string-append (package-name linux-libre-headers)
+ (package (inherit linux-headers)
+ (name (string-append (package-name linux-headers)
"-cross-" target))
(arguments
(substitute-keyword-arguments
`(#:implicit-cross-inputs? #f
- ,@(package-arguments linux-libre-headers))
+ ,@(package-arguments linux-headers))
((#:phases phases)
`(alist-replace
'build
(setenv "ARCH" ,(system->linux-architecture target))
(format #t "`ARCH' set to `~a' (cross compiling)~%" (getenv "ARCH"))
- (and (zero? (system* "make" ,(system->defconfig target)))
- (zero? (system* "make" "mrproper" "headers_check"))))
+ (invoke "make" ,(system->defconfig target))
+ (invoke "make" "mrproper" "headers_check"))
,phases))))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
- ,@(package-native-inputs linux-libre-headers)))))
+ ,@(package-native-inputs linux-headers)))))
(define xgnumach-headers
(package (inherit gnumach-headers)
`(#:modules ((guix build gnu-build-system)
(guix build utils)
(srfi srfi-26))
- #:phases (alist-cons-before
- 'configure 'set-cross-headers-path
- (lambda* (#:key inputs #:allow-other-keys)
- (let* ((mach (assoc-ref inputs "cross-gnumach-headers"))
- (cpath (string-append mach "/include")))
- (for-each (cut setenv <> cpath)
- ',%gcc-cross-include-paths)))
- %standard-phases)
+ #:phases (modify-phases %standard-phases
+ (add-before 'configure 'set-cross-headers-path
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let* ((mach (assoc-ref inputs "cross-gnumach-headers"))
+ (cpath (string-append mach "/include")))
+ (for-each (cut setenv <> cpath)
+ ',%gcc-cross-include-paths)
+ #t))))
#:configure-flags (list ,(string-append "--target=" target))
,@(package-arguments mig)))
(srfi srfi-26))
,@(package-arguments glibc/hurd-headers))
((#:phases phases)
- `(alist-cons-before
- 'pre-configure 'set-cross-headers-path
- (lambda* (#:key inputs #:allow-other-keys)
- (let* ((mach (assoc-ref inputs "gnumach-headers"))
- (hurd (assoc-ref inputs "hurd-headers"))
- (cpath (string-append mach "/include:"
- hurd "/include")))
- (for-each (cut setenv <> cpath)
- ',%gcc-cross-include-paths)))
- ,phases))))
+ `(modify-phases ,phases
+ (add-after 'unpack 'set-cross-headers-path
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let* ((mach (assoc-ref inputs "gnumach-headers"))
+ (hurd (assoc-ref inputs "hurd-headers"))
+ (cpath (string-append mach "/include:"
+ hurd "/include")))
+ (for-each (cut setenv <> cpath)
+ ',%gcc-cross-include-paths)
+ #t)))))))
(propagated-inputs `(("gnumach-headers" ,xgnumach-headers)
("hurd-headers" ,xhurd-headers)))
(srfi srfi-26))
,@(package-arguments hurd-minimal))
((#:phases phases)
- `(alist-cons-before
- 'configure 'set-cross-headers-path
- (lambda* (#:key inputs #:allow-other-keys)
- (let* ((glibc-headers (assoc-ref inputs "cross-glibc-hurd-headers"))
- (cpath (string-append glibc-headers "/include")))
- (for-each (cut setenv <> cpath)
- ',%gcc-cross-include-paths)))
- ,phases))))
+ `(modify-phases ,phases
+ (add-before 'configure 'set-cross-headers-path
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let* ((glibc-headers (assoc-ref inputs "cross-glibc-hurd-headers"))
+ (cpath (string-append glibc-headers "/include")))
+ (for-each (cut setenv <> cpath)
+ ',%gcc-cross-include-paths)
+ #t)))))))
(inputs `(("cross-glibc-hurd-headers" ,xglibc/hurd-headers)))
(define* (cross-libc target
#:optional
+ (libc glibc)
(xgcc (cross-gcc target))
(xbinutils (cross-binutils target))
(xheaders (cross-kernel-headers target)))
- "Return a libc cross-built for TARGET, a GNU triplet. Use XGCC and
-XBINUTILS and the cross tool chain."
- (define (cross-libc-for-target target)
- "Return libc depending on TARGET."
- (match target
- ((or "i586-pc-gnu" "i586-gnu") glibc/hurd)
- (_ glibc/linux)))
-
- ;; Use (cross-libc-for-target ...) to determine the correct libc to use.
-
- (if (cross-newlib? target)
- (native-libc target)
- (let ((libc (cross-libc-for-target target)))
+ "Return LIBC cross-built for TARGET, a GNU triplet. Use XGCC and XBINUTILS
+and the cross tool chain."
+ (if (cross-newlib? target libc)
+ (native-libc target libc)
+ (let ((libc libc))
(package (inherit libc)
(name (string-append "glibc-cross-" target))
(arguments
,@(package-arguments libc))
((#:configure-flags flags)
`(cons ,(string-append "--host=" target)
- ,flags))
+ ,(if (hurd-triplet? target)
+ `(cons "--disable-werror" ,flags)
+ flags)))
((#:phases phases)
- `(alist-cons-before
- 'configure 'set-cross-kernel-headers-path
- (lambda* (#:key inputs #:allow-other-keys)
- (let* ((kernel (assoc-ref inputs "kernel-headers"))
- (cpath (string-append kernel "/include")))
- (for-each (cut setenv <> cpath)
- ',%gcc-cross-include-paths)
- (setenv "CROSS_LIBRARY_PATH"
- (string-append kernel "/lib")) ;for Hurd's libihash
- #t))
- ,phases))))
+ `(modify-phases ,phases
+ ;; XXX: The hack below allows us to make sure the
+ ;; 'apply-hurd-patch' phase gets added in the first
+ ;; cross-libc, but does *not* get added twice subsequently
+ ;; when cross-building another libc.
+ ,@(if (and (hurd-triplet? target)
+ (not (hurd-target?)))
+ `((add-after 'unpack 'apply-hurd-patch
+ (lambda* (#:key inputs native-inputs
+ #:allow-other-keys)
+ ;; TODO: Move this to 'patches' field.
+ (let ((patch (or (assoc-ref native-inputs
+ "hurd-magic-pid-patch")
+ (assoc-ref inputs
+ "hurd-magic-pid-patch"))))
+ (invoke "patch" "-p1" "--force" "--input"
+ patch)))))
+ '())
+ (add-before 'configure 'set-cross-kernel-headers-path
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let* ((kernel (assoc-ref inputs "kernel-headers"))
+ (cpath (string-append kernel "/include")))
+ (for-each (cut setenv <> cpath)
+ ',%gcc-cross-include-paths)
+ (setenv "CROSS_LIBRARY_PATH"
+ (string-append kernel "/lib")) ; for Hurd's libihash
+ #t)))))))
;; Shadow the native "kernel-headers" because glibc's recipe expects the
;; "kernel-headers" input to point to the right thing.
,@(if (hurd-triplet? target)
`(("cross-mig"
,@(assoc-ref (package-native-inputs xheaders)
- "cross-mig")))
+ "cross-mig"))
+ ("hurd-magic-pid-patch"
+ ,(search-patch "glibc-hurd-magic-pid.patch")))
'())
,@(package-inputs libc) ;FIXME: static-bash
,@(package-native-inputs libc)))))))
-(define (native-libc target)
+(define* (native-libc target
+ #:optional
+ (libc glibc))
(if (target-mingw? target)
- mingw-w64
- glibc))
-
-(define (cross-newlib? target)
- (not (eq? (native-libc target) glibc)))
+ (let ((machine (substring target 0 (string-index target #\-))))
+ (make-mingw-w64 machine))
+ libc))
+
+(define* (cross-newlib? target
+ #:optional
+ (libc glibc))
+ (not (eq? (native-libc target libc) libc)))
\f
;;; Concrete cross tool chains are instantiated like this: