gcc 构建链接但共享库不与 ldd 一起出现

gcc build links but shared library does not appear with ldd

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

这是我的 gcc 命令:

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

程序生成并 links,但它没有启动。它给了我以下错误:

./a.out: symbol lookup error: /path/to/libraries/lib/libA.so: undefined symbol: 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)

我有这些条件:

我做错了什么?我可以做些什么来 link 两个库的可执行文件?

大多数 Linux 发行版(我假设您使用 Linux 基于 ldd 的输出)似乎将 gcc 配置为传递 --as-needed默认为 ld(例如,对于 Debian,请参见 here)。这意味着如果 library/executable.[=23 实际上使用了该库的某些符号,则最终的 library/executable 将仅依赖于该库(即该库具有 DT_NEEDED 标记) =]

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

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

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