andreas pushed a commit to branch core-packages-team
in repository guix.
commit ea59cc4b4866294ff26296052518960d7dfae647
Author: Leo Nikkilä <[email protected]>
AuthorDate: Fri Jan 17 05:08:49 2025 +0200
gnu: gcc-6: Use libstdc++ headers appropriate for each GCC.
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
[…]
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)
| ^
Updating libstdc++ to reference each GCC works around this.
* gnu/packages/gcc.scm (libstdc++, libstdc++-headers): Remove variables.
(make-libstdc++-headers): New procedure.
(gcc-6)[native-inputs]: Use it with `this-package'.
Change-Id: Ie05878c83860c4ccc29d66b916d11613e367e142
Signed-off-by: Ludovic Courtès <[email protected]>
Modified-by: Ludovic Courtès <[email protected]>
---
gnu/packages/gcc.scm | 50 +++++++++++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index 660f076366..66df55952d 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -17,6 +17,7 @@
;;; Copyright © 2023 Bruno Victal <[email protected]>
;;; Copyright © 2023 Maxim Cournoyer <[email protected]>
;;; Copyright © 2024 Nguyễn Gia Phong <[email protected]>
+;;; Copyright © 2025 Leo Nikkilä <[email protected]>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -51,6 +52,7 @@
#: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)
@@ -577,7 +579,7 @@ Go. It also includes runtime support libraries for these
languages.")
;; 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)))))
@@ -1125,30 +1127,28 @@ using compilers other than GCC."
(propagated-inputs '())
(synopsis "GNU C++ standard library")))
-(define libstdc++
- ;; Libstdc++ matching the default GCC.
- (make-libstdc++ gcc))
-
-(define libstdc++-headers
- ;; 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++")))
+(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))