GNU bug report logs - #75620
[PATCH core-packages-team] gnu: gcc-6: Use libstdc++ headers appropriate for each GCC.

Previous Next

Package: guix-patches;

Reported by: Leo Nikkilä <hello <at> lnikki.la>

Date: Fri, 17 Jan 2025 03:12:01 UTC

Severity: normal

Tags: patch

To reply to this bug, email your comments to 75620 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#75620; Package guix-patches. (Fri, 17 Jan 2025 03:12:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Leo Nikkilä <hello <at> lnikki.la>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Fri, 17 Jan 2025 03:12:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Leo Nikkilä <hello <at> lnikki.la>
To: guix-patches <at> gnu.org
Cc: Leo Nikkilä <hello <at> lnikki.la>
Subject: [PATCH core-packages-team] gnu: gcc-6: Use libstdc++ headers
 appropriate for each GCC.
Date: Fri, 17 Jan 2025 05:08:49 +0200
After the "hack" introduced for <https://issues.guix.gnu.org/42392>, all GCCs
are built with the current GCC's libstdc++ headers. This results in subtly
broken C++ headers in older versions, which aren't necessarily compatible with
libstdc++s from other versions.

For example, this test case works with GCC 11:

    $ guix shell --container --emulate-fhs --pure -e '(@ (gnu packages gcc) gcc)' binutils -- sh -c 'echo -e "#include <cmath>\nint main() { return std::isnan(0); }" | g++ -x c++ -; echo $?'
    0

but fails with GCC 9:

    $ guix shell --container --emulate-fhs --pure -e '(@ (gnu packages gcc) gcc-9)' binutils -- sh -c 'echo -e "#include <cmath>\nint main() { return std::isnan(0); }" | g++ -x c++ -; echo $?'
    
    In file included from /gnu/store/gkh2rljdrnj24q1q7baa6bhb119251w4-profile/include/c++/cmath:45,
                     from <stdin>:1:
    <stdin>: In function 'int main()':
    <stdin>:2:26: error: '__builtin_isnan' is not a member of 'std'; did you mean '__builtin_isnan'?
    <built-in>: note: '__builtin_isnan' declared here
    1

This specific error can be traced back to the GCC build, where GCC 10 and 11
are configured with:

    checking for ISO C99 support in <math.h> for C++11... yes

but GCC 9 is configured with:

    checking for ISO C99 support in <math.h> for C++11... no

The configure check fails due to errors like these due to the mismatched
libstdc++:

    configure:17817: checking for ISO C99 support in <math.h> for C++11
    configure:17886:  /tmp/guix-build-gcc-9.5.0.drv-0/build/./gcc/xgcc -shared-libgcc -B/tmp/guix-build-gcc-9.5.0.drv-0/build/./gcc -nostdinc++ -L/tmp/guix-build-gcc-9.5.0.drv-0/build/aarch64-unknown-linux-gnu/libstdc++-v3/src -L/tmp/guix-build-gcc-9.5.0.drv-0/build/aarch64-unknown-linux-gnu/libstdc++-v3/src/.libs -L/tmp/guix-build-gcc-9.5.0.drv-0/build/aarch64-unknown-linux-gnu/libstdc++-v3/libsupc++/.libs -B/gnu/store/l9a96zpznir4bm02lsycj35q0pakln32-gcc-9.5.0/aarch64-unknown-linux-gnu/bin/ -B/gnu/store/l9a96zpznir4bm02lsycj35q0pakln32-gcc-9.5.0/aarch64-unknown-linux-gnu/lib/ -isystem /gnu/store/l9a96zpznir4bm02lsycj35q0pakln32-gcc-9.5.0/aarch64-unknown-linux-gnu/include -isystem /gnu/store/l9a96zpznir4bm02lsycj35q0pakln32-gcc-9.5.0/aarch64-unknown-linux-gnu/sys-include   -fchecking=1 -o conftest -g -O2 -D_GNU_SOURCE -std=c++11 -fno-exceptions  -B/gnu/store/3gvs8sw95ldfypr1n688svl5brwdmdi9-glibc-2.39/lib -Wl,-dynamic-linker -Wl,/gnu/store/3gvs8sw95ldfypr1n688svl5brwdmdi9-glibc-2.39/lib/ld-linux-aarch64.so.1 conftest.cpp  -lm >&5
    In file included from /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/cmath:41,
                     from /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/math.h:36,
                     from conftest.cpp:41:
    /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/bits/c++config.h:491:18: error: missing binary operator before token "("
      491 | #if __has_builtin(__builtin_is_constant_evaluated)
          |                  ^
    In file included from /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/cmath:41,
                     from /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/math.h:36,
                     from conftest.cpp:41:
    /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/bits/c++config.h:732:25: error: missing binary operator before token "("
      732 | #if _GLIBCXX_HAS_BUILTIN(__has_unique_object_representations)
          |                         ^
    /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/bits/c++config.h:736:25: error: missing binary operator before token "("
      736 | #if _GLIBCXX_HAS_BUILTIN(__is_aggregate)
          |                         ^
    /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/bits/c++config.h:740:25: error: missing binary operator before token "("
      740 | #if _GLIBCXX_HAS_BUILTIN(__builtin_is_constant_evaluated)
          |                         ^
    /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/bits/c++config.h:744:25: error: missing binary operator before token "("
      744 | #if _GLIBCXX_HAS_BUILTIN(__is_same)
          |                         ^
    /gnu/store/y3kk0ybf7hqwndl8xpm61r4a5b3lhwix-libstdc++-11.4.0/include/bits/c++config.h:748:25: error: missing binary operator before token "("
      748 | #if _GLIBCXX_HAS_BUILTIN(__builtin_launder)
          |                         ^
    configure:17886: $? = 1

Updating libstdc++ to reference each GCC works around this. I've tested this
with GCC 9, but I swapped the `libstdc++-headers' input directly as I didn't
have the time to do a `guix pull'. I wrote this little test however to check
that `this-package' should work here:

    (use-modules (guix build-system trivial)
                 (guix gexp)
                 (guix packages))
    
    (define (make-requirement pkg)
      (define builder
        #~(call-with-output-file #$output
            (lambda (port)
              (format port "~a~%" #$(package-name pkg)))))
    
      (computed-file "requirement" builder))
    
    (define package-1
      (package
        (name "package-1")
        (version "1")
        (source #f)
        (build-system trivial-build-system)
        (inputs
         `(("requirement" ,(make-requirement this-package))))
        (arguments
         '(#:builder
           (copy-file (assoc-ref %build-inputs "requirement")
                      %output)))
        (synopsis #f)
        (description #f)
        (home-page #f)
        (license #f)))
    
    (define package-2
      (package
        (inherit package-1)
        (name "package-2")
        (version "2")))
    
    (list package-1 package-2)

Building these packages results in the expected output, where each package
uses an input customised for it:

    $ cat $(guix build -f this-package.scm)
    package-2
    package-1

* gnu/packages/gcc.scm (libstdc++, libstdc++-headers): Remove variables.
(make-libstdc++-headers): New procedure.
(gcc-6)[native-inputs]: Use it with `this-package'.
---
 gnu/packages/gcc.scm | 38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index 6247919fec4..3735a9c9d94 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -17,6 +17,7 @@
 ;;; Copyright © 2023 Bruno Victal <mirai <at> makinata.eu>
 ;;; Copyright © 2023 Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
 ;;; Copyright © 2024 Nguyễn Gia Phong <mcsinyx <at> disroot.org>
+;;; Copyright © 2025 Leo Nikkilä <hello <at> lnikki.la>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -549,7 +550,7 @@ (define-public gcc-6
        ;; XXX: This gross hack allows us to have libstdc++'s <bits/c++config.h>
        ;; in the search path, thereby avoiding misconfiguration of libstdc++:
        ;; <https://bugs.gnu.org/42392>.
-       ("libstdc++" ,libstdc++-headers)
+       ("libstdc++" ,(make-libstdc++-headers this-package))
 
        ,@(package-inputs gcc-4.7)))))
 
@@ -1055,31 +1056,28 @@ (define-public (make-libstdc++ gcc)
     (propagated-inputs '())
     (synopsis "GNU C++ standard library")))
 
-(define libstdc++
-  ;; Libstdc++ matching the default GCC.
-  (make-libstdc++ gcc))
-
-(define libstdc++-headers
+(define (make-libstdc++-headers gcc)
   ;; XXX: This package is for internal use to work around
   ;; <https://bugs.gnu.org/42392> (see above).  The main difference compared
   ;; to the libstdc++ headers that come with 'gcc' is that <bits/c++config.h>
   ;; is right under include/c++ and not under
   ;; include/c++/x86_64-unknown-linux-gnu (aka. GPLUSPLUS_TOOL_INCLUDE_DIR).
-  (package
-    (inherit libstdc++)
-    (name "libstdc++-headers")
-    (outputs '("out"))
-    (build-system trivial-build-system)
-    (arguments
-     '(#:builder (let* ((out       (assoc-ref %outputs "out"))
-                        (libstdc++ (assoc-ref %build-inputs "libstdc++")))
-                   (mkdir out)
-                   (mkdir (string-append out "/include"))
-                   (symlink (string-append libstdc++ "/include")
-                            (string-append out "/include/c++")))))
-    (inputs `(("libstdc++" ,libstdc++)))
-    (synopsis "Headers of GNU libstdc++")))
+  (let ((libstdc++ (make-libstdc++ gcc)))
+    (package
+      (inherit libstdc++)
+      (name "libstdc++-headers")
+      (outputs '("out"))
+      (build-system trivial-build-system)
+      (arguments
+       '(#:builder (let* ((out       (assoc-ref %outputs "out"))
+                          (libstdc++ (assoc-ref %build-inputs "libstdc++")))
+                     (mkdir out)
+                     (mkdir (string-append out "/include"))
+                     (symlink (string-append libstdc++ "/include")
+                              (string-append out "/include/c++")))))
+      (inputs `(("libstdc++" ,libstdc++)))
+      (synopsis "Headers of GNU libstdc++"))))
 
 (define-public libstdc++-4.9
   (make-libstdc++ gcc-4.9))

-- 
2.47.1





This bug report was last modified 81 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.