简体   繁体   English

无法从谷歌协议缓冲区编译示例

[英]Can't compile example from google protocol buffers

I grep for other topics, but they dont help me =(. On my working server, i have no sudo privilegies, so i install PB with我搜索其他主题,但它们对我没有帮助 =(。在我的工作服务器上,我没有 sudo 权限,所以我安装了 PB

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

Then i create source files with "person" example and succesfully compile it with protoc.然后我用“person”示例创建源文件并成功地用 protoc 编译它。

I have no pkg-info =(. I try to compile it with我没有 pkg​​-info =(。我试着用

g++ -I /home/username/local/include -L /home/username/local/lib -lprotobuf -lpthread main.cpp person.pb.cc 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 ie然后有十亿个模拟错误,即

person.pb.cc:(.text+0x4cf): undefined reference to `google::protobuf::internal::kEmptyString' person.pb.cc:(.text+0x4cf):对`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 echo $LD_LIBRARY_PATH /home/username/local/lib

in main.cpp:在 main.cpp 中:

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

Thanks.谢谢。

Put the library at the end:将库放在最后:

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

From GCC Link Options :GCC 链接选项

-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.此外,使用-pthread而不是-lpthread因为-pthread可能会为预处理器和链接器设置标志。

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 g++ -I /home/username/local/include -L /home/username/local/lib main.cpp person.pb.cc -lprotobuf -lpthread

There is also quite general problem that does not apply exclusively to linking protobuf but other libraries as well.还有一个非常普遍的问题,不仅适用于链接 protobuf,也适用于其他库。 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.确保您尝试链接到具有相同 ABI 的库。 C++ ABI has changed in GCC 4.7.0. C++ ABI 在 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.因此,您不能将使用 GCC<4.7.0 编译的库(如果您像我的情况一样从包存储库中获取包,则可能是 protobuf)与使用 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++.这个问题可以通过让植物链接抱怨 std::basic_string 和 std::list 来识别,因为这是 C++ 中最突出的 ABI 变化。 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.在我为 conan 定义了一个配置文件并链接到使用相同版本的 C++ ABI 编译的库后,问题就消失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM