【问题标题】:gcc shared library "undefined reference" on nested dependencies嵌套依赖项上的 gcc 共享库“未定义引用”
【发布时间】:2020-05-13 13:20:12
【问题描述】:

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. 为什么会出现这种“未定义的引用”?
  2. 是否有任何解决方案告诉链接器 libtest0.so 具有 foo() 的定义?

谢谢。

更新1:

如果我在编译libtest2时链接libtest0,则编译:

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

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

更新2

clang++ 与这个 cmd 一起工作:(并且链接器是 ld,而不是 lld)

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

更新3

一个例子是:https://gist.github.com/xgwang/da93edcc06542264157f600eb64bc082

只需在 linux 上 bash 即可。在 Ubuntu 16 上测试。

【问题讨论】:

  • libtest1 链接在哪里?
  • @Evg 它没有帮助:g++ -std=c++11 -g main.cc -L. -ltest2 -ltest0libtest1.so: undefined reference to foo
  • @BaileyKocin libtest1 是 libtest2 的一个依赖,可以通过ldd libtest2.so显示出来
  • 你能链接ltest0然后ltest2然后ltest0。
  • @BaileyKocin 仍然无法正常工作。这是我的 gcc cmd:g++ -shared -fPIC so0.cc -o libtest0.sog++ -shared -fPIC so1.cc -o libtest1.sog++ -shared -fPIC so2.cc -o libtest2.so -L. -ltest1g++ -g main.cc -L. -ltest0 -ltest2 -ltest0/path/to/libtest1.so: undefined reference to foocollect2: error: ld returned 1 exit status 抱歉格式化。

标签: c++ linker shared-libraries


【解决方案1】:

首先,引用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    相关资源
    最近更新 更多