Problems linking C++17 app agains old protobuf

68 views
Skip to first unread message

Edgar Neubauer

unread,
Jul 10, 2024, 2:12:44 PM (8 days ago) Jul 10
to Protocol Buffers
Greetings,

I try to link a C++17 app previously built with g++ 12 for c++17 now with clang++-17 and libc++ against an 3.18.2 protobuf version which is required. However, some of the app headers produce linker errors like these:

config.hpp:69: undefined reference to `google::protobuf::MessageLite::ParseFromIstream(std::__1::basic_istream<char, std::__1::char_traits<char> >*)'

As far as I know std::__1 is C++11, in 17 it's std::placeholders::__1 .
Can this be explained by protobuf being built against std=c++11 and the app against 17?
I tried to switch everything in protobuf configure.ac to c++17 It seems  to me that libprotobuf.so.29.0.2, libprotoc.so.29.0.2: and libprotobuf-lite.so.29.0.2 still have c++11 symbols.

Any ideas?

Regards

Samuel Benzaquen

unread,
Jul 10, 2024, 6:22:19 PM (8 days ago) Jul 10
to Edgar Neubauer, Protocol Buffers
On Wed, Jul 10, 2024 at 2:12 PM 'Edgar Neubauer' via Protocol Buffers <prot...@googlegroups.com> wrote:
Greetings,

I try to link a C++17 app previously built with g++ 12 for c++17 now with clang++-17 and libc++ against an 3.18.2 protobuf version which is required. However, some of the app headers produce linker errors like these:

Version 3.18 is pretty old and no longer supported.
 

config.hpp:69: undefined reference to `google::protobuf::MessageLite::ParseFromIstream(std::__1::basic_istream<char, std::__1::char_traits<char> >*)'

As far as I know std::__1 is C++11, in 17 it's std::placeholders::__1 .

`__1` is an internal inline namespace used by the standard library to add a unique mangled name when they change the ABI.
For example, when using the unstable ABI in libc++ they use `__u` instead.
It is not related to the placeholders. Note that it has two underscores.
 
Can this be explained by protobuf being built against std=c++11 and the app against 17?
I tried to switch everything in protobuf configure.ac to c++17 It seems  to me that libprotobuf.so.29.0.2, libprotoc.so.29.0.2: and libprotobuf-lite.so.29.0.2 still have c++11 symbols.

I don't think the language version is the issue. This sounds like you are mixing libraries.
Like you are compiling part of your program against one version of the standard library (eg libc++ from clang) and other parts with another standard library (eg libstdc++ from gcc).
Mixing standard libraries is not generally supported since they have different ABIs.
You have to make sure that every library in your binary is built against the same standard library, with the same compiler options.
 


Any ideas?

Regards

--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to protobuf+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/protobuf/25092f8f-8040-494b-b657-a904103c6879n%40googlegroups.com.

Edgar Neubauer

unread,
Jul 11, 2024, 2:24:08 AM (8 days ago) Jul 11
to Protocol Buffers
Thanks for your response. Some of the external libraries come prebuilt probably with libstdc++ there should be some way to mix this with the rest of the program otherwise it would be difficult for every larger project, right?

Samuel Benzaquen

unread,
Jul 11, 2024, 10:03:21 AM (7 days ago) Jul 11
to Edgar Neubauer, Protocol Buffers
On Thu, Jul 11, 2024 at 2:24 AM 'Edgar Neubauer' via Protocol Buffers <prot...@googlegroups.com> wrote:
Thanks for your response. Some of the external libraries come prebuilt probably with libstdc++ there should be some way to mix this with the rest of the program otherwise it would be difficult for every larger project, right?

Sadly, that is not how it works in C++.
If you use any library as part of your ABI (eg in your headers) then everyone that deals with that ABI has to agree on it and should use ABI compatible versions of the library.
This is unrelated to protobuf and could happen with any other library you use.

Standard library vendors tend to maintain ABI compatibility within their own libraries even between versions for this kind of thing, but there's no such compatibility between separate implementations of the standard library.

Imagine the simplest API that does something like:

void Foo(std::string_view bar);

If standard library A implements string_view as `ptr,size` and standard library B implements it as `size,ptr` (or `begin,end`, etc) then mixing them up will make the caller and the callee disagree on where the data is in the string_view parameter and what it represents.
To avoid this kind of undefined behavior at runtime they push the ABI into the name of the type (ie the inline namespace). That way if the caller/callee disagree on the ABI you get a link time failure instead of runtime brokenness.
 
Message has been deleted

Edgar Neubauer

unread,
Jul 11, 2024, 2:59:44 PM (7 days ago) Jul 11
to Protocol Buffers

Edgar Neubauer
ungelesen,
20:58 (jetzt) 
an Protocol Buffers
Ok, I built protobuf now with these flags:

         export CXXFLAGS="-O3 -I/home/user/instrumentedlibcpp/llvm-project/msan_out/include -I/home/user/instrumentedlibcpp/llvm-project/msan_out/include/c++/v1"
         export CC="clang-17"
         export CXX="clang++-17 -std=c++17 -stdlib=libc++"
         export LDFLAGS="-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer  -L/home/user/instrumentedlibcpp/llvm-project/msan_out/lib" 

It doesn't seem to link agains libstdc++.so anymore. But I still get errors in the final link:

From linking .a file:

(.data.rel.ro+0x20): undefined reference to `google::protobuf::Message::GetTypeName[abi:cxx11]() const'

Am I missing something?
Reply all
Reply to author
Forward
0 new messages