使用 gcc 11 构建的协议中未定义的符号

Posted

技术标签:

【中文标题】使用 gcc 11 构建的协议中未定义的符号【英文标题】:Undefined symbol in protoc with gcc 11 build 【发布时间】:2021-07-25 17:03:22 【问题描述】:

我正在尝试通过关注these instructions. 来构建协议缓冲区

这就是我所做的。

git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure
make -j6

构建成功后,我检查了

ldd -d src/.libs/protoc

它显示了很多未定义的符号。

root@renju-mc:~/.../protobuf# ldd -d src/.libs/protoc
        linux-vdso.so.1 (0x00007fff1f3a5000)
        libprotoc.so.28 => not found
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fdce230c000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdce20f4000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdce1d03000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdce1965000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fdce291d000)
undefined symbol: _ZN6google8protobuf8compiler20CommandLineInterface12AllowPluginsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE       (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler20CommandLineInterface3RunEiPKPKc (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler20CommandLineInterfaceD1Ev        (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler6csharp9GeneratorC1Ev     (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler6python9GeneratorC1Ev     (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler20CommandLineInterface17RegisterGeneratorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_PNS1_13CodeGeneratorESA_   (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler20CommandLineInterfaceC1Ev        (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler4java13JavaGeneratorD1Ev  (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler13CodeGeneratorD2Ev       (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler4java15KotlinGeneratorC1Ev        (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler6csharp9GeneratorD1Ev     (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler3cpp12CppGeneratorD1Ev    (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler10objectivec19ObjectiveCGeneratorC1Ev     (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler4java15KotlinGeneratorD1Ev        (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler10objectivec19ObjectiveCGeneratorD1Ev     (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler3cpp12CppGeneratorC1Ev    (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler4java13JavaGeneratorC1Ev  (src/.libs/protoc)
undefined symbol: _ZN6google8protobuf8compiler6python9GeneratorD1Ev     (src/.libs/protoc)

libprotoc.so.28 => not found此文件与 protoc 位于同一位置。

root@renju-mc:~/.../protobuf# ls -l src/.libs/libprotoc.so.28
lrwxrwxrwx 1 root root 19 Jul 25 22:20 src/.libs/libprotoc.so.28 -> libprotoc.so.28.0.3

我正在使用带有 gcc-11 的 Ubuntu 18.04。

gcc version 11.1.0 (Ubuntu 11.1.0-1ubuntu1~18.04.1)

【问题讨论】:

【参考方案1】:

默认情况下,Linux 加载程序ld.so 不会从当前目录加载库,而只会从预定义的位置加载。

您正在尝试从当前目录加载依赖于当前目录中另一个库的库,因此加载失败。

ld.so 的手册页解释了how to set LD_LIBRARY_PATH in order change this behavior。

【讨论】:

【参考方案2】:

如果您遵循包括“make install”步骤在内的所有说明,它可能会更好地工作。通常“make install”将构建的动态库放置在一些标准位置,例如 /usr/local/lib,动态链接器会在其中找到它们。

如果您出于某种原因不想安装该软件,您可以使用环境变量 LD_LIBRARY_PATH 来指出包含动态库的非标准目录。例子: 导出 LD_LIBRARY_PATH=src/.libs

【讨论】:

以上是关于使用 gcc 11 构建的协议中未定义的符号的主要内容,如果未能解决你的问题,请参考以下文章

强制 GCC 通知共享库中未定义的引用

在 Eclipse IDE 中未定义对“crypt”的引用

libboost 中未定义的符号

O2 中导致未定义符号的 gcc 优化标志

由于 iOS 中未捕获的异常,架构 i386 和终止应用程序的未定义符号

架构 x86_64 的未定义符号:El Capitan [重复]