【问题标题】:Undefined symbols, though they are defined in our .cpp file未定义的符号,尽管它们是在我们的 .cpp 文件中定义的
【发布时间】:2012-03-03 18:35:13
【问题描述】:

我正在努力在 linux 中构建一个库。这在 Windows 中构建和工作,但在 Linux 上,当使用静态库时,我在我们的库中得到一个未解析的符号。代码如下:

class MyClass : public AnotherClassRefCounded
{
public:
  static bool queryInstance(MyClass **ppmyClass);
};

在这个类的 .cpp 文件中,我有:

#include "stdafx.h"
#include "MyClass.h"

MyClass* MyClass::m_pInstance = NULL;

bool MyClass::queryInstance(MyClass **myClass)
{
  if(m_pInstance == NULL)
  {
    m_pInstance = new MyClass();
    m_pInstance->incRef(); 
  }

  m_pInstance->incRef();
  *myClass = m_pInstance;
  return true;
}

现在在 libMyLib.a 上运行 nm -Cu 时,我得到以下输出:

[matt6809@hogganz400 libDebug]$ nm -Cu libMappingd.a | grep queryInstance
                 U AFewMoreScopes::MyClass::queryInstance(AFewMoreScopes::MyClass**)

我的系统信息是:

[matt6809@hogganz400 libDebug]$ cat /etc/redhat-release ; gcc --version
Red Hat Enterprise Linux Server release 6.1 (Santiago)
gcc (GCC) 4.4.5 20110214 (Red Hat 4.4.5-6)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

出于版权原因,我不能发布相同的代码。我已经尽我所能复制了代码。如果您觉得我遗漏了任何信息,请随时询问。


更新

构建示例:

...

g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W <DEFINE FLAGS> <INCLUDE FLAGS> -o MyClass.o MyClass.cpp

...

ar cqs libMappingd.a <all object files>

更新 0

这很有趣。在“MyClass”的目标文件中,该符号不是未定义的:

MyClass.o:
                 <My Symbol Not Undefined>

但是,如果您转到另一个目标文件:

<Other Object>.o:
                 ...
                 U Scope::MyClass::queryInstance(Socpe::MyClass**)

更新1

g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o MyClass.o MyClass.cpp
g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o OtherClass.o OtherClass.cpp
rm -f libMappingd.a
ar cqs libMappingd.a <Other Objects> MyClass.o OtherClass.o

g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o OtherClass.o OtherClass.cpp
g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o MyClass.o MyClass.cpp
rm -f libMappingd.a
ar cqs libMappingd.a <Other Objects> OtherClass.o MyClass.o

没关系,我仍然在其他库中得到未定义的符号。

【问题讨论】:

  • 你是如何制作libMappingd.a的?发布命令及其输出。
  • 为什么'MyClass'在你的cpp文件中变成了'RuntimeEnvironment'?
  • 我正在使用 Qt 构建静态库。给我一点时间从编译语句中取出一行。
  • 版权原因?我认为这是合理使用,但无论如何。您发布的代码是否出现同样的错误?
  • 我有一个使用静态实例方法和属性的单例类,它在库中编译得很好。我担心我们正在构建的图书馆可能有更深层次的问题,只是想在深入挖掘之前看看是否有一个简单的答案。

标签: c++ g++ ld


【解决方案1】:

我知道 VC++ 和 GCC 之间的主要区别在于,您提供给链接器的目标文件的顺序很重要。在目标文件 A 中使用的符号必须在链接顺序中定义在其中或之后。

尝试将 MyClass.o 移动到目标文件列表的末尾。

【讨论】:

  • 我以为 ar 只是在没有检查的情况下提取了所有符号?
  • @MatthewHoggan - 我实际上不确定存档器是否依赖于订单...我说的是链接器,因为您说 消费 时出现错误静态库,即使用链接器时的含义。您是否在最终的可执行文件/共享库中的其他地方使用了这个未定义的符号?如果是这样,请尝试将 libMappingd.a 移到列表的后面,并告诉我,以便我更新答案。
  • 存在未定义符号问题的两个文件都在 Mapping 中,并且 Mapping 依赖于所有其他库。因此,它被列在第一位。从 Qt 项目文件“LIBS += \ -lMapping \ 复制
【解决方案2】:

经过大量研究,我发现 RHEL 6.1 上的存档器中存在错误。我不再尝试将静态库直接拉入共享动态库,而是解压缩静态库,并将相应的目标文件直接拉入 .so 文件。除了我没有静态链接的那些之外,我现在在我们的库中有 0 个未定义的符号。

【讨论】:

    猜你喜欢
    • 2017-09-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多