我正在尝试为QNX / ARM编译一个简单的项目,它包含一个主要的可执行文件和两个共享库,liba和libb。
main仅依赖于liba,并且根本不使用libb中的任何内容。 liba依赖于libb。 所以依赖链是:main - > liba - > libb。因此,libb是main的间接/传递依赖。 liba.so位于子目录liba /中,libb.so位于子目录libb /中。
我通过以下方式链接主要:
qcc -Vgcc_ntoarmv7le -Wl,--no-undefined -lang-c++ -o linktest main.o -L$TARGET/lib -Llibb -Lliba -la
如您所见,由于两条-L行,链接器在查找libb和liba时应该没有问题。
当我用QNX / ARM工具链编译它时,我收到一个错误:
ntoarm-ld: warning: libb.so, needed by liba/liba.so, not found (try using -rpath or -rpath-link)
使用strace确认ld从未查看libb /目录,尽管使用-L指定它。
为什么不在这里查看-L目录?
答案 0 :(得分:0)
-lb
丢失了! L
指定路径,而l
指定实际库。在构建命令的末尾添加-lb
:
qcc -Vgcc_ntoarmv7le -Wl,--no-undefined -lang-c++ -o linktest main.o \
-L$TARGET/lib -Llibb -Lliba -la -lb
如果要消除此构建时依赖性,请考虑使用{em> libb 通过 liba 中的运行时dynamic loading使用dlopen()。
更新:
正如 tmcguire 所指出的,共享库的间接链接行为因链接器而异。根据{{3}},负责的ld
选项为--no-copy-dt-needed-entries
(有时称为--no-add-needed
,默认情况下会启用最新的gcc
版本(> 4.5?)。
另一个有趣的选择是--as-needed
:
将
--as-needed
标志传递给GNU链接器(GNU ld)。国旗 告诉链接器仅在生成的二进制文件中链接库 包含二进制文件本身实际使用的符号。这个二进制可以 是最终的可执行文件或另一个库。
其他阅读材料为this article和here。