【问题标题】:Tricky Undefined Reference Error棘手的未定义引用错误
【发布时间】:2012-07-17 16:52:32
【问题描述】:

在尝试使用 C++ 在 Linux 中构建模块时,我遇到了一个严重的“未定义引用”错误。我将在高层次上描述它,并在必要时稍后发布代码(它是专有的,因此发布它需要更改名称)。一些细节:

  • 模块 A(一个库)有一个类,我们将使用一个名为 Bar 的方法调用该类。模块 A 构建得很好,使用 nm 查看目标文件表明构造函数和 Bar 都已定义(它们显示为“T”)。
  • 模块 B(一个库)包含一个使用模块 A 的类,其中引用了 Foo::Foo、Foo::~Foo 和 Foo::Bar。它的makefile 包括-L/path/to/Foo 和-lFoo。这个模块也构建得很好。但是,当我在模块 B 的目标文件上运行 nm 时,对模块 Foo::Foo、Foo::~Foo 和 Foo::Bar 的调用是未定义的(它们显示为“U”)。为什么它构建我无法理解。
  • 模块 C - 其输出是可执行文件 - 包含对模块 B 的引用。当我尝试构建模块 C 时,然后它对我大喊大叫,因为从模块 B 到模块 A 的 Foo 和条形方法。

    1. 如果引用未定义,为什么要构建模块 B?
    2. 为什么只有进入模块 C 后才报告错误?

编辑:

  1. 我应该提一下,模块 C 的 makefile 也有 -L/path/to/Foo 和 -lFoo,但它仍然失败。关于我应该尝试的任何事情的任何高级猜测?我有一种感觉,我将不得不发布一些代码......

【问题讨论】:

标签: c++ linux linker g++ ld


【解决方案1】:

我知道为什么它没有建立。这与这里的问题相同:

undefined reference to symbol even when nm indicates that this symbol is present in the shared library

【讨论】:

    【解决方案2】:

    模块 B 是 build 还是只是 compile?在尝试构建模块 C 之前,您实际上是否将模块 B 链接到模块 A?如果你是,我会感到惊讶。在编译 阶段,编译器只检查所有名称是否已声明。编译器不寻找定义(即实现)。链接阶段负责这个细节。在链接阶段,您需要指定构建项目所需的所有模块(在本例中为A、B和C。)

    【讨论】:

    • 很可能是 build。库不需要解析所有符号来链接。
    • @DavidRodríguez-dribeas 嗯……那么我(也许是 OP 方面)有些困惑。 OP 将模块 A 称为“库”,然后再引用“目标文件”。 AFAIK,目标文件是编译而不是链接的结果。
    【解决方案3】:

    创建共享库时,不需要定义所有符号。如果需要,可以使用编译器命令行开关(链接器选项 --no-allow-shlib-undefined)更改此行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-09
      • 2014-12-20
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多