棘手的未定义参考错误

时间:2012-07-17 16:52:33

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

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

  • 模块A(库)有一个类,我们用一个名为Bar的方法调用Foo。模块A构建得很好,使用nm查看目标文件显示构造函数和条形图都已定义(它们显示为“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,但它仍然失败。我应该尝试任何高级猜测吗?我有一种感觉,我将不得不发布一些代码......

3 个答案:

答案 0 :(得分:1)

我弄清楚它为什么没有建造。这是和以前一样的问题:

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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