-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unintended Consequences of Supporting -stdlib=libc++ #21
Comments
To summarize, the old behaviors in a large number of build systems are:
But now, by supporting
|
For now, as a workaround, for Gentoo Prefix, we will use just The old behavior is not perfect, of course, if clang and GCC are mixed when building software libraries, cross-linking libraries built by clang and built by GCC into the same binary can be a complete mess with a ton of conflicts. But the new behavior is equally a headache, since it broke the default assumption of many programs for deciding when to use |
A related problem is that, at least without changing the built-time option, the default include paths in distributions would be broken: on macOS 13, the system clang's default include path is, using Homebrew's package as an example:
Meanwhile for GCC, it's:
The system C++ library path is not correctly passed to GCC as a built-time option. This is not a bug, but the downstreams need to handle that for supporting |
I'll report it downstream at Homebrew. |
IFF one intends to configure GCC to support libc++ (which is actually a pretty good idea on modern Darwin) then you need to arrange to install or point the configuration to a suitable set of libc++ headers. There is no magic "it just works" to pick up those headers, since they are not part of GCC's sources (depending on the macOS version you might need to use older versions of libc++). The libc++ headers need to be configured to be used with GCC (not clang) - since they have different capabilities. Unfortunately, this is volunteer effort from me and $dayjob is very busy - but at some stage I hope to package up some suitable libc++ headers for GCC. [I did one set back in the gcc-9 era] |
Yes, and I think this problem is the part that is the easiest of solve. It's "just" a matter of supplying the correct default path to GCC during built time. However, the other problem, that is, the existing practice in many programs of relying on the presence or absence of The real problem for downstream distributions is:
Tricky question. |
yeah, abusing -stdlib as a means of detecting the compiler in use is a poor configuration script choice :(. From my PoV we 're trying to make GCC more compatible with modern macOS as time goes on - and supporting the system libc++ is pretty essential to that. |
Another question: what would happen if multiple |
That is exactly the point - but it ought not to be a problem for the "downstream" - the default configuration for GCC will look for c++/v1 in the compilers include directory - so the compiler distributor could/should arrange for a suitable set of headers to be found. |
Almost all command line switches for GCC take the last value specified, but I'd always recommend checking that before relying on it in a given case. |
I am going to close this:
However, it would be a very good idea to get any upstream projects fixed that are using this (incorrectly) to decide if the compiler is GCC or clang. As time goes on, IMO it will be increasingly important to allow GCC to use the system |
I have to disagree... I claimed that in the original report, but it eventually turned out to be a mistake when I was trying to patch Gentoo. The so-called "option" --disable-stdlib-option does not actually exist. In the upstream GCC, the original script defines the macro
Please consider an option for explicitly disabling stdlib for systems that need compatibility before other packages are fixed. |
Yes, sure - the intention would be to have some way to opt out of most things (in this case, a configuration test that tried to use the option would fail - but one that simply checks for its existence will not). I will take a look at this [we need to do a 13.1r1 anyway] |
this is what I am testing [on all open branches for the sake of preserving consistency] configure, Darwin: Adjust handing of stdlib option. The intent of the configuration choices for -stdlib is that default However, it seems that there are some cases where (external) config In order to allow for these cases, this patch refines the setting --with-gxx-libcxx-include-dir= is used to configure the path containing We are adding a special value for path: Otherwise if the --with-gxx-libcxx-include-dir is set we use the path if --with-gxx-libcxx-include-dir is unset edit: so that the default case (--with-gxx-libcxx-include-dir is unset) should produce the 'correct' behaviour for the defaults, absent the issue mentioned. |
To be repetitive: the scripts using support for -stdlib to determine the compiler in use really need fixing, since I think that there are projects that we want to be able to build with GCC that need libc++ support. I built around 120 core (from the toolchain perspective) OSS projects using gcc-7.5 + stdlib=libc++ and the libc++ headers I modified from LLVM 9(I think). This worked well - and I think would be even more important when mixing GCC and clang code - having two different (but quite similar) C++ runtimes bound into one executable seems likely to be asking for trouble :) |
Technically speaking, they do not determine the compiler type, but to determine which libc they are going to link. If But as clang's |
so, in practice, if we install a GCC-compatible set of libc++ headers, it should all "just work" (my experience [so far] has been that GCC + libc++ headers works fine). My open questions on that are (1) how many different header sets do we need to cover the OS version range and (2) how to deliver them - since i do not think that we are going to import libc++ into GCC any time soon, there will need to be separate step(s). |
although it is default to use libc++ from 10.8+ we obviously do not do that yet (because of needing to install the headers) - however, if it just happens that a package is assuming that it will be using libc++ (but will be really using libstdc++ with GCC, that could also cause us subtle [or not so subtle] issues) |
For the record, we cannot just link to the Xcode libc++ headers, because they were built against clang's internal headers and we then get mismatches in definitions of some entities (because GCC's stddef.h is different from clang's for example). There are also other issues to do with when headers are in experimental/ in clang and not in GCC (or vice versa). |
Suppose we ship GCC with libc++ headers or default to libc++ in GCC in the future, it can still create its own surprises at downstream. In the past, people expect GCC-built programs to use GCC's infrastructure, including libstdc++, and I believe most people still want things to stay this way. |
When a build script always adds |
yeah, there's a tension between "keeping the devil you know" and fixing things to work as they are supposed to. We have some turbulence ahead ; since we want to implement Maintaining the status quo (as of now) will mean that GCC is going to become unusable - we are already seeing some cases where there are no alternate APIs to the blocks ones... for some stuff [which is why libsanitizer is now disabled for Ventura+]. We need to recognise and deal with this - I am not sure that we can plan exactly - since this is still all voluntary at present so the timescales are unknown. |
one additional note; we do not actually default GCC to use libc++ in any proposed or released patch. The only effect of this patch is to enable the -stdlib option (so that one does not need to rebuild to add the support). What was unexpected was that packages would test the option only (and not that a program could be built successfully with it). Anyway, the revision in test provides a mechanism to back out of this. We do need to find a process to introduce things that make GCC a better compiler on macOS - and find ways to iron out the inevitable wrinkles. (std)libc++ is a particularly knotty problem, since the dyld-shared-cache includes the mentioned 'ancient' libstdc++. I am definitely open to suggestions on how you folks (i.e. my downstream) can help make sure that new work to make GCC more compatible can be integrated into the distro's workflow. |
…tproc. The newer tools apparently do not accept the existing order (which is likely to cause quite some fallout with other OSS using asm). Fixed here with a patch from Rich Townsend. Resolves Issue #21. Signed-off-by: Iain Sandoe <[email protected]> (cherry picked from commit 4fdcc027fcc235805c7cc4bede6948b9a00afe1e)
In the past, Darwin shipped an ancient C++ standard library by default, so most C++ programs needed to be compiled with the option
stdlib=libc++
to use the newer library shipped on macOS. This option is only supported by clang on Darwin, and it's invalid for GCC. Thus, most./configure
scripts attempt to check whether-stdlib=libc++
is a valid build-time option using a dummy program - if it's the case, this flag is passed to the compiler. If it's not, it's omitted. Thus, when the program is compiled with (an up-to-date version of) GCC, it automatically links to native C++ runtime forg++
. When the program is compiled with clang, it automatically links to Apple's new C++ library.Unfortunately, since GCC Darwin 12.2, now it recognizes the option
stdlib=libc++
and attempts linking to Darwin's C++ library instead of GCC's native C++ library. As a result, compilation of many previously successful programs now may fail if C++ iflibc++
's header files are not present on the system. Since a dummy program without any#include
statement is used to check the existence of-stdlib=libc++
, it escapes detection but later fails in the middle of the build.The minimum example is:
In the past, because
-stdlib=libc++
was unsupported, the build system would remove-stdlib=libc++
from theCFLAGS
and successfully building the program. But now,-stdlib=libc++
is passed to GCC, the compilation of the same program now fails due to missinglibc++
system headers.Replicated on both Gentoo Prefix and Homebrew.
It's not strictly a bug, but it's noteworthy enough to be reported here.
The text was updated successfully, but these errors were encountered: