Opened 3 months ago

Last modified 3 months ago

#70341 new defect

g++ fails to compile when -libstd=libc++ is set

Reported by: mouse07410 (Mouse) Owned by:
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc: cjones051073 (Chris Jones)
Port: gcc12 gcc13 gcc14

Description (last modified by mouse07410 (Mouse))

This problem started with GCC12, and continues with GCC13. Also, GCC14 - but that one simply doesn't work, so better to concentrate on releases that otherwise do compile successfully.

File in question t3.cpp:

#include <iostream>

int main() {
     std::cout << "Hello World!" << std::endl;
     return 0;
}

"Normal" compilation:

$ g++-mp-13 -pipe  -o t3 t3.cpp
$ ./t3
Hello World!
$ 

Attempt to compile with -libstd=libc++:

$ g++-mp-13 -pipe -stdlib=libc++ -o t3 t3.cpp
In file included from /opt/local/libexec/gcc13/libc++/include/c++/v1/__concepts/convertible_to.h:13,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__concepts/common_reference_with.h:12,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__compare/three_way_comparable.h:14,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__compare/compare_three_way.h:13,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__memory/shared_ptr.h:14,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/mutex:191,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__locale:18,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/ios:221,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/iostream:43,
                 from t3.cpp:1:
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:71:8: error: expected identifier before '__is_convertible'
   71 | struct __is_convertible
      |        ^~~~~~~~~~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:71:8: error: expected unqualified-id before '__is_convertible'
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:77:40: error: expected identifier before '__is_convertible'
   77 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};
      |                                        ^~~~~~~~~~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:77:40: error: expected unqualified-id before '__is_convertible'
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:78:40: error: expected identifier before '__is_convertible'
   78 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};
      |                                        ^~~~~~~~~~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:78:40: error: expected unqualified-id before '__is_convertible'
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:79:40: error: expected identifier before '__is_convertible'
   79 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};
      |                                        ^~~~~~~~~~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:79:40: error: expected unqualified-id before '__is_convertible'
/opt/local/libexec/gcc13/libc++/include/c++/v1/__type_traits/is_convertible.h:80:40: error: expected identifier before '__is_convertible'
   80 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};
.  .  .
/opt/local/libexec/gcc13/libc++/include/c++/v1/__thread/poll_with_backoff.h:51:15:   required from 'bool std::__1::__libcpp_thread_poll_with_backoff(_Fn&&, _BFn&&, chrono::nanoseconds) [with _Fn = __cxx_atomic_wait_test_fn_impl<const volatile __cxx_atomic_impl<bool>, bool>&; _BFn = __libcpp_atomic_wait_backoff_impl<const volatile __cxx_atomic_impl<bool>, __cxx_atomic_wait_test_fn_impl<const volatile __cxx_atomic_impl<bool>, bool> >&; chrono::nanoseconds = chrono::duration<long long int, ratio<1, 1000000000> >]'
/opt/local/libexec/gcc13/libc++/include/c++/v1/atomic:1482:50:   required from 'bool std::__1::__cxx_atomic_wait(_Atp*, _Fn&&) [with _Atp = const volatile __cxx_atomic_impl<bool>; _Fn = __cxx_atomic_wait_test_fn_impl<const volatile __cxx_atomic_impl<bool>, bool>&]'
/opt/local/libexec/gcc13/libc++/include/c++/v1/atomic:1515:34:   required from 'bool std::__1::__cxx_atomic_wait(_Atp*, _Tp, memory_order) [with _Atp = const volatile __cxx_atomic_impl<bool>; _Tp = bool; memory_order = memory_order]'
/opt/local/libexec/gcc13/libc++/include/c++/v1/atomic:2376:27:   required from here
/opt/local/libexec/gcc13/libc++/include/c++/v1/__chrono/duration.h:247:9: note: candidate: 'std::__1::chrono::duration<_Rep, _Period>::duration() [with _Rep = long long int; _Period = std::__1::ratio<1, 1000000000>]'
  247 |         duration() = default;
      |         ^~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/__chrono/duration.h:247:9: note:   candidate expects 0 arguments, 1 provided
/opt/local/libexec/gcc13/libc++/include/c++/v1/__chrono/duration.h:202:28: note: candidate: 'constexpr std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >::duration(const std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >&)'
  202 | class _LIBCPP_TEMPLATE_VIS duration
      |                            ^~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/__chrono/duration.h:202:28: note:   no known conversion for argument 1 from 'std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >::rep' {aka 'long long int'} to 'const std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >&'
/opt/local/libexec/gcc13/libc++/include/c++/v1/__chrono/duration.h:202:28: note: candidate: 'constexpr std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >::duration(std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >&&)'
/opt/local/libexec/gcc13/libc++/include/c++/v1/__chrono/duration.h:202:28: note:   no known conversion for argument 1 from 'std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >::rep' {aka 'long long int'} to 'std::__1::chrono::duration<long long int, std::__1::ratio<1, 1000000000> >&&'
$ 

Attachments (1)

g++-t3-log.txt (269.1 KB) - added by mouse07410 (Mouse) 3 months ago.
Complete output of compilation (1570 lines)

Download all attachments as: .zip

Change History (28)

Changed 3 months ago by mouse07410 (Mouse)

Attachment: g++-t3-log.txt added

Complete output of compilation (1570 lines)

comment:1 Changed 3 months ago by mouse07410 (Mouse)

Description: modified (diff)

comment:2 Changed 3 months ago by cjones051073 (Chris Jones)

So, here is the thing. libc++ support with GCC is, and always has been, somewhat experimental. Its a nice idea, and when I first added support it worked OK, for some cases, but even then you could not compile every you could with GCC+stdlibc++ or clang+libc++, there where plenty of things which just did not work.

Part of the problem is GCC expects the LLVM/clang headers to use when targeting libc++ to be externally supplied to the build, GCC does not ship a compatible set itself. The question then of course is which to use, and here it gets even murkier as GCC has varying support for different versions. Xcode does not (from memory) supply anything usable so we have to rely on one of our own clang ports.

This is where the sub-ports gccN-libcxx come in. These take a copy of the required headers, from a clang version, and these are then use during the GCC build.

These sub-ports offer various possible clang versions to use, with one picked as the default. e.g.

Larissa ~/Projects/MacPorts/ports > port info gcc13-libcxx
gcc13-libcxx @13.3.0_1 (lang)
Variants:             clang11, clang12, clang13, clang14, clang15, [+]clang16, clang17, clang18

Description:          libc++ header implementation to be used by gcc13
Homepage:             https://llvm.org/

Build Dependencies:   clang-16
Platforms:            any
License:              NCSA
Maintainers:          none

now, the best I can get is with gcc14 (I have built from source so currently by-passing the issues in https://trac.macports.org/ticket/70331) and when I have upped the clang version to 17. Even then I get

Larissa ~/cernbox/MacPorts/simple > g++-mp-14 -stdlib=libc++ ./test.cpp
In file included from /opt/local/libexec/gcc14/libc++/include/c++/v1/new:99,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/__memory/construct_at.h:23,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/__memory/allocator_traits.h:14,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/__memory/allocation_guard.h:15,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/__memory/shared_ptr.h:22,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/__locale:15,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/ios:222,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/iostream:43,
                 from ./test.cpp:1:
/opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib:144:9: error: 'at_quick_exit' has not been declared in '::'
  144 | using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
      |         ^~~~~~~~~~~~~
/opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib:145:9: error: 'quick_exit' has not been declared in '::'
  145 | using ::quick_exit _LIBCPP_USING_IF_EXISTS;
      |         ^~~~~~~~~~
Larissa ~/cernbox/MacPorts/simple > 

which in itself is yet another issue we have been seeing in a few places recently.

So Mouse, by all means play with this. Try out different clang versions to use as the header source. But, in the end, this is experimental 'you get what you pay for' level stuff at the moment I am afraid.

comment:3 Changed 3 months ago by cjones051073 (Chris Jones)

Port: gcc14 added

comment:4 Changed 3 months ago by mouse07410 (Mouse)

libc++ support with GCC is, and always has been, somewhat experimental. Its a nice idea, and when I first added support it worked OK, for some cases, but even then you could not compile every you could with GCC+stdlibc++ or clang+libc++, there where plenty of things which just did not work

I see. I was not aware of that. In fact, for a long time, I used G++ to compile Crypto++ package with -stdlib=libc++, and it worked fine (!!!).

Starting with GCC12, it stopped working. :-(

Yes, I confirm that "quick_exit" is the issue that keeps rearing its ugly head now.

by all means play with this. Try out different clang versions to use as the header source

Here's what I get (gcc13-libcxx +clang18 and gcc12-libcxx +clang17):

$ g++-mp-13 -stdlib=libc++ -o t3 t3.cpp
In file included from /opt/local/libexec/gcc13/libc++/include/c++/v1/new:364,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__memory/construct_at.h:23,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__memory/allocator_traits.h:14,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__memory/allocation_guard.h:15,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__memory/shared_ptr.h:24,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/__locale:15,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/ios:223,
                 from /opt/local/libexec/gcc13/libc++/include/c++/v1/iostream:43,
                 from t3.cpp:1:
/opt/local/libexec/gcc13/libc++/include/c++/v1/cstdlib:146:9: error: 'at_quick_exit' has not been declared in '::'
  146 | using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
      |         ^~~~~~~~~~~~~
/opt/local/libexec/gcc13/libc++/include/c++/v1/cstdlib:147:9: error: 'quick_exit' has not been declared in '::'
  147 | using ::quick_exit _LIBCPP_USING_IF_EXISTS;
      |         ^~~~~~~~~~
$ g++-mp-12 -stdlib=libc++ -o t3 t3.cpp
In file included from /opt/local/libexec/gcc12/libc++/include/c++/v1/new:99,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/__memory/construct_at.h:23,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/__memory/allocator_traits.h:14,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/__memory/allocation_guard.h:15,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/__memory/shared_ptr.h:22,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/__locale:15,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/ios:222,
                 from /opt/local/libexec/gcc12/libc++/include/c++/v1/iostream:43,
                 from t3.cpp:1:
/opt/local/libexec/gcc12/libc++/include/c++/v1/cstdlib:144:9: error: 'at_quick_exit' has not been declared in '::'
  144 | using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
      |         ^~~~~~~~~~~~~
/opt/local/libexec/gcc12/libc++/include/c++/v1/cstdlib:145:9: error: 'quick_exit' has not been declared in '::'
  145 | using ::quick_exit _LIBCPP_USING_IF_EXISTS;
      |         ^~~~~~~~~~
$ 

Same problem you're observing. Any luck approaching it, BTW?

comment:5 Changed 3 months ago by cjones051073 (Chris Jones)

I haven't given this issue a lot of thought myself, but currently no I don't have an idea how to start approaching this.

comment:6 Changed 3 months ago by ryandesign (Ryan Carsten Schmidt)

Cc: ryandesign removed

comment:7 Changed 3 months ago by mouse07410 (Mouse)

Well, this is an annoyingly stupid problem - and I came up with an equally stupid workaround:

--- /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig	2024-07-09 13:43:11
+++ /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib	2024-07-09 13:42:41
@@ -142,7 +142,7 @@
 using ::mbstowcs _LIBCPP_USING_IF_EXISTS;
 using ::wcstombs _LIBCPP_USING_IF_EXISTS;
 #endif
-#if !defined(_LIBCPP_CXX03_LANG)
+#if !defined(_LIBCPP_CXX03_LANG) && 0
 using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 #endif

With it, -libstd=libc++ mostly works:

$ cat t-sstream.cpp 
#include <string>
#include <iostream>
#include <sstream>

int main () {

  std::ostringstream foo;
  std::stringstream boo;

  foo.str("Test string");
  boo.str("Example string");

  //std::cout << foo << std::endl;
  std::cout << foo.str() << std::endl;

  foo << boo.str();

  //std::cout << foo << std::endl;
  std::cout << foo.str() << std::endl;

  return 0;
}
$ g++-mp-14 -pipe -stdlib=libc++ -std=gnu++20 -o t t-sstream.cpp
$ ./t
Test string
Example string
$ 

comment:8 Changed 3 months ago by mouse07410 (Mouse)

Here's the next problem that surfaced when I was compiling https://github.com/weidai11/cryptopp.git with G++-14, using -libstd=libc++ (without that flag it builds fine and passes all the tests):

.  .  .
g++ -stdlib=libc++ -pipe -DNDEBUG -g2 -Wa,-q -fPIC -pthread -fno-common -pipe -std=gnu++20 -O3 -march=native -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -c dh2.cpp
g++ -stdlib=libc++ -pipe -DNDEBUG -g2 -Wa,-q -fPIC -pthread -fno-common -pipe -std=gnu++20 -O3 -march=native -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -c dll.cpp
In file included from /opt/local/libexec/gcc14/libc++/include/c++/v1/__filesystem/filesystem_error.h:15,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/__filesystem/directory_entry.h:20,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/filesystem:539,
                 from /opt/local/libexec/gcc14/libc++/include/c++/v1/fstream:199,
                 from files.h:16,
                 from dll.h:27,
                 from dll.cpp:6:
/opt/local/libexec/gcc14/libc++/include/c++/v1/__filesystem/path.h: In instantiation of 'std::__1::__fs::filesystem::path::_EnableIfPathable<_Source> std::__1::__fs::filesystem::path::append(const _Source&) [with _Source = std::__1::basic_string<char>]':
/opt/local/libexec/gcc14/libc++/include/c++/v1/__filesystem/path.h:534:52: error: use of built-in trait '__remove_pointer(typename std::__1::decay<_Tp>::type)' in function signature; use library traits instead
  534 |   _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) {
      |                                                    ^~~~~~
make: *** [dll.o] Error 1

comment:9 Changed 3 months ago by cjones051073 (Chris Jones)

yeah, hacking the headers like that was not the direction I was thinking of.

I was more thinking we should first contact the GCC maintainers to find out what the level of support still is for libc++ in GCC. Is it still supported, and whatever level, or has interest died off. we also should find out if there is an 'officially' support set of headers we can use, rather than just guessing ourselves.

comment:10 Changed 3 months ago by mouse07410 (Mouse)

hacking the headers like that was not the direction I was thinking of

I understand. However, these two problems seem to be header-induced (or by the mechanism that mucks with the headers).

The first one that I "knew" how to fix: the correct fix is the following - it was present in GCC12 originally, and then somehow got lost:

diff -uw /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib
--- /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig	2024-07-09 13:43:11
+++ /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib	2024-07-10 09:41:58
@@ -142,7 +142,7 @@
 using ::mbstowcs _LIBCPP_USING_IF_EXISTS;
 using ::wcstombs _LIBCPP_USING_IF_EXISTS;
 #endif
-#if !defined(_LIBCPP_CXX03_LANG)
+#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
 using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 #endif

The second problem, which I don't know how to fix, is about using a "built-in trait". Since I don't understand how that piece works, I don't think merely removing the __remove_pointer<> wrapper of the argument would be correct.

Could you please get the above fix incorporated in the ports (gcc12-gcc13-gcc14)? And perhaps you could report the "error: use of built-in trait" to the upstream?

Thanks!

comment:11 Changed 3 months ago by kencu (Ken)

When you prepared to push the gcc libc++ stuff to macports, you might recall I pointed out that Iain had already said the headers were not yet right to support that. You pushed it anyway.

Nobody has worked on fixing a set of headers since then.

The fact that people are having troubles using it was inevitable.

comment:12 in reply to:  10 Changed 3 months ago by cjones051073 (Chris Jones)

Replying to mouse07410:

hacking the headers like that was not the direction I was thinking of

I understand. However, these two problems seem to be header-induced (or by the mechanism that mucks with the headers).

The first one that I "knew" how to fix: the correct fix is the following - it was present in GCC12 originally, and then somehow got lost:

diff -uw /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib
--- /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig	2024-07-09 13:43:11
+++ /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib	2024-07-10 09:41:58
@@ -142,7 +142,7 @@
 using ::mbstowcs _LIBCPP_USING_IF_EXISTS;
 using ::wcstombs _LIBCPP_USING_IF_EXISTS;
 #endif
-#if !defined(_LIBCPP_CXX03_LANG)
+#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
 using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 #endif

The second problem, which I don't know how to fix, is about using a "built-in trait". Since I don't understand how that piece works, I don't think merely removing the __remove_pointer<> wrapper of the argument would be correct.

Could you please get the above fix incorporated in the ports (gcc12-gcc13-gcc14)? And perhaps you could report the "error: use of built-in trait" to the upstream?

For the headers, please note the files under /opt/local/libexec/gcc14/libc++/include have nothing to do with GCC. They are the copy of the headers from a particular clang version, as determined by the clang variant you used to install gccN-libcxx. So in that regard there is nothing there for me to fix (and no, I am not going to submit a bug report to LLVM/clang for this).

Can you isolate which clang version the issue started with ?

On the second point, no, I will not be the one chasing the built-in trait issue. I don't have the time (or interest) to do this. Please follow up yourself.

Thanks!

Last edited 3 months ago by cjones051073 (Chris Jones) (previous) (diff)

comment:13 in reply to:  11 Changed 3 months ago by cjones051073 (Chris Jones)

Replying to kencu:

When you prepared to push the gcc libc++ stuff to macports, you might recall I pointed out that Iain had already said the headers were not yet right to support that. You pushed it anyway.

Nobody has worked on fixing a set of headers since then.

The fact that people are having troubles using it was inevitable.

It was pushed to allow people to experiment with, not as a finished article, and in that regard it has served its purpose. I stand by doing it.

comment:14 Changed 3 months ago by mouse07410 (Mouse)

It was pushed to allow people to experiment with, not as a finished article, and in that regard it has served its purpose. I stand by doing it

I too support this decision.

comment:15 Changed 3 months ago by mouse07410 (Mouse)

Can you isolate which clang version the issue started with ?

The quick_exit issue started with one of the GCC12 updates, and persisted since (GCC13, GCC14). Thus, I'm leaning towards saying that it started with Clang-16 or -17. Definitely no later than -17.

See https://github.com/iains/gcc-14-branch/issues/7#issuecomment-2220937446 for recommendations.

Last edited 3 months ago by mouse07410 (Mouse) (previous) (diff)

comment:16 Changed 3 months ago by cjones051073 (Chris Jones)

I am not going to start patching around the headers installed by the gccN-libcxx ports. These are just a direct copy of the headers from LLVm/clang, so any fixes on that side will first have to find there way into an LLVm-clang release, which gccN-libcxx will subsequently pick up.

comment:17 Changed 3 months ago by mouse07410 (Mouse)

@Chris, with all due respect, it looks like this patch comment:10 was either lost (?), or, more likely, dropped from the upstream - so it's either you, or each user who needs this to work.

If you know how to tell the appropriate maintainers (i.e., what repo and where to raise the issue), please let me know here, and I'll do it.

Update Do you happen to have a theory why it works OK without patching in Clang? As all the Clang's mentioned (-16, -17, -18) work fine without this patch, and they obviously use libc++.

Last edited 3 months ago by ryandesign (Ryan Carsten Schmidt) (previous) (diff)

comment:18 Changed 3 months ago by cjones051073 (Chris Jones)

You should report it to LLVM/clang and see what they say, but I suspect they may not care much how well GCC supports using their headers and thus will consider this a GCC issue.

comment:19 Changed 3 months ago by mouse07410 (Mouse)

report it to LLVM/clang and see what they say

It would be great if you could point me at the specific repo (on GitHub, presumably?).

comment:20 Changed 3 months ago by cjones051073 (Chris Jones)

I do not know where LLVM/clang track their bug reports. Presumably this info is somewhere under https://llvm.org/

comment:22 Changed 3 months ago by mouse07410 (Mouse)

As you can see from the issue, upstream will not fix this problem. So, it's either Macports patching ctsdlib file, or each user individually, or we all waiting for Xcode-16 release.

comment:23 Changed 3 months ago by kencu (Ken)

Xcode 16 will be of no value, and will do nothing to help improve the situation.

If you look through the commit history in the LLVM Libcxx directory, you’ll find the commit two years ago, where the workaround that used to make this work was removed and broke this. It’s no surprise that Louis didn’t want to put it back in. He was the one who took it out.

Your options at this point in time are to give up, which would probably be the best idea. Alternatively, you could find the commit yourself, which took me no more than 60 seconds to find, and patch it back in for your own use. Or you could use the headers from LLVM 14, which pre-date the commit that broke it, rather than LLVM 17, which has the updated headers that broke it.

Even if you do that, you will be highly likely to find other inconsistencies soon enough.

as to Chris’s point about standing by the decision to push things that are broken, just so people can experiment with them, I think this is just a recipe for frustration and disaster much like the frustration that you are currently experiencing, and then asking people to go about fixing things when you have no idea how to do it yourself is probably not going to lead anywhere useful.

comment:24 Changed 3 months ago by cjones051073 (Chris Jones)

The response from LLVM is entirely what I expected.

I will not be patching the headers manually for this on the macPorts side. If GCC wishes to carry on supporting building against libc++, it is then up to then to support the recent headers, unpatched. I will leave it to you mouse to raise this with GCC, if you so feel inclined.

Given support for libc++ in GCC has degraded so much since I first added it, at this point I am more inclined (depending perhaps on what GCC says) to no longer enable the variant that enables libc++ support by default. It will still be available for those that want to try, but it won't be on by default...

comment:25 Changed 3 months ago by mouse07410 (Mouse)

In general, I do constrain myself to building with Clang only. Usually Xcode Clang, occasionally with Macports Clang. Xcode GCC has been nothing for a long time, so I don't even check it now to see if it improved at all.

Thus, most if not all of the C++ libraries on my systems are libc++ compatible, not stdc++. So, for those thankfully rare cases that I need to use GCC, it greatly improves usability and usefulness if it can produce libc++ compatible binaries.

Regarding Xcode having nothing to do with our libc++ support, here's what the upstream got to say:

The libc++ headers include some of the SDK headers. When updating XCode you get new (more recent) SDK headers, which should (apparently) now include declarations for quick_exit and friends.

Re. inconsistencies - so far, after applying the relevant patches to the header files, it's more or less smooth. Except for one weird problem ;-0 that I'm having linking Crypto++ library:

Undefined symbols for architecture x86_64:
  "___cxa_call_terminate", referenced from:
      CryptoPP::LazyPutter::~LazyPutter() in asn.o
      CryptoPP::LazyPutter::~LazyPutter() in asn.o
      CryptoPP::DERSequenceEncoder::~DERSequenceEncoder() in asn.o
      non-virtual thunk to CryptoPP::DERSequenceEncoder::~DERSequenceEncoder() in asn.o
      CryptoPP::DERSequenceEncoder::~DERSequenceEncoder() in asn.o
      non-virtual thunk to CryptoPP::DERSequenceEncoder::~DERSequenceEncoder() in asn.o
      CryptoPP::BERSequenceDecoder::~BERSequenceDecoder() in asn.o
      ...
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

If you happen to have any clues - I'd appreciate you sharing them.

Re. changing default: I'd much appreciate if you keep support for libc++ enabled by default. It doesn't hurt those who don't use it, and those who do, may find solution in the tickets like this one.

comment:26 Changed 3 months ago by cjones051073 (Chris Jones)

OK, so yes it is correct a number of SDKROOT headers get pulled in when you build, this is true regardless of if you are using libc++ or the GCC default stdlibc++. So if a future Xcode/CLT update adds the declarations currently missing that would include fix the issue.

Of course, that only helps if you are using this future hypothetical Xcode/CLT, so by contraction will only help with the newest OSes that support that Xcode.

That is also only true until the next incompatibility hits you, as you see above. In short, as long as support libc++ with GCC remains a 'side project' as it currently would seem to be, support is going to always be very patchy.

comment:27 Changed 3 months ago by cjones051073 (Chris Jones)

b.t.w. If a future Xcode does fix things, the solution for older OSes might well be for someone to add a fallback implementation of the missing methods to our legacy-support package.

Note: See TracTickets for help on using tickets.