guix/gnu/packages/cross-base.scm

596 lines
26 KiB
Scheme
Raw Normal View History

;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014, 2015, 2018 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2016, 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2016 Manolis Fragkiskos Ragkousis <manolis837@gmail.com>
;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2019, 2020 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2019 Carl Dong <contact@carldong.me>
;;; Copyright © 2020 Mathieu Othacehe <m.othacehe@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu packages cross-base)
#:use-module (gnu packages)
#:use-module (gnu packages gcc)
#:use-module (gnu packages base)
#:use-module (gnu packages linux)
#:use-module (gnu packages hurd)
#:use-module (gnu packages mingw)
#:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix utils)
#:use-module (guix build-system gnu)
#:use-module (guix build-system trivial)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
#:use-module (ice-9 regex)
#:export (cross-binutils
cross-libc
cross-gcc
cross-newlib?
cross-kernel-headers))
(define-syntax %xgcc
;; GCC package used as the basis for cross-compilation. It doesn't have to
;; be 'gcc' and can be a specific variant such as 'gcc-4.8'.
;;
;; Note: This is a macro so that we do not refer to 'gcc' from the top
;; level, which would lead to circular-dependency issues.
(identifier-syntax gcc))
(define %gcc-include-paths
;; Environment variables for header search paths.
;; Note: See <http://bugs.gnu.org/22186> for why not 'CPATH'.
'("C_INCLUDE_PATH"
"CPLUS_INCLUDE_PATH"
"OBJC_INCLUDE_PATH"
"OBJCPLUS_INCLUDE_PATH"))
(define %gcc-cross-include-paths
;; Search path for target headers when cross-compiling.
(map (cut string-append "CROSS_" <>) %gcc-include-paths))
(define (cross p target)
(package (inherit p)
(name (string-append (package-name p) "-cross-" target))
(arguments
(substitute-keyword-arguments (package-arguments p)
((#:configure-flags flags)
`(cons ,(string-append "--target=" target)
,flags))))))
(define* (cross-binutils target #:optional (binutils binutils))
"Return a cross-Binutils for TARGET using BINUTILS."
(let ((binutils (package (inherit binutils)
(arguments
(substitute-keyword-arguments (package-arguments
binutils)
((#:configure-flags flags)
;; Build with `--with-sysroot' so that ld honors
;; DT_RUNPATH entries when searching for a needed
;; library. This works because as a side effect
;; `genscripts.sh' sets `USE_LIBPATH=yes', which tells
;; elf32.em to use DT_RUNPATH in its search list.
;; See <http://sourceware.org/ml/binutils/2013-05/msg00312.html>.
;;
;; In theory choosing / as the sysroot could lead ld
;; to pick up native libs instead of target ones. In
;; practice the RUNPATH of target libs only refers to
;; target libs, not native libs, so this is safe.
`(cons "--with-sysroot=/" ,flags)))))))
;; For Xtensa, apply Qualcomm's patch.
(cross (cond ((string-prefix? "xtensa-" target)
(package-with-patches binutils
(search-patches
"ath9k-htc-firmware-binutils.patch")))
((target-mingw? target)
(package-with-extra-patches
binutils
(search-patches "binutils-mingw-w64-timestamp.patch"
"binutils-mingw-w64-deterministic.patch")))
(else binutils))
target)))
(define (cross-gcc-arguments target xgcc libc)
"Return build system arguments for a cross-gcc for TARGET, using XGCC as the
base compiler and using LIBC (which may be either a libc package or #f.)"
;; Set the current target system so that 'glibc-dynamic-linker' returns the
;; right name.
(parameterize ((%current-target-system target))
;; Disable stripping as this can break binaries, with object files of
;; libgcc.a showing up as having an unknown architecture. See
;; <http://lists.fedoraproject.org/pipermail/arm/2010-August/000663.html>
;; for instance.
(let ((args `(#:strip-binaries? #f
,@(package-arguments xgcc))))
(substitute-keyword-arguments args
((#:configure-flags flags)
`(append (list ,(string-append "--target=" target)
,@(if libc
`( ;; Disable libcilkrts because it is not
;; ported to GNU/Hurd.
"--disable-libcilkrts"
;; When building a cross compiler, --with-sysroot is
;; implicitly set to "$gcc_tooldir/sys-root". This does
;; not work for us, because --with-native-system-header-dir
;; is searched for relative to this location. Thus, we set
;; it to "/" so GCC is able to find the target libc headers.
;; This is safe because in practice GCC uses CROSS_CPATH
;; & co to separate target and host libraries.
"--with-sysroot=/")
`( ;; Disable features not needed at this stage.
"--disable-shared" "--enable-static"
"--enable-languages=c,c++"
;; libstdc++ cannot be built at this stage
;; ("Link tests are not allowed after
;; GCC_NO_EXECUTABLES.").
"--disable-libstdc++-v3"
"--disable-threads" ;libgcc, would need libc
"--disable-libatomic"
"--disable-libmudflap"
"--disable-libgomp"
"--disable-libmpx"
"--disable-libssp"
"--disable-libquadmath"
"--disable-decimal-float" ;would need libc
"--disable-libcilkrts"
,@(if (string-prefix? "powerpc64le-" target)
;; On POWER9 (little endian) glibc needs
;; the 128-bit long double type.
'("--with-long-double-128")
'())
;; When target is any OS other than 'none' these
;; libraries will fail if there is no libc
;; present. See
;; <https://lists.gnu.org/archive/html/guix-devel/2016-02/msg01311.html>
"--disable-libitm"
"--disable-libvtv"
"--disable-libsanitizer"
))
;; Install cross-built libraries such as libgcc_s.so in
;; the "lib" output.
,@(if libc
`((string-append "--with-toolexeclibdir="
(assoc-ref %outputs "lib")
"/" ,target "/lib"))
'())
;; For a newlib (non-glibc) target
,@(if (cross-newlib? target)
'("--with-newlib")
'()))
,(if libc
flags
`(remove (cut string-match "--enable-languages.*" <>)
,flags))))
((#:make-flags flags)
(if libc
`(let ((libc (assoc-ref %build-inputs "libc")))
;; FLAGS_FOR_TARGET are needed for the target libraries to receive
;; the -Bxxx for the startfiles.
(cons (string-append "FLAGS_FOR_TARGET=-B" libc "/lib")
,flags))
flags))
((#:phases phases)
`(cross-gcc-build-phases ,target ,phases))))))
(define (cross-gcc-patches xgcc target)
"Return GCC patches needed for XGCC and TARGET."
(cond ((string-prefix? "xtensa-" target)
;; Patch by Qualcomm needed to build the ath9k-htc firmware.
gnu: packages: Use 'search-patches' everywhere. * gnu/packages/abiword.scm: Use 'search-patches' for 'patches' field. * gnu/packages/acl.scm: Likewise. * gnu/packages/admin.scm: Likewise. * gnu/packages/algebra.scm: Likewise. * gnu/packages/animation.scm: Likewise. * gnu/packages/apr.scm: Likewise. * gnu/packages/audacity.scm: Likewise. * gnu/packages/audio.scm: Likewise. * gnu/packages/autotools.scm: Likewise. * gnu/packages/avahi.scm: Likewise. * gnu/packages/backup.scm: Likewise. * gnu/packages/base.scm: Likewise. * gnu/packages/bash.scm: Likewise. * gnu/packages/bioinformatics.scm: Likewise. * gnu/packages/cdrom.scm: Likewise. * gnu/packages/ci.scm: Likewise. * gnu/packages/cmake.scm: Likewise. * gnu/packages/cpio.scm: Likewise. * gnu/packages/cross-base.scm: Likewise. * gnu/packages/dico.scm: Likewise. * gnu/packages/doxygen.scm: Likewise. * gnu/packages/ebook.scm: Likewise. * gnu/packages/elf.scm: Likewise. * gnu/packages/emacs.scm: Likewise. * gnu/packages/engineering.scm: Likewise. * gnu/packages/firmware.scm: Likewise. * gnu/packages/flashing-tools.scm: Likewise. * gnu/packages/fltk.scm: Likewise. * gnu/packages/ftp.scm: Likewise. * gnu/packages/games.scm: Likewise. * gnu/packages/gawk.scm: Likewise. * gnu/packages/gcc.scm: Likewise. * gnu/packages/gd.scm: Likewise. * gnu/packages/ghostscript.scm: Likewise. * gnu/packages/glib.scm: Likewise. * gnu/packages/gnome.scm: Likewise. * gnu/packages/gnucash.scm: Likewise. * gnu/packages/gnunet.scm: Likewise. * gnu/packages/gnupg.scm: Likewise. * gnu/packages/gnuzilla.scm: Likewise. * gnu/packages/graphics.scm: Likewise. * gnu/packages/grub.scm: Likewise. * gnu/packages/gtk.scm: Likewise. * gnu/packages/guile.scm: Likewise. * gnu/packages/icu4c.scm: Likewise. * gnu/packages/idutils.scm: Likewise. * gnu/packages/image.scm: Likewise. * gnu/packages/imagemagick.scm: Likewise. * gnu/packages/irc.scm: Likewise. * gnu/packages/ldc.scm: Likewise. * gnu/packages/libcanberra.scm: Likewise. * gnu/packages/libevent.scm: Likewise. * gnu/packages/libreoffice.scm: Likewise. * gnu/packages/libunwind.scm: Likewise. * gnu/packages/libusb.scm: Likewise. * gnu/packages/linux.scm: Likewise. * gnu/packages/lirc.scm: Likewise. * gnu/packages/llvm.scm: Likewise. * gnu/packages/lsh.scm: Likewise. * gnu/packages/lua.scm: Likewise. * gnu/packages/lxqt.scm: Likewise. * gnu/packages/mail.scm: Likewise. * gnu/packages/maths.scm: Likewise. * gnu/packages/mcrypt.scm: Likewise. * gnu/packages/messaging.scm: Likewise. * gnu/packages/mit-krb5.scm: Likewise. * gnu/packages/mp3.scm: Likewise. * gnu/packages/multiprecision.scm: Likewise. * gnu/packages/music.scm: Likewise. * gnu/packages/ninja.scm: Likewise. * gnu/packages/nvi.scm: Likewise. * gnu/packages/ocaml.scm: Likewise. * gnu/packages/orpheus.scm: Likewise. * gnu/packages/ots.scm: Likewise. * gnu/packages/parallel.scm: Likewise. * gnu/packages/patchutils.scm: Likewise. * gnu/packages/pcre.scm: Likewise. * gnu/packages/pdf.scm: Likewise. * gnu/packages/perl.scm: Likewise. * gnu/packages/plotutils.scm: Likewise. * gnu/packages/polkit.scm: Likewise. * gnu/packages/pulseaudio.scm: Likewise. * gnu/packages/python.scm: Likewise. * gnu/packages/qemu.scm: Likewise. * gnu/packages/qt.scm: Likewise. * gnu/packages/ratpoison.scm: Likewise. * gnu/packages/rdf.scm: Likewise. * gnu/packages/readline.scm: Likewise. * gnu/packages/rush.scm: Likewise. * gnu/packages/scheme.scm: Likewise. * gnu/packages/screen.scm: Likewise. * gnu/packages/sdl.scm: Likewise. * gnu/packages/slim.scm: Likewise. * gnu/packages/ssh.scm: Likewise. * gnu/packages/tcl.scm: Likewise. * gnu/packages/tcsh.scm: Likewise. * gnu/packages/texinfo.scm: Likewise. * gnu/packages/tls.scm: Likewise. * gnu/packages/tor.scm: Likewise. * gnu/packages/tv.scm: Likewise. * gnu/packages/valgrind.scm: Likewise. * gnu/packages/version-control.scm: Likewise. * gnu/packages/video.scm: Likewise. * gnu/packages/vpn.scm: Likewise. * gnu/packages/vtk.scm: Likewise. * gnu/packages/w3m.scm: Likewise. * gnu/packages/web.scm: Likewise. * gnu/packages/wicd.scm: Likewise. * gnu/packages/wm.scm: Likewise. * gnu/packages/xdisorg.scm: Likewise. * gnu/packages/xfce.scm: Likewise. * gnu/packages/xiph.scm: Likewise. * gnu/packages/xml.scm: Likewise. * gnu/packages/xorg.scm: Likewise. * gnu/packages/zip.scm: Likewise.
2016-04-08 08:18:13 -04:00
(search-patches "ath9k-htc-firmware-gcc.patch"))
((target-mingw? target)
(append (search-patches "gcc-4.9.3-mingw-gthr-default.patch")
(if (version>=? (package-version xgcc) "7.0")
(search-patches "gcc-7-cross-mingw.patch")
'())))
(else '())))
(define (cross-gcc-snippet target)
"Return GCC snippet needed for TARGET."
`(begin
,@(if (target-mingw? target)
'((copy-recursively "libstdc++-v3/config/os/mingw32-w64"
"libstdc++-v3/config/os/newlib"))
'())
;; TOOLDIR_BASE_PREFIX is erroneous when using a separate "lib"
;; output. Specify it correctly, otherwise GCC won't find its shared
;; libraries installed in the "lib" output. See:
;; https://lists.gnu.org/archive/html/bug-guix/2020-03/msg00196.html.
(substitute* "gcc/Makefile.in"
(("-DTOOLDIR_BASE_PREFIX=[^ ]*")
"-DTOOLDIR_BASE_PREFIX=\\\"../../../../\\\""))
#t))
(define* (cross-gcc target
#:key
(xgcc %xgcc)
(xbinutils (cross-binutils target))
(libc #f))
"Return a cross-compiler for TARGET, where TARGET is a GNU triplet. Use
XGCC as the base compiler. Use XBINUTILS as the associated cross-Binutils.
If LIBC is false, then build a GCC that does not target a libc; otherwise,
target that libc."
(package (inherit xgcc)
(name (string-append "gcc-cross-"
(if libc "" "sans-libc-")
target))
(source
(origin
(inherit (package-source xgcc))
(patches
(append
(origin-patches (package-source xgcc))
(append (cond
((version>=? (package-version xgcc) "8.0")
(search-patches "gcc-8-cross-environment-variables.patch"))
((version>=? (package-version xgcc) "6.0")
(search-patches "gcc-7-cross-toolexeclibdir.patch"
"gcc-6-cross-environment-variables.patch"))
(else
(search-patches "gcc-cross-environment-variables.patch")))
(cross-gcc-patches xgcc target))))
(modules '((guix build utils)))
(snippet
(cross-gcc-snippet target))))
(outputs '("out" "lib"))
(arguments
`(#:implicit-inputs? #f
#:imported-modules ((gnu build cross-toolchain)
,@%gnu-build-system-modules)
#:modules ((guix build gnu-build-system)
(guix build utils)
(gnu build cross-toolchain)
(srfi srfi-1)
(srfi srfi-26)
(ice-9 regex))
,@(cross-gcc-arguments target xgcc libc)))
(native-inputs
`(("ld-wrapper-cross" ,(make-ld-wrapper
(string-append "ld-wrapper-" target)
#:target (const target)
#:binutils xbinutils))
("binutils-cross" ,xbinutils)
,@(let ((inputs (append (package-inputs xgcc)
(fold alist-delete (%final-inputs)
'("libc" "libc:static"))
;; Call it differently so that the builder can
;; check whether the "libc" input is #f.
`(("libc-native"
,@(assoc-ref (%final-inputs) "libc"))
("libc-native:static"
,@(assoc-ref (%final-inputs)
"libc:static"))))))
(cond
((target-mingw? target)
(if libc
`(,@inputs
("libc" ,libc))
`(,@inputs
("mingw-source" ,(package-source mingw-w64)))))
(libc
`(,@inputs
("libc" ,libc)
("libc:static" ,libc "static")
("xkernel-headers" ;the target headers
,@(assoc-ref (package-propagated-inputs libc)
"kernel-headers"))))
(else inputs)))))
(inputs '())
;; Only search target inputs, not host inputs.
(search-paths (cons (search-path-specification
(variable "CROSS_LIBRARY_PATH")
(files '("lib" "lib64")))
(map (lambda (variable)
(search-path-specification
(variable variable)
;; Add 'include/c++' here so that <cstdlib>'s
;; "#include_next <stdlib.h>" finds GCC's
;; <stdlib.h>, not libc's.
(files (match variable
("CROSS_CPLUS_INCLUDE_PATH"
'("include/c++" "include"))
(_
'("include"))))))
%gcc-cross-include-paths)))
(native-search-paths '())))
(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-headers)
(name (string-append (package-name linux-headers)
"-cross-" target))
(arguments
build-system: Introduce "bags" as an intermediate representation. * guix/build-system.scm (<build-system>)[build, cross-build]: Remove. [lower]: New field. (<bag>): New record type. (make-bag): New procedure. * guix/packages.scm (bag-transitive-inputs, bag-transitive-build-inputs, bag-transitive-host-inputs, bag-transitive-target-inputs, package->bag): New procedures. (package-derivation): Use it; use the bag, apply its build procedure, etc. (package-cross-derivation): Likewise. * gnu/packages/bootstrap.scm (raw-build, make-raw-bag): New procedure. (%bootstrap-guile): Use them. * guix/build-system/trivial.scm (lower): New procedure. (trivial-build, trivial-cross-build): Remove 'source' parameter. Pass INPUTS as is. (trivial-build-system): Adjust accordingly. * guix/build-system/gnu.scm (%store, inputs-search-paths, standard-search-paths, expand-inputs, standard-inputs): Remove. (gnu-lower): New procedure. (gnu-build): Remove 'source' and #:implicit-inputs? parameters. Remove 'implicit-inputs' and 'implicit-search-paths' variables. Get the source from INPUT-DRVS. (gnu-cross-build): Likewise. (standard-cross-packages): Remove call to 'standard-packages'. (standard-cross-inputs, standard-cross-search-paths): Remove. (gnu-build-system): Remove 'build' and 'cross-build'; add 'lower'. * guix/build-system/cmake.scm (lower): New procedure. (cmake-build): Remove 'source' and #:cmake parameters. Use INPUTS and SEARCH-PATHS as is. Get the source from INPUTS. * guix/build-system/perl.scm: Likewise. * guix/build-system/python.scm: Likewise. * guix/build-system/ruby.scm: Likewise. * gnu/packages/cross-base.scm (cross-gcc): Change "cross-linux-headers" to "linux-headers". (cross-libc)[xlinux-headers]: Pass #:implicit-cross-inputs? #f. Likewise. In 'propagated-inputs', change "cross-linux-headers" to "linux-headers". * guix/git-download.scm (git-fetch): Use 'standard-packages' instead of 'standard-inputs'. * tests/builders.scm ("gnu-build-system"): Remove use of 'build-system-builder'. ("gnu-build"): Remove 'source' and #:implicit-inputs? arguments to 'gnu-build'. * tests/packages.scm ("search paths"): Adjust to new build system API. ("package-cross-derivation, no cross builder"): Likewise. * doc/guix.texi (Build Systems): Add paragraph on bags.
2014-10-03 12:06:16 -04:00
(substitute-keyword-arguments
`(#:implicit-cross-inputs? #f
,@(package-arguments linux-headers))
((#:phases phases)
`(alist-replace
'build
(lambda _
(setenv "ARCH" ,(system->linux-architecture target))
(format #t "`ARCH' set to `~a' (cross compiling)~%" (getenv "ARCH"))
(invoke "make" ,(system->defconfig target))
(invoke "make" "mrproper" "headers_check"))
,phases))))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
,@(package-native-inputs linux-headers)))))
(define xgnumach-headers
(package (inherit gnumach-headers)
(name (string-append (package-name gnumach-headers)
"-cross-" target))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
,@(package-native-inputs gnumach-headers)))))
(define xmig
(package (inherit mig)
(name (string-append "mig-cross"))
(arguments
`(#:modules ((guix build gnu-build-system)
(guix build utils)
(srfi srfi-26))
#: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))
#:tests? #f))
(propagated-inputs `(("cross-gnumach-headers" ,xgnumach-headers)))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
,@(package-native-inputs mig)))))
(define xhurd-headers
(package (inherit hurd-headers)
(name (string-append (package-name hurd-headers)
"-cross-" target))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
("cross-mig" ,xmig)
,@(alist-delete "mig"(package-native-inputs hurd-headers))))))
(define xglibc/hurd-headers
(package (inherit glibc/hurd-headers)
(name (string-append (package-name glibc/hurd-headers)
"-cross-" target))
(arguments
(substitute-keyword-arguments
`(#:modules ((guix build gnu-build-system)
(guix build utils)
(srfi srfi-26))
,@(package-arguments glibc/hurd-headers))
((#:phases 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)))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
("cross-mig" ,xmig)
,@(alist-delete "mig"(package-native-inputs glibc/hurd-headers))))))
(define xhurd-minimal
(package (inherit hurd-minimal)
(name (string-append (package-name hurd-minimal)
"-cross-" target))
(arguments
(substitute-keyword-arguments
`(#:modules ((guix build gnu-build-system)
(guix build utils)
(srfi srfi-26))
,@(package-arguments hurd-minimal))
((#:phases 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)))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
("cross-mig" ,xmig)
,@(alist-delete "mig"(package-native-inputs hurd-minimal))))))
(define xhurd-core-headers
(package (inherit hurd-core-headers)
(name (string-append (package-name hurd-core-headers)
"-cross-" target))
(inputs `(("gnumach-headers" ,xgnumach-headers)
("hurd-headers" ,xhurd-headers)
("hurd-minimal" ,xhurd-minimal)))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
("cross-mig" ,xmig)
,@(package-native-inputs hurd-core-headers)))))
(match target
((or "i586-pc-gnu" "i586-gnu") xhurd-core-headers)
(_ xlinux-headers)))
(define* (cross-libc target
#:optional
(libc glibc)
(xgcc (cross-gcc target))
(xbinutils (cross-binutils target))
(xheaders (cross-kernel-headers 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
#:xgcc xgcc
#:xbinutils xbinutils)
(package
(inherit libc)
(name (string-append "glibc-cross-" target))
(arguments
(substitute-keyword-arguments
`( ;; Disable stripping (see above.)
#:strip-binaries? #f
;; This package is used as a target input, but it should not have
;; the usual cross-compilation inputs since that would include
;; itself.
#:implicit-cross-inputs? #f
;; We need SRFI 26.
#:modules ((guix build gnu-build-system)
(guix build utils)
(srfi srfi-26))
,@(package-arguments libc))
((#:configure-flags flags)
`(cons ,(string-append "--host=" target)
,(if (hurd-triplet? target)
`(cons "--disable-werror" ,flags)
flags)))
((#:phases phases)
`(modify-phases ,phases
(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)))
,@(if (hurd-triplet? target)
'((add-after 'install 'augment-libc.so
(lambda* (#:key outputs #:allow-other-keys)
(let* ((out (assoc-ref outputs "out")))
(substitute* (string-append out "/lib/libc.so")
(("/[^ ]+/lib/libc.so.0.3")
(string-append out "/lib/libc.so.0.3"
" libmachuser.so libhurduser.so"))))
#t))
;; TODO: move to glibc in the next rebuild cycle
(add-after 'unpack 'patch-libc/hurd
(lambda* (#:key inputs #:allow-other-keys)
(for-each
(lambda (name)
(let ((patch (assoc-ref inputs name)))
(invoke "patch" "-p1" "--force" "-i" patch)))
'("hurd-mach-print.patch"
"hurd-gettyent.patch")))))
'())))))
;; Shadow the native "kernel-headers" because glibc's recipe expects the
;; "kernel-headers" input to point to the right thing.
(propagated-inputs `(("kernel-headers" ,xheaders)))
;; FIXME: 'static-bash' should really be an input, not a native input, but
;; to do that will require building an intermediate cross libc.
(inputs (if (hurd-triplet? target)
`(;; TODO: move to glibc in the next rebuild cycle
("hurd-mach-print.patch"
,(search-patch "glibc-hurd-mach-print.patch"))
("hurd-gettyent.patch"
,(search-patch "glibc-hurd-gettyent.patch")))
'()))
(native-inputs `(("cross-gcc" ,xgcc)
("cross-binutils" ,xbinutils)
,@(if (hurd-triplet? target)
`(("cross-mig"
,@(assoc-ref (package-native-inputs xheaders)
"cross-mig")))
'())
,@(package-inputs libc) ;FIXME: static-bash
,@(package-native-inputs libc))))))
(define* (native-libc target
#:optional
(libc glibc)
#:key
xgcc
xbinutils)
(if (target-mingw? target)
(let ((machine (substring target 0 (string-index target #\-))))
(make-mingw-w64 machine
#:xgcc xgcc
#:xbinutils xbinutils))
libc))
(define* (cross-newlib? target
#:optional
(libc glibc))
(not (eq? (native-libc target libc) libc)))
;;; Concrete cross tool chains are instantiated like this:
;;
;; (define-public xgcc-armhf
;; (let ((triplet "arm-linux-gnueabihf"))
;; (cross-gcc triplet
;; #:xbinutils (cross-binutils triplet)
;; #:libc (cross-libc triplet))))
;;
;;; We don't do that here because we'd be referring to bindings from (gnu
;;; packages gcc) from the top level, which doesn't play well with circular
;;; dependencies among modules.