10

我有一个必须构建的程序。该程序依赖于libA,并且libA依赖于libB. 两个库都在同一个文件夹中,但ldd libA.so不包含libB.so,所以我必须在链接时添加它。

这是我的gcc命令:

gcc -L/path/to/libraries/lib -lA -lB -I/path/to/libraries/include main.cpp

该程序构建和链接,但它没有启动。它给了我以下错误:

./a.out:符号查找错误:/path/to/libraries/lib/libA.so:未定义符号:symbol_used_in_libA_but_defined_in_libB

ldd我可以看到它libB.so不包含在我的二进制文件中:

linux-vdso.so.1 =>  (0x00007fffaecd9000)
libA.so => /path/to/libraries/lib/libA.so (0x00007effc02a4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007effbfebb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007effbfca5000)
/lib64/ld-linux-x86-64.so.2 (0x00007effc05cb000)

我有这些条件:

  • /path/to/libraries在里面LD_LIBRARY_PATH
  • 运行ldconfig没问题,ldconfig -p找到libA.so两者libB.so
  • 如果在 gcc 命令中更改-lB-lBB会给我一个链接器错误,所以我认为即使它没有将它链接到可执行文件中,也gcc可以正确找到。libB.so

我做错了什么?为了将可执行文件链接到两个库,我能做些什么?

4

1 回答 1

15

大多数 Linux 发行版(我假设您正在使用基于 的输出的 Linux ldd)似乎默认配置gcc为传递--as-neededld(例如,请参阅此处的 Debian)。这意味着最终的库/可执行文件将仅依赖于一个库(即,具有DT_NEEDED该库的标签),如果该库的某个符号实际被库/可执行文件使用。

在您的情况下,main.cpp不使用 的任何功能,libB因此链接器不会添加libB为最终可执行文件的依赖项。您可以通过将--no-as-needed标志传递给链接器来解决它。例如,

gcc -Wl,--no-as-needed ...

当然,正确的解决方法是重新链接libA并确保它libB作为依赖项列出。

于 2015-01-22T12:05:17.490 回答