Linux下C++编译Protobuf时链接失败问题求助
Protobuf C++链接错误解决
问题场景
编写极简Protobuf C++示例时遭遇链接错误,尝试显式指定库路径等操作均无法解决问题。
相关文件与编译步骤
- Proto定义文件
tempproj.proto:
package tempproj; message name { required string first = 1; required string last = 2; }
- 编译Proto文件生成C++代码:
protoc --cpp_out=. tempproj.proto
生成tempproj.pb.h和tempproj.pb.cc文件。
- 测试代码
main.cpp:
#include "tempproj.bh.h" int main(int argc, char** argv) { return 0; }
- 编译测试代码的命令:
g++ -std=gnu++14 -m64 -lprotobuf main.cpp tempproj.pb.cc
即使显式指定库路径:
g++ -std=gnu++14 -m64 -L/usr/lib64 -lprotobuf main.cpp tempproj.pb.cc
仍出现以下链接错误:
/opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o: in function `protobuf_tempproj_2eproto::protobuf_AssignDescriptors()': tempproj.pb.cc:(.text+0xf6): undefined reference to `google::protobuf::internal::AssignDescriptors(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, google::protobuf::internal::MigrationSchema const*, google::protobuf::Message const* const*, unsigned int const*, google::protobuf::MessageFactory*, google::protobuf::Metadata*, google::protobuf::EnumDescriptor const**, google::protobuf::ServiceDescriptor const**)' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o: in function `protobuf_tempproj_2eproto::AddDescriptorsImpl()': tempproj.pb.cc:(.text+0x1a5): undefined reference to `google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o: in function `tempproj::name::SerializeWithCachedSizes(google::protobuf::io::CodedOutputStream*) const': tempproj.pb.cc:(.text+0xcb9): 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*)' /opt/rh/gcc-toolset-11/root/usr/bin/ld: tempproj.pb.cc:(.text+0xd24): 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*)' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o: in function `google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11]()': tempproj.pb.cc:(.text._ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev[_ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev]+0x5): undefined reference to `google::protobuf::internal::fixed_address_empty_string[abi:cxx11]' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o: in function `google::protobuf::internal::WireFormatLite::ReadString(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)': tempproj.pb.cc:(.text._ZN6google8protobuf8internal14WireFormatLite10ReadStringEPNS0_2io16CodedInputStreamEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14WireFormatLite10ReadStringEPNS0_2io16CodedInputStreamEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x1f): undefined reference to `google::protobuf::internal::WireFormatLite::ReadBytes(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o: in function `google::protobuf::internal::WireFormatLite::WriteStringToArray(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*)': tempproj.pb.cc:(.text._ZN6google8protobuf8internal14WireFormatLite18WriteStringToArrayEiRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPh[_ZN6google8protobuf8internal14WireFormatLite18WriteStringToArrayEiRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPh]+0x39): undefined reference to `google::protobuf::io::CodedOutputStream::WriteStringWithSizeToArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*)' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o:(.rodata._ZTVN8tempproj4nameE[_ZTVN8tempproj4nameE]+0x20): undefined reference to `google::protobuf::Message::GetTypeName[abi:cxx11]() const' /opt/rh/gcc-toolset-11/root/usr/bin/ld: /tmp/ccj7rSmF.o:(.rodata._ZTVN8tempproj4nameE[_ZTVN8tempproj4nameE]+0x58): undefined reference to `google::protobuf::Message::InitializationErrorString[abi:cxx11]() const' collect2: error: ld returned 1 exit status
环境说明:使用EL8系统,gcc-toolset-11(g++ 11.2.1),头文件路径为/usr/include,库文件路径为/usr/lib64。
解决方法
编译时添加-D_GLIBCXX_USE_CXX11_ABI=0选项,命令如下:
g++ -std=gnu++14 -m64 -D_GLIBCXX_USE_CXX11_ABI=0 -lprotobuf main.cpp tempproj.pb.cc
原因说明
GCC 5及后续版本默认启用了新的C++11 ABI(基于std::__cxx11命名空间),而系统预装的Protobuf库是用旧ABI编译的。两者ABI不兼容,导致链接时无法找到匹配的符号。添加该编译选项可强制编译器使用旧ABI,与系统库的ABI保持一致,从而解决链接错误。
内容的提问来源于stack exchange,提问作者basil
相关产品推荐
相关产品推荐

