2

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

  • 模块 A(一个库)有一个类,我们将使用名为 Bar 的方法调用 Foo。模块 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 和 Bar 方法的未定义引用而大喊大叫。

    1. 如果引用未定义,为什么要构建模块 B?
    2. 为什么只有在我们到达模块 C 时才报告错误?

编辑:

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

3 回答 3

1

我想通了为什么它没有建立。这与这里的问题相同:

即使 nm 指示此符号存在于共享库中,对符号的未定义引用

于 2012-07-17T17:47:06.547 回答
0

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

于 2012-07-17T16:59:27.910 回答
0

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

于 2012-07-17T17:06:42.580 回答