XCode 4.2静态库链接问题

XCode 4.2 static libraries linking issue

本文关键字:链接 问题 静态 XCode      更新时间:2023-10-16

我有Core静态库,一些Component静态库依赖于Core一个,然后有一个App链接到CoreComponent库。我的App可以链接CoreComponent,只要Component不使用Core中的类(App使用Core中的类)。

我在armv6和armv7版本中都得到了以下错误。所以我的问题不是每个人都有的非常流行的链接问题。

ld: symbol(s) not found for architecture armv6
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我在Component中添加了对Core的引用,甚至在"Link Binary With Libraries"中添加了它,这对于静态库来说是不必要的。

自从我开始有这个问题,我开始怀疑我的设计…它可能在动态链接环境中更有意义,但仍然应该在静态环境中可行,特别是因为它已经在Windows下使用MSVC编译器

编辑:

我取得了一些进步!虽然我仍然不知道该怎么做。

下面是我的设置:

  • Core有一个类cResourceManager,该类有一个模板化方法GetResource(int id)

  • Core也有cResource类

  • 组件有继承cResource

  • 的类cMesh

下面是一些测试:

  • 如果我尝试从App调用rm->GetResource(…)我得到链接错误

  • 如果我尝试从App构建cMesh,我会链接链接错误

  • 如果我尝试从App调用静态方法,将返回cMesh的新实例,我得到链接错误

  • 如果我注释掉cMesh的构造,但留下其他成员cMesh函数调用应用程序链接。我甚至可以叫删除网

我从来没有见过这样的东西!

如果您删除了cMesh构造函数,那么您将使用默认的(没有参数,没有主体)cMesh构造函数。这几乎听起来像有一个构建错误或缺失的代码作为一些代码在你的cMesh构造器的结果,所以库实际上并没有生成,也许Xcode没有报告错误。Xcode不擅长报告链接器错误。

我建议看看链接器说缺少什么符号,并仔细检查它们是否在您的代码中实际定义。我的猜测是,您在cMesh构造函数中使用了这些符号之一。很多时候,使用虚基类时,您可能会忘记在子类中定义实现一两个方法。可能是由于缺少基于您的模板的方法,或者您的模板不是正确的#include d。这可以正常编译,但会导致链接器错误,如您所见。

如果Xcode没有显示完整的链接器错误,请显示日志导航器(Command⌘+7),双击最后一个"构建"条目,选择错误,然后按下选中时出现的行右侧的按钮。符号应该列在那里。如果没有,是时候在终端中使用xcodebuild了。

如果它是不是的情况下,我很有兴趣看到的结果是否库是为适当的体系结构构建的,或者这可能会刺激一些进展:

  1. 在Xcode管理器Shift +Command⌘+2中,单击Projects并找到项目的DerivedData路径。
  2. 在终端中,导航到该目录(cd ~/Library/Developer/Xcode/DerivedData/proj-<random value>/)
  3. 删除(或移到一边)Build目录(rm -r Build)
  4. 在Xcode中,尝试使用cMesh构造器进行构建。
  5. 查找库产品文件(cd Build/Products/<scheme>-iphoneos)

编译的静态库(<libname>.a)应该在这个目录中。如果他们不在那里,他们就没有建立(除非你把你的产品放在别处)。如果您的库在那里,让我们确认它们实际上是为适当的体系结构构建的。执行otool -vh <library>.a命令。您应该看到如下内容:

$ otool -vh libtesting.a 
Archive : libtesting.a
libtesting.a(testing.o):
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
   MH_MAGIC     ARM         V7  0x00      OBJECT     3       1928 SUBSECTIONS_VIA_SYMBOLS

如您所见,我的测试库是为ARMv7构建的。

确保你的链接顺序正确。

如果Component依赖于Core中的符号,那么Component需要在链接顺序中排在第一位,这样链接器就知道在Core中查找哪些符号。

在MSVC中,顺序无关紧要,但在大多数其他编译器套件中,顺序是重要的。

我认为Clang不会为armv6生成代码,如果您的目标设备是旧的,您仍然需要使用GCC