Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to google::protobuf::internal::empty_string_[abi:cxx11]

Tags:

I'm trying to build simple test application with Protocol Buffers 2.6.1 and GNU GCC 5.1.0 (on Ubuntu 14.10) and I get following errors:

/home/ragnar/cpp-tools/gcc-linux/bin/g++   -c  "/home/ragnar/cpp-projects/gprotobuf_test/main.cpp" -g -O0 -Wall   -o ./Debug/main.cpp.o -I. -I/home/ragnar/cpp-tools/libs/linux64/protobuf/include -I. /home/ragnar/cpp-tools/gcc-linux/bin/g++   -c  "/home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc" -g -O0 -Wall   -o ./Debug/messages.pb.cc.o -I. -I/home/ragnar/cpp-tools/libs/linux64/protobuf/include -I.   /home/ragnar/cpp-tools/gcc-linux/bin/g++  -o ./Debug/gprotobuf_test @"gprotobuf_test.txt" -L. -L/home/ragnar/cpp-tools/libs/linux64/protobuf/lib  -lprotobuf   ./Debug/main.cpp.o: In function google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11]():     /home/ragnar/cpp-tools/libs/linux64/protobuf/include/google/protobuf/generated_message_util.h:80:      undefined reference to google::protobuf::internal::empty_string_[abi:cxx11]     /home/ragnar/cpp-tools/libs/linux64/protobuf/include/google/protobuf/generated_message_util.h:81:      undefined reference to google::protobuf::internal::empty_string_[abi:cxx11]   ./Debug/messages.pb.cc.o: In function protobuf_AssignDesc_messages_2eproto():     /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:32:      undefined reference to google::protobuf::DescriptorPool::FindFileByName(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const   ./Debug/messages.pb.cc.o: In function protobuf_AddDesc_messages_2eproto():     /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:83:      undefined reference to google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))   ./Debug/messages.pb.cc.o: In function my_message::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*):   /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:187:      undefined reference to google::protobuf::internal::WireFormatLite::ReadString(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)   ./Debug/messages.pb.cc.o: In function my_message::SerializeWithCachedSizes(google::protobuf::io::CodedOutputStream*) const:   /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:247:      undefined reference to google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, google::protobuf::io::CodedOutputStream*)   ./Debug/messages.pb.cc.o: In function google::protobuf::internal::WireFormatLite::WriteStringToArray(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*):   /home/ragnar/cpp-tools/libs/linux64/protobuf/include/google/protobuf/wire_format_lite_inl.h:749:      undefined reference to google::protobuf::io::CodedOutputStream::WriteStringWithSizeToArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*)   ./Debug/messages.pb.cc.o:(.rodata._ZTV10my_message[_ZTV10my_message]+0x20):      undefined reference to google::protobuf::Message::GetTypeName[abi:cxx11]() const    ./Debug/messages.pb.cc.o:(.rodata._ZTV10my_message[_ZTV10my_message]+0x40):      undefined reference to google::protobuf::Message::InitializationErrorString[abi:cxx11]() const   collect2: error: ld returned 1 exit status   gprotobuf_test.mk:93: recipe for target "Debug/gprotobuf_test" failed   make[1]: *** [Debug/gprotobuf_test] Error 1   make[1]: Leaving directory "/home/ragnar/cpp-projects/gprotobuf_test"   Makefile:4: recipe for target "All" failed   make: *** [All] Error 2   

The /home/ragnar/cpp-tools/libs/linux64/protobuf/lib contains following libraries:

libprotobuf.a   libprotobuf.so.9.0.1   libprotobuf-lite.a   libprotobuf-lite.so.9.0.1   libprotoc.a   libprotoc.so.9.0.1   

Here's the simple messages.proto file:

option java_package = "my.package";  message my_message {   required string word = 1;   required uint32 number = 2; } 

and the code I'm trying to get working:

#include <iostream> #include <vector> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include "messages.pb.h"  std::vector<unsigned char> encode( google::protobuf::Message & msg ) {   std::vector<unsigned char> data( msg.ByteSize() +      google::protobuf::io::CodedOutputStream::VarintSize32( msg.ByteSize() ) );   google::protobuf::io::ArrayOutputStream array_out( &data[0], data.size() );   google::protobuf::io::CodedOutputStream coded_out( &array_out );   coded_out.WriteVarint32( msg.ByteSize() );   msg.SerializeToCodedStream( &coded_out );   return data; }  void decode( const std::vector<unsigned char> & data, google::protobuf::Message & msg ) {   google::protobuf::io::ArrayInputStream array_in( &data[0] , data.size() );   google::protobuf::io::CodedInputStream coded_in( &array_in );   google::protobuf::uint32 size;   coded_in.ReadVarint32( &size );   google::protobuf::io::CodedInputStream::Limit msg_limit = coded_in.PushLimit( size );   msg.ParseFromCodedStream( &coded_in );   coded_in.PopLimit( msg_limit ); }  int main(int argc, char **argv) {   my_message in_msg;   in_msg.set_word( \"blah blah\" );   in_msg.set_number( 123 );   std::vector<unsigned char> data = encode( in_msg );    my_message out_msg;   decode( data, out_msg );   std::cout << \"word: \" << out_msg.word() << \" number: \" << out_msg.number() << std::endl;   return 0; } 

Gcc is built from source with following options:

--enable-64bit --enable-32bit --enable-languages=c,c++ --enable-multilib --disable-nls --enable-threads=posix --enable-checking=release --enable-lto --enable-multiarch --with-multilib-list=m32,m64,mx32  --with-tune=generic --enable-shared --with-glibc-version=2.13 --enable-libstdcxx-time=rt 

and Protobuf is built from source with following options:

--enable-64it --disable-32bit --enable-shared CXXFLAGS=-m64 -DNDEBUG LDFLAGS=-m64 

Any help would be greatly appreciated.

like image 462
Ragnar Avatar asked May 08 '15 12:05

Ragnar


People also ask

How do I check Protobuf version?

To check which version of the Python library protobuf is installed, run pip show protobuf or pip3 show protobuf in your CMD/Powershell (Windows), or terminal (macOS/Linux/Ubuntu).

What is Google Protobuf message?

namespace google::protobuf. Defines Message, the abstract interface implemented by non-lite protocol message objects. Although it's possible to implement this interface manually, most users will use the protocol compiler to generate implementations.


2 Answers

I suspect this is a C++ ABI issue. The ABI for std::string has changed in GCC 5 (related to C++11 requirements, but it applies even if you aren't using C++11). See:

https://gcc.gnu.org/gcc-5/changes.html#libstdcxx

If libprotobuf was built with GCC 4.x or prior, but your app is built with GCC 5, then you will see problems, because libprotobuf uses std::string in its interface. You have two options:

  1. Rebuild libprotobuf with GCC 5 (but now any apps built with GCC 4 won't work with the new version of libprotobuf).
  2. Build you app with -D_GLIBCXX_USE_CXX11_ABI=0 as described at the above link. This will force GCC to use the old ABI version.
like image 192
Kenton Varda Avatar answered Oct 27 '22 19:10

Kenton Varda


I had similar problem as

writeProto.cpp:(.text+0x2a8): undefined reference to `google::protobuf::internal::VerifyVersion(int, int, char const*)' writeProto.cpp:(.text+0x308): undefined reference to `tutorial::AddressBook::AddressBook()' writeProto.cpp:(.text+0x3a2): undefined reference to `google::protobuf::Message::ParseFromIstream(std::istream*)' writeProto.cpp:(.text+0x463): undefined reference to `google::protobuf::Message::SerializeToOstream(std::ostream*) const' writeProto.cpp:(.text+0x4b4): undefined reference to `google::protobuf::ShutdownProtobufLibrary()' writeProto.cpp:(.text+0x4c8): undefined reference to `tutorial::AddressBook::~AddressBook()' writeProto.cpp:(.text+0x515): undefined reference to `tutorial::AddressBook::~AddressBook()' 

I wrote this on the command line and now my code is working.

c++ writeProto.cpp addressbook.pb.cc `pkg-config --cflags --libs protobuf` 
like image 28
Akanksha Gupta Avatar answered Oct 27 '22 17:10

Akanksha Gupta