Is it deliberate that the gcc@7 7.5 formula now has _GLIBCXX_HAVE_TLS defined?

In /usr/local/Cellar/gcc@7//7.4.0_2/include/c++/7.4.0/x86_64-apple-darwin18.5.0/bits/c++config.h:

1118 /* Define to 1 if the target supports thread-local storage. */
1119 /* #undef _GLIBCXX_HAVE_TLS */

In this case the gcc stdlib chooses constructs like __once_functor in <mutex> and the corresponding symbols are available in libstdc++.6.dylib.

But, in /usr/local/Cellar/gcc@7//7.5.0/include/c++/7.5.0/x86_64-apple-darwin18.7.0/bits/c++config.h:

1118 /* Define to 1 if the target supports thread-local storage. */
1119 #define _GLIBCXX_HAVE_TLS 1

Now the std lib chooses __once_call. However libstdc++.6.dylib only provides ___emutls_v._ZSt11__once_call. If I compile with gcc, it already picks the emulated symbol, but if I build with clang (against the gcc std lib) it doesn’t, so my build now fails because __ZSt11__once_call is undefined. It looks like I need to explicitly add -femulated-tls when building with clang now…?

Most of all I am hoping someone can tell me the intended behaviour here and then I can work around it :slight_smile:

Thanks

(Edit: this is not spam… but apparently got flagged as such?!)

1 Like

Hmm, actually building with clang against this stdlib and -femulated-tls just results in a seg fault at runtime when attempting to call std::call_once. However building with gcc does work.

Any guidance would be much appreciated…!

Bump… does nobody have any idea? Someone surely must be aware that _GLIBCXX_HAVE_TLS was changed in the brew package being published, and hopefully knows whether they meant to do this or not.

I did look at the change log of the formula but it just updates the SHA of the bottle. I don’t know how to trace how the change was made upstream. Can someone help there?

This is still a real issue for me so any response would be much appreciated!

This looks like a decision on the part of the gcc maintainers. Homebrew just packages the software. You can see the diff with brew log -u gcc@7, which leads you to this commit: https://github.com/Homebrew/homebrew-core/commit/0f9799e2207c888668f4b48f951c245cc44f6afc

Thanks for the response @jonchang. I have asked about that on gcc-help but haven’t had a reply.

Meanwhile, I got my clang build against gcc 7.5 std lib working by linking to libgcc_s.1 explicitly. (gcc does this automatically)

So in case anyone else runs into this, here is my working build command to build with clang on OSX against the gcc 7.5 std lib:

usr/local/Cellar/llvm@7/7.1.0_1/bin/clang++ -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0 -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0/x86_64-apple-darwin18.7.0 -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0/backward -L /usr/local/Cellar/gcc@7/7.5.0/lib/gcc/7 -nostdinc++ -stdlib=libstdc++ -std=c++17  -femulated-tls -lgcc_s.1 example.cpp -o example

It appears that _GLIBCXX_HAVE_TLS has been changed inconsistently between the same versions of gcc for different OS versions, so this issue can come up with 7.4 as well. On Mojave in /usr/local/Cellar/gcc@7//7.4.0_2/include/c++/7.4.0/x86_64-apple-darwin18.5.0/bits/c++config.h :

1118 /* Define to 1 if the target supports thread-local storage. */
1119 /* #undef _GLIBCXX_HAVE_TLS */

On Catalina in /usr/local/Cellar/gcc@7/7.4.0_2/include/c++/7.4.0/x86_64-apple-darwin19.3.0/bits/c++config.h:

1118 /* Define to 1 if the target supports thread-local storage. */
1119 #define _GLIBCXX_HAVE_TLS 1

Note that both are 7.4.0_2.