g ++ 5.4.0
Ubuntu 16.04
我有几个共享库,这是它们的抽象:
libtest0.so: definition of `void foo()`
libtest1.so: `extern void foo()`, and not depends on libtest0.so
libtest2.so: use libtest1.so and depends on libtest1.so
现在我有一个二进制文件:
a.out: use libtest2.so
当然a.out
具有未定义的符号foo()
。为了解决这个问题,我尝试过:
g++ main.cc -L. -ltest2 -ltest0
因为libtest0.so具有foo()
的定义。
但是,它不起作用:
$g++ -g main.cc -L. -ltest2 -ltest0
libtest1.so: undefined reference to `foo'
collect2: error: ld returned 1 exit status
我的问题是:
foo()
定义的解决方案?谢谢。
更新1:
如果我在编译libtest2时链接libtest0,则进行编译:
g++ -g main.cc -L. -ltest2
现在一切都很好。但是,在现实世界中,我无法更改libtest2.so的链接。
Update2
clang ++使用此cmd :(链接器是ld,不是lld)
# clang version 11.0.0
clang++ -g main.cc -L. -ltest2 -ltest0
Update3
一个例子是:https://gist.github.com/xgwang/da93edcc06542264157f600eb64bc082
只需在Linux上对其进行重击即可。在Ubuntu 16上进行了测试。
答案 0 :(得分:2)
首先,引用here中的一个引号(强调是我的意思):
最终链接失败,未定义符号
这是使用
--as-needed
时最常见的错误。它发生在可执行文件的最后链接阶段(库不会造成问题,因为允许它们具有未定义的符号)。可执行链接阶段之所以消失,是因为在馈送到命令行的库之一中存在未定义的符号。但是,可执行文件本身未使用该库,因此它会被--as-needed
删除。 这通常意味着一个库没有链接到另一个库,而是在使用它,然后依赖最终的可执行文件将它们链接在一起。对于使用该库的开发人员来说,这种行为也是一种额外的负担,因为他们必须检查要求。
一种解决方法,而不是
g++ main.cc -L. -ltest2 -ltest0
尝试
g++ main.cc -L. -ltest2 -Wl,--no-as-needed -ltest0
禁用--as-needed
行为。
最适合我的最小示例:
#!/bin/bash
export LD_LIBRARY_PATH=.
g++ -fPIC -shared test0.cc -o libtest0.so
g++ -fPIC -shared test1.cc -o libtest1.so
g++ -fPIC -shared test2.cc -o libtest2.so -L. -ltest1
g++ main.cc -L. -ltest2 -Wl,--no-as-needed -ltest0