解决protobuf编译过程中【对‘google::protobuf:: ....... [abi:cxx11]() const’未定义的引用】的问题思路

前言

  此处,是本人在学习 protobuf 时所触发的错误,并不全面,但认为是一个极其珍惜的错误(错误最终不在 protobuf 库的版本问题)(走了很多岔路😢😢😢)

思路

  首先,错误如下:

[qcr@VM-16-6-centos Learn_protoBuf]$ make
g++ -o write write.cc contacts.pb.cc -std=c++11 -lprotobuf
/tmp/ccmCcLHl.o: In function `google::protobuf::Any* google::protobuf::MessageLite::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)':
write.cc:(.text._ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE[_ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE]+0x14): undefined reference to `google::protobuf::Any* google::protobuf::Arena::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)'
collect2: error: ld returned 1 exit status
make: *** [write] Error 1
  • 重点在于
  • google::protobuf::Arena::CreateMaybeMessage<google::protobuf::Any(google::protobuf::Arena*) 连接过程中找不到导致的。
      所以,首先怀疑:这可能是由于链接时没有包含正确的 protobuf 库或者 protobuf 版本不匹配引起的。

1.确保 protobuf 库已正确安装

pkg-config 是一个用于查询已安装软件包的信息,特别是编译和链接时需要的标志和路径的工具。

pkg-config --modversion protobuf - 获取已安装的 protobuf 库的版本号
pkg-config --cflags protobuf - 获取编译时需要包含的头文件路径和其他编译选项
pkg-config --libs protobuf - 获取链接时需要包含的库文件路径和其他链接选项

  确保这些命令返回正确的值,并且编译命令中包含了正确的 -I(头文件路径)和 -L(库路径)选项,我们可以直接使用。

  • 本人执行:
[qcr@VM-16-6-centos Learn_protoBuf]$ pkg-config --modversion protobuf
3.21.11
[qcr@VM-16-6-centos Learn_protoBuf]$ pkg-config --cflags protobuf
-I/usr/local/protobuf/include
[qcr@VM-16-6-centos Learn_protoBuf]$ pkg-config --libs protobuf
-L/usr/local/protobuf/lib -lprotobuf

  检查protobuf版本: 确保我们的 protobuf 版本与我们的代码兼容。有时,不同版本的 protobuf 会引入一些不同的特性或者更改 API,导致链接错误。

2.是否正确的链接

  至此为了确保链接的是正确版本的protobuf 库,又执行了下述:

[qcr@VM-16-6-centos Learn_protoBuf]$ g++ -o write write.cc -std=c++11 -L/usr/local/protobuf/lib -I/usr/local/protobuf/include -lprotobuf
/tmp/ccf4OU13.o: In function `AddPeopleInfo(contacts::PeopleInfo*)':
write.cc:(.text+0x5dc): undefined reference to `contacts::Address::~Address()'
write.cc:(.text+0x69c): undefined reference to `contacts::Address::~Address()'
/tmp/ccf4OU13.o: In function `main':
write.cc:(.text+0x8a7): undefined reference to `contacts::Contacts::~Contacts()'
write.cc:(.text+0x8e5): undefined reference to `contacts::Contacts::~Contacts()'
/tmp/ccf4OU13.o: In function `contacts::Address::Address()':
write.cc:(.text._ZN8contacts7AddressC2Ev[_ZN8contacts7AddressC5Ev]+0x1e): undefined reference to `contacts::Address::Address(google::protobuf::Arena*, bool)'
/tmp/ccf4OU13.o: In function `contacts::Contacts::Contacts()':
write.cc:(.text._ZN8contacts8ContactsC2Ev[_ZN8contacts8ContactsC5Ev]+0x1e): undefined reference to `contacts::Contacts::Contacts(google::protobuf::Arena*, bool)'
/tmp/ccf4OU13.o: In function `google::protobuf::Any* google::protobuf::MessageLite::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)':
write.cc:(.text._ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE[_ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE]+0x14): undefined reference to `google::protobuf::Any* google::protobuf::Arena::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)'
/tmp/ccf4OU13.o: In function `_ZN8contacts10PeopleInfo6set_qqIRSsIEEEvOT_DpT0_':
write.cc:(.text._ZN8contacts10PeopleInfo6set_qqIRSsIEEEvOT_DpT0_[_ZN8contacts10PeopleInfo6set_qqIRSsIEEEvOT_DpT0_]+0x2b): undefined reference to `contacts::PeopleInfo::clear_other_contact()'
/tmp/ccf4OU13.o: In function `_ZN8contacts10PeopleInfo10set_wechatIRSsIEEEvOT_DpT0_':
write.cc:(.text._ZN8contacts10PeopleInfo10set_wechatIRSsIEEEvOT_DpT0_[_ZN8contacts10PeopleInfo10set_wechatIRSsIEEEvOT_DpT0_]+0x2b): undefined reference to `contacts::PeopleInfo::clear_other_contact()'
/tmp/ccf4OU13.o: In function `google::protobuf::internal::GenericTypeHandler<contacts::Phone>::New(google::protobuf::Arena*)':
write.cc:(.text._ZN6google8protobuf8internal18GenericTypeHandlerIN8contacts5PhoneEE3NewEPNS0_5ArenaE[_ZN6google8protobuf8internal18GenericTypeHandlerIN8contacts5PhoneEE3NewEPNS0_5ArenaE]+0x14): undefined reference to `contacts::Phone* google::protobuf::Arena::CreateMaybeMessage<contacts::Phone>(google::protobuf::Arena*)'
/tmp/ccf4OU13.o: In function `google::protobuf::internal::GenericTypeHandler<contacts::PeopleInfo>::New(google::protobuf::Arena*)':
write.cc:(.text._ZN6google8protobuf8internal18GenericTypeHandlerIN8contacts10PeopleInfoEE3NewEPNS0_5ArenaE[_ZN6google8protobuf8internal18GenericTypeHandlerIN8contacts10PeopleInfoEE3NewEPNS0_5ArenaE]+0x14): undefined reference to `contacts::PeopleInfo* google::protobuf::Arena::CreateMaybeMessage<contacts::PeopleInfo>(google::protobuf::Arena*)'
collect2: error: ld returned 1 exit status

  该死的他还是找不到!!!

3.是否正确的编译

  然后我又回头看他们的各自编译情况是否出错。

  • -Wall 开启一组常见的警告,包括但不限于未使用变量、函数未声明等。它允许编译器发现一些潜在的代码问题,但并不包括所有可能的警告。
  • -Wextra 打开更多的警告,包括一些 -Wall 没有涵盖到的。这可能包括一些更严格的规则,帮助进一步提高代码质量。

write.cc

[qcr@VM-16-6-centos Learn_protoBuf]$ g++ -std=c++11 -c write.cc -o write.o -Wall -Wextra
[qcr@VM-16-6-centos Learn_protoBuf]$ 

contacts.pb.cc

[qcr@VM-16-6-centos Learn_protoBuf]$ g++ -std=c++11 -c contacts.pb.cc -o contacts.pb.o -Wall -Wextra
[qcr@VM-16-6-centos Learn_protoBuf]$ 

  我宣布还是没任何问题,好好好,绝望的一刻。

[qcr@VM-16-6-centos Learn_protoBuf]$ g++ -std=c++11 write.o contacts.pb.o -o write -L/usr/local/protobuf/lib -I/usr/local/protobuf/include -lprotobuf
write.o: In function `google::protobuf::Any* google::protobuf::MessageLite::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)':
write.cc:(.text._ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE[_ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE]+0x14): undefined reference to `google::protobuf::Any* google::protobuf::Arena::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)'
collect2: error: ld returned 1 exit status

  我就彻底确定是链接这一刻的问题,但是库版本对头文件路径对库文件路径对
  然后我开始迷茫,还看见 -lpthread 的添加,链接命令的顺序等方法,都不行!直到我再一次尝试的时候才发现问题:我又一次再 gcc 命令中加了 -v

  -v 选项用于显示详细的编译过程信息,包括编译器所执行的每个步骤和所调用的命令。这个选项通常称为 "verbose"(冗长)模式

[qcr@VM-16-6-centos Learn_protoBuf]$ g++ -std=c++11 write.o contacts.pb.o -o write -L/usr/local/protobuf/lib -I/usr/local/protobuf/include -lprotobuf -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:./:/usr/local/protobuf/lib/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-std=c++11' '-o' 'write' '-L/usr/local/protobuf/lib' '-I' '/usr/local/protobuf/include' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o write /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/local/protobuf/lib -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L. -L/usr/local/protobuf/lib -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. write.o contacts.pb.o -lprotobuf -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o
write.o: In function `google::protobuf::Any* google::protobuf::MessageLite::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)':
write.cc:(.text._ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE[_ZN6google8protobuf11MessageLite18CreateMaybeMessageINS0_3AnyEEEPT_PNS0_5ArenaE]+0x14): undefined reference to `google::protobuf::Any* google::protobuf::Arena::CreateMaybeMessage<google::protobuf::Any>(google::protobuf::Arena*)'
collect2: error: ld returned 1 exit status

  惊醒:我用的是 4.8.5 版本的 GCC
  因为编译和链接的命令已经非常详细的进行了分析,但问题仍然是由于链接到的 protobuf 库版本与你的代码不兼容引起的。就是因为 GCC 4.8.5 版本,是一个相对旧的版本。
  GCC 4.8.5 版本,相较于较新的 C++ 标准少引入了一些新的语言特性和库,而这些特性可能在旧版本的编译器中不受支持。而代码中如果使用了较新的 C++ 特性,而我们的编译器版本太老,可能会导致编译或链接错误。因为 protobuf 库依赖于较新的 C++ 标准或库,因此在使用较旧版本的 GCC 编译 protobuf 库时,可能会导致与你的代码不兼容的问题。

  • 百度搜索:scl gcc devsettool 升级 gcc
//安装scl
$ sudo yum install centos-release-scl scl-utils-build

//安装新版本gcc,这里也可以把9换成7或者8
$ sudo yum install -y devtoolset-9-gcc devtoolset-9-gcc-c++
$ ls /opt/rh/

//启动: 细节,命令行启动只能在本会话有效
$ scl enable devtoolset-9 bash
$ gcc -v

  问题就此搞定!!!

[qcr@VM-16-6-centos Learn_protoBuf]$ scl enable devtoolset-9 bash
[qcr@VM-16-6-centos Learn_protoBuf]$ gcc --version
gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[qcr@VM-16-6-centos Learn_protoBuf]$ make
g++ -o write write.cc contacts.pb.cc -std=c++11 -lprotobuf -lpthread
g++ -o read read.cc contacts.pb.cc -std=c++11 -lprotobuf -lpthread
[qcr@VM-16-6-centos Learn_protoBuf]$ 

后话

  本人的错误实在有些丢脸,搞"复古"😢😢😢,也是对于云服务器的老地方并未更新所导致的。

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

川入

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值