嵌套依赖项上的 gcc 共享库 "undefined reference"

gcc shared library "undefined reference" on nested dependencies

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.outfoo() 的未定义符号。为了解决它,我试过:

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

我的问题是:

  1. 为什么会这样"undefined reference"?
  2. 任何告诉 linker libtest0.so 具有 foo() 定义的解决方案?

谢谢。

更新1:

if i link libtest0 when compile libtest2, then compile:

g++ -g main.cc -L. -ltest2

现在一切都很好。但是,在现实世界的问题中,我无法更改 libtest2.so

的 linkage

更新2

clang++ 使用此 cmd:(linker 是 ld,而不是 lld)

# clang version 11.0.0
clang++ -g main.cc -L. -ltest2 -ltest0

更新3

例如:https://gist.github.com/xgwang/da93edcc06542264157f600eb64bc082

只是 bash 它在 linux 上。在 Ubuntu 16.

上测试

首先,引自here(重点是我的):

Failure in final linking, undefined symbols

This is the most common error that happens while using --as-needed. It happens during the final linking stage of an executable (libraries don't create problems, because they are allowed to have undefined symbols). The executable linking stage dies because of an undefined symbol that is present in one of the libraries fed to the command line. However, the library is not used by the executable itself, thus it gets removed by --as-needed. This usually means that a library was not linked to another library, but was using it, and then relying on the final executable to link them together. This behavior is also an extra encumbrance on developers using that library because they have to check for the requirements.

作为解决方法,而不是

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