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

Done: Ludovic Courtès <ludo <at> gnu.org>

To reply to this bug, email your comments to 75620 AT debbugs.gnu.org.
There is no need to reopen the bug first.

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





Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Fri, 11 Apr 2025 09:50:02 GMT) Full text and rfc822 format available.

Notification sent to Leo Nikkilä <hello <at> lnikki.la>:
bug acknowledged by developer. (Fri, 11 Apr 2025 09:50:02 GMT) Full text and rfc822 format available.

Message #10 received at 75620-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Leo Nikkilä <hello <at> lnikki.la>
Cc: 75620-done <at> debbugs.gnu.org
Subject: Re: bug#75620: [PATCH core-packages-team] gnu: gcc-6: Use libstdc++
 headers appropriate for each GCC.
Date: Fri, 11 Apr 2025 11:49:08 +0200
[Message part 1 (text/plain, inline)]
Hi Leo,

Leo Nikkilä <hello <at> lnikki.la> skribis:

> 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.

[...]

> * 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(-)

Somehow this patch fell into the cracks.

I’ve now applied it with the change below (using ‘mlambdaq’ for
‘make-libstdc++-headers’); I also shortened the commit log.

Thanks!

Ludo’.

[Message part 2 (text/x-patch, inline)]
diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index 0eec6452f6..5273aa2ce3 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -52,6 +52,7 @@ (define-module (gnu packages gcc)
   #:use-module (gnu packages perl)
   #:use-module (guix packages)
   #:use-module (guix download)
+  #:use-module (guix memoization)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system trivial)
   #:use-module (guix gexp)
@@ -1081,27 +1082,28 @@ (define-public (make-libstdc++ gcc)
     (propagated-inputs '())
     (synopsis "GNU C++ standard library")))
 
-(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).
-  (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 make-libstdc++-headers
+  (mlambdaq (gcc)      ;memoize to play well with the object cache
+    ;; 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).
+    (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))

Information forwarded to guix-patches <at> gnu.org:
bug#75620; Package guix-patches. (Tue, 15 Apr 2025 13:40:02 GMT) Full text and rfc822 format available.

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

From: Greg Hogan <code <at> greghogan.com>
To: 75620 <at> debbugs.gnu.org, ludo <at> gnu.org, hello <at> lnikki.la
Subject: Re: bug#75620: [PATCH core-packages-team] gnu: gcc-6: Use libstdc++
 headers appropriate for each GCC.
Date: Tue, 15 Apr 2025 09:39:01 -0400
On Fri, Apr 11, 2025 at 5:50 AM Ludovic Courtès <ludo <at> gnu.org> wrote:
>
> Hi Leo,
>
> Leo Nikkilä <hello <at> lnikki.la> skribis:
>
> > 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.
>
> [...]
>
> > * 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(-)
>
> Somehow this patch fell into the cracks.
>
> I’ve now applied it with the change below (using ‘mlambdaq’ for
> ‘make-libstdc++-headers’); I also shortened the commit log.
>
> Thanks!
>
> Ludo’.

With this patch I now get build errors on gcc older than 14. CI is
returning 504 when viewing evaluations, but I am getting:

libtool: compile:  g++
-I/tmp/guix-build-libstdc++-13.3.0.drv-0/gcc-13.3.0/libstdc++-v3/../libgcc
-I/tmp/guix-build-libstdc++-13.3.0.drv-0/gcc-13.3.0/build/include/
-I/tmp/guix-build-libstdc++-13.3.0.drv-0/gcc-13.3.0/build/include
-I/tmp/guix-build-libstdc++-13.3.0.drv-0/gcc-13.3.0/libstdc++-v3/libsupc++
-D_GLIBCXX_SHARED -fno-implicit-templates -Wall -Wextra
-Wwrite-strings -Wcast-qual -Wabi=2 -fdiagnostics-show-location=once
-ffunction-sections -fdata-sections -frandom-seed=eh_call.lo
-fcf-protection -mshstk -c ../../libstdc++-v3/libsupc++/eh_call.cc
-fPIC -DPIC -D_GLIBCXX_SHARED -o eh_call.o
../../libstdc++-v3/libsupc++/eh_call.cc:39:1: warning: new declaration
‘void __cxa_call_terminate(_Unwind_Exception*)’ ambiguates built-in
declaration ‘void __cxa_call_terminate(void*)’
[-Wbuiltin-declaration-mismatch]
   39 | __cxa_call_terminate(_Unwind_Exception* ue_header) throw ()
      | ^~~~~~~~~~~~~~~~~~~~
../../libstdc++-v3/libsupc++/eh_call.cc: In function ‘void
__cxa_call_terminate(_Unwind_Exception*)’:
../../libstdc++-v3/libsupc++/eh_call.cc:39:1: internal compiler error:
in gimple_build_eh_must_not_throw, at gimple.cc:730
0x7ffff7ced956 __libc_start_call_main
        ???:0
0x7ffff7ceda14 __libc_start_main_alias_1
        ???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
make[2]: *** [Makefile:777: eh_call.lo] Error 1
make[2]: Leaving directory
'/tmp/guix-build-libstdc++-13.3.0.drv-0/gcc-13.3.0/build/libsupc++'
make[1]: *** [Makefile:576: all-recursive] Error 1
make[1]: Leaving directory
'/tmp/guix-build-libstdc++-13.3.0.drv-0/gcc-13.3.0/build'
make: *** [Makefile:501: all] Error 2




This bug report was last modified 13 days ago.

Previous Next


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