??此处,是本人在学习 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
版本不匹配引起的。
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,导致链接错误。
??至此为了确保链接的是正确版本的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
??该死的他还是找不到!!!
??然后我又回头看他们的各自编译情况是否出错。
-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
$ 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]$
??本人的错误实在有些丢脸,搞"复古"😢😢😢,也是对于云服务器的老地方并未更新所导致的。