--- guix.old/gnu/packages/cross-base.scm 2015-02-01 13:52:32.657316282 +0100 +++ guix/gnu/packages/cross-base.scm 2015-02-01 19:42:12.563316282 +0100 @@ -33,6 +33,7 @@ #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:export (cross-binutils + cross-ld-wrapper cross-libc cross-gcc)) @@ -67,6 +68,46 @@ `(cons "--with-sysroot=/" ,flags))))))) (cross binutils target))) +(define (cross-ld-wrapper target binutils) + "Return a linker wrapper for BINUTILS of TARGET." + (package (inherit ld-wrapper) + (name (string-append (package-name ld-wrapper) "-cross-" target)) + (inputs '()) + (native-inputs `(("binutils" ,binutils) + ,@(fold alist-delete (package-inputs ld-wrapper) + '("binutils")))) + (arguments + `(#:modules ((guix build utils)) + #:builder (begin + (use-modules (guix build utils) + (system base compile)) + + (let* ((target ,target) + (out (assoc-ref %outputs "out")) + (bin (string-append out "/bin")) + (ld (string-append bin "/" target "-ld")) + (go (string-append bin "/" target "-ld.go"))) + + (setvbuf (current-output-port) _IOLBF) + (format #t "building ~s/bin/~s-ld wrapper in ~s~%" + (assoc-ref %build-inputs "binutils") + target out) + + (mkdir-p bin) + (copy-file (assoc-ref %build-inputs "wrapper") ld) + (substitute* ld + (("@GUILE@") + (string-append (assoc-ref %build-inputs "guile") + "/bin/guile")) + (("@BASH@") + (string-append (assoc-ref %build-inputs "bash") + "/bin/bash")) + (("@LD@") + (string-append (assoc-ref %build-inputs "binutils") + "/bin/" target "-ld"))) + (chmod ld #o555) + (compile-file ld #:output-file go))))))) + (define (cross-gcc-arguments target libc) "Return build system arguments for a cross-gcc for TARGET, using LIBC (which may be either a libc package or #f.)" @@ -112,17 +153,24 @@ `(alist-cons-after 'install 'make-cross-binutils-visible (lambda* (#:key outputs inputs #:allow-other-keys) - (let* ((out (assoc-ref outputs "out")) - (libexec (string-append out "/libexec/gcc/" - ,target)) - (binutils (string-append - (assoc-ref inputs "binutils-cross") - "/bin/" ,target "-"))) + (let* ((out (assoc-ref outputs "out")) + (libexec (string-append out "/libexec/gcc/" + ,target)) + (binutils (string-append + (assoc-ref inputs "binutils-cross") + "/bin/" ,target "-")) + (ld-wrapper (string-append + (assoc-ref inputs "ld-wrapper-cross") + "/bin/" ,target "-ld"))) (for-each (lambda (file) (symlink (string-append binutils file) (string-append libexec "/" file))) - '("as" "ld" "nm")) + '("as" "nm")) + ;; Use ld-wrapper instead of directly binutils ld. + (symlink ld-wrapper (string-append libexec "/ld")) + (symlink (string-append ld-wrapper ".go") + (string-append libexec "/ld.go")) #t)) ,phases))) (if libc @@ -207,7 +255,8 @@ ,@(cross-gcc-arguments target libc))) (native-inputs - `(("binutils-cross" ,xbinutils) + `(("ld-wrapper-cross" ,(cross-ld-wrapper target xbinutils)) + ("binutils-cross" ,xbinutils) ;; Call it differently so that the builder can check whether the "libc" ;; input is #f. --- guix.old/guix/build-system/gnu.scm 2015-01-31 11:06:42.067984113 +0100 +++ guix/guix/build-system/gnu.scm 2015-02-01 17:42:28.609316282 +0100 @@ -381,15 +381,18 @@ (lambda (target kind) "Return the list of name/package tuples to cross-build for TARGET. KIND is one of `host' or `target'." - (let* ((cross (resolve-interface '(gnu packages cross-base))) - (gcc (module-ref cross 'cross-gcc)) - (binutils (module-ref cross 'cross-binutils)) - (libc (module-ref cross 'cross-libc))) + (let* ((cross (resolve-interface '(gnu packages cross-base))) + (gcc (module-ref cross 'cross-gcc)) + (binutils (module-ref cross 'cross-binutils)) + (ld-wrapper (module-ref cross 'cross-ld-wrapper)) + (libc (module-ref cross 'cross-libc))) (case kind ((host) `(("cross-gcc" ,(gcc target (binutils target) (libc target))) + ("cross-ld-wrapper" ,(ld-wrapper target + (binutils target))) ("cross-binutils" ,(binutils target)) ,@(standard-packages))) ((target)