Coming from https://github.com/conan-io/conan-center-index/issues/1091
I have looked for more information regarding libstdc++11 and clang in Linux and I did not found anything in the documentation, only this that I suppose is related to the libc++ version 11 (not the same thing) https://libcxx.llvm.org/docs/index.html
And https://clang.llvm.org/cxx_status.html states:
Clang's C++11 mode can be used with libc++ or with gcc's libstdc++
Regarding Conan, libstdc++11 was introduced in the clang settings at https://github.com/conan-io/conan/pull/185 and the compiler flags used for that libstdc++11 sub-setting are:
_GLIBCXX_USE_CXX11_ABI=1-stdlib=libstdc++ (same flag for compiler.libcxx=libstdc++)But I don't know if the definition _GLIBCXX_USE_CXX11_ABI=1 is taken into account by the clang compiler the same way it works for GCC.
So I have a couple of questions:
libstdc++11 a real thing in Linux clang?libstdc++ ABI compatible withlibstdc++11?The answer to the first question is yes, we are currently using it exactly as described. The second question I'm a bit confused about, can you clarify what you meant by libstdc++ ABI?
There are this values available for linux clang libcxx: [libstdc++, libstdc++11, libc++]. The one I see recommended (as apple-clang deprecated libstdc++) is using libc++. So my second question is about: Is there any real difference between libstdc++ and libstdc++11 in Conan?
yes, this is a real thing on Linux clang.
for instance, compiling gtest's test_package:
> conan profile show default
[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=clang
compiler.version=7.0
compiler.libcxx=libstdc++
build_type=Release
[options]
[build_requires]
[env]
> conan create . gtest/1.10.0@ -k -s gtest:compiler=clang -s gtest:compiler.libcxx=libstdc++11
will result in many undefined references:
/usr/bin/ld: CMakeFiles/test_package.dir/test_package.cpp.o: in function `testing::internal::FunctionMocker<void ()>::DescribeDefaultActionTo(std::tuple<> const&, std::ostream*) const':
test_package.cpp:(.text._ZNK7testing8internal14FunctionMockerIFvvEE23DescribeDefaultActionToERKSt5tupleIJEEPSo[_ZNK7testing8internal14FunctionMockerIFvvEE23DescribeDefaultActionToERKSt5tupleIJEEPSo]+0x7b): undefined reference to `testing::internal::FormatFileLocation(char const*, int)'
/usr/bin/ld: CMakeFiles/test_package.dir/test_package.cpp.o: in function `testing::internal::ExpectationBase::DescribeLocationTo(std::ostream*) const':
test_package.cpp:(.text._ZNK7testing8internal15ExpectationBase18DescribeLocationToEPSo[_ZNK7testing8internal15ExpectationBase18DescribeLocationToEPSo]+0x15): undefined reference to `testing::internal::FormatFileLocation(char const*, int)'
/usr/bin/ld: CMakeFiles/test_package.dir/test_package.cpp.o: in function `testing::internal::TypedExpectation<void ()>::GetCurrentAction(testing::internal::FunctionMocker<void ()> const*, std::tuple<> const&) const':
test_package.cpp:(.text._ZNK7testing8internal16TypedExpectationIFvvEE16GetCurrentActionEPKNS0_14FunctionMockerIS2_EERKSt5tupleIJEE[_ZNK7testing8internal16TypedExpectationIFvvEE16GetCurrentActionEPKNS0_14FunctionMockerIS2_EERKSt5tupleIJEE]+0x1f1): undefined reference to `testing::internal::Log(testing::internal::LogSeverity, std::string const&, int)'
/usr/bin/ld: CMakeFiles/test_package.dir/test_package.cpp.o: in function `testing::AssertionResult testing::internal::CmpHelperEQFailure<std::string, std::string>(char const*, char const*, std::string const&, std::string const&)':
test_package.cpp:(.text._ZN7testing8internal18CmpHelperEQFailureISsSsEENS_15AssertionResultEPKcS4_RKT_RKT0_[_ZN7testing8internal18CmpHelperEQFailureISsSsEENS_15AssertionResultEPKcS4_RKT_RKT0_]+0x53): undefined reference to `testing::internal::EqFailure(char const*, char const*, std::string const&, std::string const&, bool)'
/usr/bin/ld: CMakeFiles/test_package.dir/test_package.cpp.o: in function `std::string testing::internal::FormatForComparisonFailureMessage<std::string, std::string>(std::string const&, std::string const&)':
test_package.cpp:(.text._ZN7testing8internal33FormatForComparisonFailureMessageISsSsEESsRKT_RKT0_[_ZN7testing8internal33FormatForComparisonFailureMessageISsSsEESsRKT_RKT0_]+0x28): undefined reference to `testing::internal::PrintStringTo(std::string const&, std::ostream*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [CMakeFiles/test_package.dir/build.make:87: bin/test_package] Error 1
make[2]: Leaving directory '/host/bincrafters/conan-center-index/recipes/gtest/all/test_package/build/4d1f2b88e556e5c9d1eb252fd8f04c07ef071ce3'
make[1]: *** [CMakeFiles/Makefile2:79: CMakeFiles/test_package.dir/all] Error 2
make[1]: Leaving directory '/host/bincrafters/conan-center-index/recipes/gtest/all/test_package/build/4d1f2b88e556e5c9d1eb252fd8f04c07ef071ce3'
make: *** [Makefile:87: all] Error 2
thus, libstdc++ and libstdc++11 packages aren't ABI compatible, for Clang as well.
libgtest.a contains different symbols in these two configurations (libstdc++ vs libstdc++11):
00000000000064b0 T testing::internal::StringStreamToString(std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >*)
00000000000055d0 T testing::internal::StringStreamToString(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >*)
the _GLIBCXX_USE_CXX11_ABI definition is "taken by account by the compiler". the compiler here doesn't matter - it's the same for any compiler using libstdc++: GCC, Clang, Intel, etc.
this is standard library itself (libstdc++) with its headers the one who is enabling different code according to the _GLIBCXX_USE_CXX11_ABI - either std::basic_stringstream or std::__cxx11::basic_stringstream.
the macro is documented here https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
as said above, it has nothing to do with the particular compiler, it's standard library implementation detail
@SSE4 Thanks a lot for the clarification. I would like to have this documented in the settings page of Conan documentation!
Just a final question regarding this issue and apple-clang. Apple-clang deprecated libstdc++ in favor of libc++ flag. Does the usage of libc++imply _GLIBCXX_USE_CXX11_ABI=1 as well?
libc++ doesn't have dual abi and doesn't have _GLIBCXX_USE_CXX11_ABI. the flag has no effect on libc++ builds at all, it means build with no _GLIBCXX_USE_CXX11_ABI defined, build with _GLIBCXX_USE_CXX11_ABI=0 and build _GLIBCXX_USE_CXX11_ABI=1 are absolutely identical. that's why we don't have libc++ and libc++11 I guess.
@danimtb seems like everything is already documented here: https://github.com/conan-io/docs/blob/6531ce7bc1a83e81e78af1b0318d3fbd69c28f20/howtos/manage_gcc_abi.rst
I would like to have it documented here as well https://docs.conan.io/en/latest/reference/config_files/settings.yml.html so we can keep adding the different meanings of the values used for different compilers as well
libc++doesn't have dual abi and doesn't have_GLIBCXX_USE_CXX11_ABI. the flag has no effect onlibc++builds at all, it means build with no_GLIBCXX_USE_CXX11_ABIdefined, build with_GLIBCXX_USE_CXX11_ABI=0and build_GLIBCXX_USE_CXX11_ABI=1are absolutely identical. that's why we don't havelibc++andlibc++11I guess.
Yeah, libc++ did not break the ABI because it was created for C++11.
- Is the
libstdc++11a real thing in Linux clang?
Yes, it is a real thing.
- Are Conan packages using
libstdc++ABI compatible withlibstdc++11?
They are compatible as long as you don't use any of the standard library components that broke compatibility.
Most helpful comment
yes, this is a real thing on Linux clang.
for instance, compiling gtest's test_package:
will result in many undefined references:
thus, libstdc++ and libstdc++11 packages aren't ABI compatible, for Clang as well.
libgtest.a contains different symbols in these two configurations (libstdc++ vs libstdc++11):
the
_GLIBCXX_USE_CXX11_ABIdefinition is "taken by account by the compiler". the compiler here doesn't matter - it's the same for any compiler using libstdc++: GCC, Clang, Intel, etc.this is standard library itself (libstdc++) with its headers the one who is enabling different code according to the
_GLIBCXX_USE_CXX11_ABI- either std::basic_stringstream or std::__cxx11::basic_stringstream.the macro is documented here https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
as said above, it has nothing to do with the particular compiler, it's standard library implementation detail