12
votes

I grep for other topics, but they dont help me =(. On my working server, i have no sudo privilegies, so i install PB with

./configure --prefix=/home/username/local

Then i create source files with "person" example and succesfully compile it with protoc.

I have no pkg-info =(. I try to compile it with

g++ -I /home/username/local/include -L /home/username/local/lib -lprotobuf -lpthread main.cpp person.pb.cc

and then have a billion simular errors i.e.

person.pb.cc:(.text+0x4cf): undefined reference to `google::protobuf::internal::kEmptyString'

I think, that it is a problem with linking, but how to solve it?

echo $LD_LIBRARY_PATH /home/username/local/lib

in main.cpp:

#include "person.pb.h"
...

Thanks.

3

3 Answers

22
votes

Put the library at the end:

g++ -I /home/username/local/include -L /home/username/local/lib main.cpp person.pb.cc -lprotobuf -pthread

From GCC Link Options:

-llibrary
-l library
    Search the library named library when linking. 
    (The second alternative with the library as a separate argument
    is only for POSIX compliance and is not recommended.)

    It makes a difference where in the command you write this option;
    the linker searches and processes libraries and object files in the
    order they are specified.
    Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but
    before bar.o. If bar.o refers to functions in `z', those functions
    may not be loaded.

Also, use -pthread instead of -lpthread as -pthread may set flags for preprocessor and linker.

2
votes

Library linking flags go at the end of the compiler's arguments:

g++ -I /home/username/local/include -L /home/username/local/lib main.cpp person.pb.cc -lprotobuf -lpthread

-1
votes

There is also quite general problem that does not apply exclusively to linking protobuf but other libraries as well. Since it was my issue I'll put the solution here, maybe someone find it useful.

Make sure that you are trying to link to a library with the same ABI. C++ ABI has changed in GCC 4.7.0. So you cannot link a library that was compiled with GCC<4.7.0 (that may be protobuf if you fetch package from a package repository as it was in my case) with your library compiled with GCC>4.7.0.

The issue may be recognized by having planty linkage complains about std::basic_string and std::list as this was most prominet ABI changes in C++. My linker screams looked like this:

    /bincrafters/stable/package/c0c1ef10e3d0ded44179e28b669d6aed0277ca6a/lib  -L/home/adam/.conan/data/libpcap/1.8.1/bincrafters/stable/package/0a813c597d519ec14c71192b99d7de0a92bbc1c3/lib  -L/home/adam/.conan/data/zmq/4.2.2/bincrafters/stable/package/0144a3b0aceb8edb5e63295c432a8de8020ab1b7/lib  -L/home/adam/.conan/data/libsodium/1.0.16/bincrafters/stable/package/db2ca884c9793e0b0fb54ec3f846326d1addacc8/lib -Wl,-rpath,/hoar, std::char_traits<char>, std::allocator<char> > const&, google::protobuf::io::CodedOutputStream*)'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o: In function `tutorial::Person_PhoneNumber::InternalSerializeWithCachedSizesToArray(unsigned char*) const':
/home/adam/.conan/data/protobuf/3.9.1/bincrafters/stable/package/053ea29eb0edc6b1695c893b738a971110c756fd/include/google/protobuf/wire_format_lite.h:1673: undefined reference to `google::protobuf::io::CodedOutputStream::WriteStringWithSizeToArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*)'
/home/adam/.conan/data/protobuf/3.9.1/bincrafters/stable/package/053ea29eb0edc6b1695c893b738a971110c756fd/include/google/protobuf/wire_format_lite.h:1673: undefined reference to `google::protobuf::io::CodedOutputStream::WriteStringWithSizeToArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*)'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o: In function `google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11]()':
/home/adam/.conan/data/protobuf/3.9.1/bincrafters/stable/package/053ea29eb0edc6b1695c893b738a971110c756fd/include/google/protobuf/message_lite.h:153: undefined reference to `google::protobuf::internal::fixed_address_empty_string[abi:cxx11]'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o: In function `google::protobuf::internal::WireFormatLite::ReadString(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)':
/home/adam/.conan/data/protobuf/3.9.1/bincrafters/stable/package/053ea29eb0edc6b1695c893b738a971110c756fd/include/google/protobuf/wire_format_lite.h:880: undefined reference to `google::protobuf::internal::WireFormatLite::ReadBytes(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o:(.data.rel.ro._ZTVN8tutorial11AddressBookE[_ZTVN8tutorial11AddressBookE]+0x20): undefined reference to `google::protobuf::Message::GetTypeName[abi:cxx11]() const'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o:(.data.rel.ro._ZTVN8tutorial11AddressBookE[_ZTVN8tutorial11AddressBookE]+0x58): undefined reference to `google::protobuf::Message::InitializationErrorString[abi:cxx11]() const'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o:(.data.rel.ro._ZTVN8tutorial6PersonE[_ZTVN8tutorial6PersonE]+0x20): undefined reference to `google::protobuf::Message::GetTypeName[abi:cxx11]() const'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o:(.data.rel.ro._ZTVN8tutorial6PersonE[_ZTVN8tutorial6PersonE]+0x58): undefined reference to `google::protobuf::Message::InitializationErrorString[abi:cxx11]() const'
CMakeFiles/NetworkMonitor.dir/addressbook.pb.cc.o:(.data.rel.ro._ZTVN8tutorial18Person_PhoneNumberE[_ZTVN8tutorial18Person_PhoneNumberE]+0x20): undefined reference to `google::protobuf::Message::GetTypeName[abi:cxx11]() const'
make[2]: *** [bin/N

The issue was gone after I defined a profile for conan and link with libraries compiled with the same version of C++ ABI.