~ruther/guix-local

de1d41f9807dec9cc8a151af60e4949aa62b25d6 — Ludovic Courtès 12 years ago e7133c7
gnu: gcc: Allow cross-compilation of GCC itself.

* gnu/packages/gcc.scm (gcc-4.7): Define `CC_FOR_TARGET',
  `AR_FOR_TARGET', etc. when cross-compiling.
1 files changed, 127 insertions(+), 106 deletions(-)

M gnu/packages/gcc.scm
M gnu/packages/gcc.scm => gnu/packages/gcc.scm +127 -106
@@ 32,129 32,150 @@
  "ftp://gcc.gnu.org/pub/gcc/infrastructure/")

(define-public gcc-4.7
  (let ((stripped? #t))                         ; TODO: make this a parameter
    (package
     (name "gcc")
     (version "4.7.3")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/gcc/gcc-"
                                  version "/gcc-" version ".tar.bz2"))
              (sha256
               (base32
                "1hx9h64ivarlzi4hxvq42as5m9vlr5cyzaaq4gzj4i619zmkfz1g"))))
     (build-system gnu-build-system)
    (inputs `(("gmp" ,gmp)
              ("mpfr" ,mpfr)
              ("mpc" ,mpc)
              ("isl" ,isl)
              ("cloog" ,cloog)
              ("libelf" ,libelf)
              ("zlib" ,zlib)))
     (arguments
      `(#:out-of-source? #t
        #:strip-binaries? ,stripped?
        #:configure-flags
        `("--enable-plugin"
          "--enable-languages=c,c++"
          "--disable-multilib"
  (let* ((stripped? #t)                           ; TODO: make this a parameter
         (maybe-target-tools
          (lambda ()
            ;; Return the `_FOR_TARGET' variables that are needed when
            ;; cross-compiling GCC.
            (let ((target (%current-target-system)))
              (if target
                  (map (lambda (var tool)
                         (string-append (string-append var "_FOR_TARGET")
                                        "=" target "-" tool))
                       '("CC"  "CXX" "LD" "AR" "NM" "RANLIB" "STRIP")
                       '("gcc" "g++" "ld" "ar" "nm" "ranlib" "strip"))
                  '()))))
         (configure-flags
          (lambda ()
            ;; This is terrible.  Since we have two levels of quasiquotation,
            ;; we have to do this convoluted thing just so we can insert the
            ;; contents of (maybe-target-tools).
            (list 'quasiquote
                  (append
                   '("--enable-plugin"
                     "--enable-languages=c,c++"
                     "--disable-multilib"

          "--with-local-prefix=/no-gcc-local-prefix"
                     "--with-local-prefix=/no-gcc-local-prefix"

          ,(let ((libc (assoc-ref %build-inputs "libc")))
             (if libc
                 (string-append "--with-native-system-header-dir=" libc
                                "/include")
                 "--without-headers")))
        #:make-flags
        (let ((libc (assoc-ref %build-inputs "libc")))
          `(,@(if libc
                  (list (string-append "LDFLAGS_FOR_TARGET="
                                       "-B" libc "/lib "
                                       "-Wl,-dynamic-linker "
                                       "-Wl," libc
                                       ,(glibc-dynamic-linker)))
                  '())
            ,(string-append "BOOT_CFLAGS=-O2 "
                            ,(if stripped? "-g0" "-g"))))
                     ,(let ((libc (assoc-ref %build-inputs "libc")))
                        (if libc
                            (string-append "--with-native-system-header-dir=" libc
                                           "/include")
                            "--without-headers")))

                   (maybe-target-tools))))))
    (package
      (name "gcc")
      (version "4.7.3")
      (source (origin
               (method url-fetch)
               (uri (string-append "mirror://gnu/gcc/gcc-"
                                   version "/gcc-" version ".tar.bz2"))
               (sha256
                (base32
                 "1hx9h64ivarlzi4hxvq42as5m9vlr5cyzaaq4gzj4i619zmkfz1g"))))
      (build-system gnu-build-system)
      (inputs `(("gmp" ,gmp)
                ("mpfr" ,mpfr)
                ("mpc" ,mpc)
                ("isl" ,isl)
                ("cloog" ,cloog)
                ("libelf" ,libelf)
                ("zlib" ,zlib)))
      (arguments
       `(#:out-of-source? #t
         #:strip-binaries? ,stripped?
         #:configure-flags ,(configure-flags)
         #:make-flags
         (let ((libc (assoc-ref %build-inputs "libc")))
           `(,@(if libc
                   (list (string-append "LDFLAGS_FOR_TARGET="
                                        "-B" libc "/lib "
                                        "-Wl,-dynamic-linker "
                                        "-Wl," libc
                                        ,(glibc-dynamic-linker)))
                   '())
             ,(string-append "BOOT_CFLAGS=-O2 "
                             ,(if stripped? "-g0" "-g"))))

        #:tests? #f
        #:phases
        (alist-cons-before
         'configure 'pre-configure
         (lambda* (#:key inputs outputs #:allow-other-keys)
           (let ((out  (assoc-ref outputs "out"))
                 (libc (assoc-ref inputs "libc")))
             (when libc
               ;; The following is not performed for `--without-headers'
               ;; cross-compiler builds.
         #:tests? #f
         #:phases
         (alist-cons-before
          'configure 'pre-configure
          (lambda* (#:key inputs outputs #:allow-other-keys)
            (let ((out  (assoc-ref outputs "out"))
                  (libc (assoc-ref inputs "libc")))
              (when libc
                ;; The following is not performed for `--without-headers'
                ;; cross-compiler builds.

               ;; Fix the dynamic linker's file name.
               (substitute* (find-files "gcc/config"
                                        "^linux(64|-elf)?\\.h$")
                 (("#define GLIBC_DYNAMIC_LINKER([^ ]*).*$" _ suffix)
                  (format #f "#define GLIBC_DYNAMIC_LINKER~a \"~a\"~%"
                          suffix
                          (string-append libc ,(glibc-dynamic-linker)))))
                ;; Fix the dynamic linker's file name.
                (substitute* (find-files "gcc/config"
                                         "^linux(64|-elf)?\\.h$")
                  (("#define GLIBC_DYNAMIC_LINKER([^ ]*).*$" _ suffix)
                   (format #f "#define GLIBC_DYNAMIC_LINKER~a \"~a\"~%"
                           suffix
                           (string-append libc ,(glibc-dynamic-linker)))))

               ;; Tell where to find libstdc++, libc, and `?crt*.o', except
               ;; `crt{begin,end}.o', which come with GCC.
               (substitute* (find-files "gcc/config"
                                        "^(gnu-user(64)?|linux-elf)\\.h$")
                 (("#define LIB_SPEC (.*)$" _ suffix)
                  ;; Note that with this "lib" spec, we may still add a
                  ;; RUNPATH to GCC even when `libgcc_s' is not NEEDED.
                  ;; There's not much that can be done to avoid it, though.
                  (format #f "#define LIB_SPEC \"-L~a/lib %{!static:-rpath=~a/lib \
                ;; Tell where to find libstdc++, libc, and `?crt*.o', except
                ;; `crt{begin,end}.o', which come with GCC.
                (substitute* (find-files "gcc/config"
                                         "^(gnu-user(64)?|linux-elf)\\.h$")
                  (("#define LIB_SPEC (.*)$" _ suffix)
                   ;; Note that with this "lib" spec, we may still add a
                   ;; RUNPATH to GCC even when `libgcc_s' is not NEEDED.
                   ;; There's not much that can be done to avoid it, though.
                   (format #f "#define LIB_SPEC \"-L~a/lib %{!static:-rpath=~a/lib \
%{!static-libgcc:-rpath=~a/lib64 -rpath=~a/lib}} \" ~a"
                          libc libc out out suffix))
                 (("#define STARTFILE_SPEC.*$" line)
                  (format #f "#define STANDARD_STARTFILE_PREFIX_1 \"~a/lib\"
                           libc libc out out suffix))
                  (("#define STARTFILE_SPEC.*$" line)
                   (format #f "#define STANDARD_STARTFILE_PREFIX_1 \"~a/lib\"
#define STANDARD_STARTFILE_PREFIX_2 \"\"
~a~%"
                          libc line))))
                           libc line))))

             ;; Don't retain a dependency on the build-time sed.
             (substitute* "fixincludes/fixincl.x"
               (("static char const sed_cmd_z\\[\\] =.*;")
                "static char const sed_cmd_z[] = \"sed\";"))))
              ;; Don't retain a dependency on the build-time sed.
              (substitute* "fixincludes/fixincl.x"
                (("static char const sed_cmd_z\\[\\] =.*;")
                 "static char const sed_cmd_z[] = \"sed\";"))))

         (alist-cons-after
          'configure 'post-configure
          (lambda _
            ;; Don't store configure flags, to avoid retaining references to
            ;; build-time dependencies---e.g., `--with-ppl=/nix/store/xxx'.
            (substitute* "Makefile"
              (("^TOPLEVEL_CONFIGURE_ARGUMENTS=(.*)$" _ rest)
               "TOPLEVEL_CONFIGURE_ARGUMENTS=\n")))
          (alist-replace 'install
                         (lambda* (#:key outputs #:allow-other-keys)
                           (zero?
                            (system* "make"
                                     ,(if stripped?
                                          "install-strip"
                                          "install"))))
                         %standard-phases)))))
          (alist-cons-after
           'configure 'post-configure
           (lambda _
             ;; Don't store configure flags, to avoid retaining references to
             ;; build-time dependencies---e.g., `--with-ppl=/nix/store/xxx'.
             (substitute* "Makefile"
               (("^TOPLEVEL_CONFIGURE_ARGUMENTS=(.*)$" _ rest)
                "TOPLEVEL_CONFIGURE_ARGUMENTS=\n")))
           (alist-replace 'install
                          (lambda* (#:key outputs #:allow-other-keys)
                            (zero?
                             (system* "make"
                                      ,(if stripped?
                                           "install-strip"
                                           "install"))))
                          %standard-phases)))))

     (native-search-paths
      (list (search-path-specification
             (variable "CPATH")
             (directories '("include")))
            (search-path-specification
             (variable "LIBRARY_PATH")
             (directories '("lib" "lib64")))))
      (native-search-paths
       (list (search-path-specification
              (variable "CPATH")
              (directories '("include")))
             (search-path-specification
              (variable "LIBRARY_PATH")
              (directories '("lib" "lib64")))))

     (properties `((gcc-libc . ,(assoc-ref inputs "libc"))))
     (synopsis "GNU Compiler Collection")
     (description
      "The GNU Compiler Collection includes compiler front ends for C, C++,
      (properties `((gcc-libc . ,(assoc-ref inputs "libc"))))
      (synopsis "GNU Compiler Collection")
      (description
       "The GNU Compiler Collection includes compiler front ends for C, C++,
Objective-C, Fortran, OpenMP for C/C++/Fortran, Java, and Ada, as well as
libraries for these languages (libstdc++, libgcj, libgomp,...).

GCC development is a part of the GNU Project, aiming to improve the compiler
used in the GNU system including the GNU/Linux variant.")
     (license gpl3+)
     (home-page "http://gcc.gnu.org/"))))
      (license gpl3+)
      (home-page "http://gcc.gnu.org/"))))

(define-public gcc-4.8
  ;; FIXME: Move to gcc.scm when Binutils is updated.