Conan: [question] Is libstdc++11 used in Linux clang?

Created on 12 May 2020  路  9Comments  路  Source: conan-io/conan

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:

  • Set compiler definition _GLIBCXX_USE_CXX11_ABI=1
  • Set compiler flag -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:

  • Is the libstdc++11 a real thing in Linux clang?
  • Are Conan packages using libstdc++ ABI compatible withlibstdc++11?
Feedback please! medium medium queue look into question

Most helpful comment

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

All 9 comments

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.

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 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.

Yeah, libc++ did not break the ABI because it was created for C++11.

  • Is the libstdc++11 a 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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zlalanne picture zlalanne  路  3Comments

rconde01 picture rconde01  路  3Comments

theodelrieu picture theodelrieu  路  3Comments

liberforce picture liberforce  路  3Comments

zomeck picture zomeck  路  3Comments