Skip to content
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

[bug] Invert the logic of _GLIBCXX_USE_CXX11_ABI ? #7070

Closed
0x8000-0000 opened this issue May 22, 2020 · 16 comments · Fixed by #8457
Closed

[bug] Invert the logic of _GLIBCXX_USE_CXX11_ABI ? #7070

0x8000-0000 opened this issue May 22, 2020 · 16 comments · Fixed by #8457

Comments

@0x8000-0000
Copy link

Environment Details (include every applicable attribute)

  • Operating System+version: Ubuntu 18.04
  • Compiler+version: gcc9
  • Conan version: 1.25.1
  • Python version: 3.6.9

Steps to reproduce (Include if Applicable)

The default for _GLIBCXX_USE_CXX11_ABI is 1 for several years now. Can we invert the logic of compiler.libcxx to use libstdc++ancient for the older version and use libstdc++ by default, or have libstdc++ NOT emit _GLIBCXX_USE_CXX11_ABI ?

The reason I'm asking this is that we have a rule for formatting global macros in clang-tidy which is tripped by this macro, and there is no way to suppress it in tidy, since it does not come from a source file, but it is injected on the command line.

I suppose this is a bug in tidy, but there is some redundancy in Conan / CMake injecting this variable explicitly when it is not needed for quite some time now.

@memsharded memsharded self-assigned this May 22, 2020
@memsharded
Copy link
Member

Hi @0x8000-0000

The default for _GLIBCXX_USE_CXX11_ABI is 1 for several years now. Can we invert the logic of compiler.libcxx to use libstdc++ancient for the older version and use libstdc++ by default, or have libstdc++ NOT emit _GLIBCXX_USE_CXX11_ABI ?

I am not sure I understood that. Is that you are using the default auto-detected profile that is using compiler.libcxx=libstdc++?

If that is the case, this is not a bug, this is by design, and cannot be changed without breaking. The reason it is this way is because of wider binary compatibility with older distros, even modern compilers can't upgrade to libstdc++11 in older distros: https://blog.conan.io/2016/03/22/From-CMake-syntax-to-libstdc++-ABI-incompatibiliy-migrations-are-always-hard.html

Using the default profile is not recommended for production. Better use your own profiles (can manage them with conan config install), with the compiler.libcxx=libstdc++11 value. Or if not, dynamically change the default one with conan profile update compiler.libcxx=libstdc++11 default.

Please let me know if that helps, most likely I didn't understand this well enough.

@0x8000-0000
Copy link
Author

I have compiler.libcxx=libstdc++11 in my profile, and it injects the definition on the command line when building, even though it is redundant given the compiler version I'm using.

The dual ABI page says:

Using the default configuration options for GCC the default value of the macro is 1 which causes the new ABI to be active, so to use the old ABI you must explicitly define the macro to 0 before including any library headers. (Be aware that some GNU/Linux distributions configure GCC 5 differently so that the default value of the macro is 0 and users must define it to 1 to enable the new ABI.)

So since it was introduced, on most distributions the value was 1.

What I am asking in effect is that for compiler.libcxx=libstdc++11 with GCC9 we should not get a define, and for compiler.libcxx=libstdc++ with GCC9 we should get -D_GLIBCXX_USE_CXX11_ABI=0, otherwise we'll keep adding this define until the end of time ;)

@0x8000-0000
Copy link
Author

This is the bug in clang-tidy: https://bugs.llvm.org/show_bug.cgi?id=42635

@memsharded memsharded added this to the 1.27 milestone May 25, 2020
@danimtb
Copy link
Member

danimtb commented Jun 9, 2020

The problem I see with this is that it may not be evident what is the default value for all the compilers we are supporting including all the versions.

Currently, we adjusting _GLIBCXX_USE_CXX11_ABI=0 or _GLIBCXX_USE_CXX11_ABI=1 for compilers gcc, clang & apple-clang

@0x8000-0000 do you know if we can find this information in the GNU website?

@0x8000-0000
Copy link
Author

The problem I see with this is that it may not be evident what is the default value for all the compilers we are supporting including all the versions.

Currently, we adjusting _GLIBCXX_USE_CXX11_ABI=0 or _GLIBCXX_USE_CXX11_ABI=1 for compilers gcc, clang & apple-clang

@0x8000-0000 do you know if we can find this information in the GNU website?

I don't know, and as documented by the page I linked possible that distributions are setting up the default differently than what upstream has.

The way that the configuration setting was defined in Conan, it is not clear what the plan for sunsetting it is. GCC5 was released 5 years ago, and when it was release the default was to use the new ABI. Perhaps this should have been followed here and users should have had to explicitly select the old ABI, and by default to follow what the compiler is doing by default.

With the current semantic of compiler.libcxx, I am forced to make a choice, and it is possible I'll make the wrong choice.

@danimtb
Copy link
Member

danimtb commented Jun 10, 2020

@0x8000-0000 I understand the hassle of being forced to set compiler.libcxx and it is something you don't worry about in a small project if you are not using Conan. However, as Conan manages the binary compatibility I think this is something to really take into account.

With the lack of information about the defaults, I find it difficult to rely on just the defaults of the compiler and I consider changing this a bit risky for the value. @uilianries @SSE4 WDYT about this topic?

@sourcedelica
Copy link

sourcedelica commented Jun 10, 2020

For gcc you can find out if your compiler was built with _GLIBCXX_USE_CXX11_ABI=0 by running gcc -v and looking for --with-default-libstdcxx-abi=gcc4-compatible. For example:

$ gcc --version
gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6)

$ gcc -v 2>&1 | sed -n 's/.*\(--with-default-libstdcxx-abi=gcc4-compatible\).*/\1/p'
--with-default-libstdcxx-abi=gcc4-compatible

The Red Hat Devtoolset compiler suites continue to use _GLIBCXX_USE_CXX11_ABI=0 all the way up to gcc 8 for backwards compatibility. For example:

$ gcc --version
gcc (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)

$ gcc -v 2>&1 | sed -n 's/.*\(--with-default-libstdcxx-abi=gcc4-compatible\).*/\1/p'
--with-default-libstdcxx-abi=gcc4-compatible

Devtoolset is very common in Red Hat Enterprise Linux shops.

@danimtb
Copy link
Member

danimtb commented Jun 10, 2020

Thanks a lot for the info @sourcedelica. I still think it is too much for the value and a bit risky to change the definition for the benefit (just a clang-tidy warning, or am I missing something?).

I can only think about something like #5740 to improve this.

@memsharded
Copy link
Member

memsharded commented Jun 30, 2020

The way that the configuration setting was defined in Conan, it is not clear what the plan for sunsetting it is. GCC5 was released 5 years ago, and when it was release the default was to use the new ABI. Perhaps this should have been followed here and users should have had to explicitly select the old ABI, and by default to follow what the compiler is doing by default.

This is not very accurate, and much part of the problem. Specifically this: GCC5 was released 5 years ago, and when it was release the default was to use the new ABI.

GCC5 and even more modern versions, when used in a somewhat older distro, still defaults to libstdc++, not to libstdc++11. This is very unfortunate, but it is the reality, and nothing Conan can do about, but to model the choice of libcxx: https://blog.conan.io/2016/03/22/From-CMake-syntax-to-libstdc++-ABI-incompatibiliy-migrations-are-always-hard.html

With the current semantic of compiler.libcxx, I am forced to make a choice, and it is possible I'll make the wrong choice.

Yes, as explained above, because it is not a constant default, it really changes from platform to platform, distro to distro, so the only way is to making it a choice.

Summary: I agree with @danimtb, definitely this is too much of a risk. Conan not passing _GLIBCXX_USE_CXX11_ABI will cause many ABI incompatibilities for many compilers, and at the moment it is almost impossible to know which compiler in which distros have this as the default or not. As the request is related to a warning of clang-tidy, it doesn't seem worth the risk (almost a certainty) of breaking hundreds of Conan users.

@memsharded memsharded removed this from the 1.27 milestone Jun 30, 2020
@sourcedelica
Copy link

Hi @danimtb - I’m not looking for a change. I agree with the current approach. I was just providing a datapoint - that the old ABI is still in use and probably will be indefinitely on Red Hat Enterprise.

@0x8000-0000
Copy link
Author

My question is, why am I getting this flag when building on Ubuntu? I understand it to be set when building on RedHat with their official compilers.

The point is, for the benefit of a single distro (admittedly with a large influence) we're adding this macro to build systems everywhere until the end of time.

@memsharded
Copy link
Member

My question is, why am I getting this flag when building on Ubuntu? I understand it to be set when building on RedHat with their official compilers.

Because Conan by default, does not manage or model the different distros. It is possible to do it and add custom settings to represent different distros, but it is not built-in. As such, the only safe way is to provide always the flag and switch the 1 or 0 value. We haven't find any docs out there where setting _GLIBCXX_USE_CXX11_ABI=1 was discouraged.

@0x8000-0000
Copy link
Author

My question is, why am I getting this flag when building on Ubuntu? I understand it to be set when building on RedHat with their official compilers.

Because Conan by default, does not manage or model the different distros. It is possible to do it and add custom settings to represent different distros, but it is not built-in. As such, the only safe way is to provide always the flag and switch the 1 or 0 value. We haven't find any docs out there where setting _GLIBCXX_USE_CXX11_ABI=1 was discouraged.

Actually, in the enterprise case this is a needed feature. We're just running into this where we have to build and package the same application for several versions of Ubuntu/SuSE/RHEL. We can definitely add the setting, but it would be handy for Conan to automatically identify the distribution and create a different binary package - this is more relevant for the GLIBC even since the ancient RHEL stil supported is missing certain functions added in more recent GLIBC versions. And packages that we built with Conan can definitely adapt, but it is surprising if somebody downloads a package built on newer Ubuntu, links against it on RHEL then the application fails to start due to missing symbols.

@memsharded
Copy link
Member

#8457, that is intended for next Conan releases, will invert the logic, defining _GLIBCXX_USE_CXX11_ABI=0 only when compiler.libcxx=libstdc++, but not the other way round, as _GLIBCXX_USE_CXX11_ABI=1 is now the default by gcc. If this needs to be changed, we can introduce a new [conf] for tools.gnu

@memsharded
Copy link
Member

After seeing that CMakeToolchain is settings GLIBCXX_USE_CXX11_ABI=11, I came to revisit this.

The concerning bit is this:

(Be aware that some GNU/Linux distributions configure GCC 5 differently so that the default value of the macro is 0 and users must define it to 1 to enable the new ABI.)

from (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)

So this means that some Linux distros do really need GLIBCXX_USE_CXX11_ABI=11 defined, and Conan would be doing the safe thing, redundant in some cases, but safer than not defining and getting the wrong ABI.

It seems that https://bugs.llvm.org/show_bug.cgi?id=42635 was fixed, so if this is not an issue anymore, what Conan should do by default?

@0x8000-0000
Copy link
Author

It might be useful to have a survey of supported distributions to see how many build by default with _GLIBCXX_USE_CXX11_ABI=0 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants