XCode:来自库(iOS)的一种特定方法的“未定义符号”

时间:2014-01-02 14:38:46

标签: ios xcode undefined symbols gameplay3d

我有一个与游戏引擎静态库链接的测试项目。我成功地为OS X和iOS构建了它,然后,在我的实验中,在我的应用程序代码中添加了一个新的库方法用法(已经有一些其他的用法):

std::vector<Node*> allNodes;
_scene->findNodes("", allNodes, true, false);

之后iOS构建开始产生链接器错误(虽然OS X构建仍然可以正常工作):

Undefined symbols for architecture armv7:
  "gameplay::Scene::findNodes(char const*, std::vector<gameplay::Node*, std::allocator<gameplay::Node*> >&, bool, bool) const", referenced from:
      App::initialize() in App.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Undefined symbols for architecture armv7s:
  "gameplay::Scene::findNodes(char const*, std::vector<gameplay::Node*, std::allocator<gameplay::Node*> >&, bool, bool) const", referenced from:
      App::initialize() in App.o
ld: symbol(s) not found for architecture armv7s
clang: error: linker command failed with exit code 1 (use -v to see invocation)

同时其他功能(甚至来自同一类场景)被链接并正常工作。 此方法具有以下签名:

unsigned int findNodes(const char* id, std::vector<Node*>& nodes, bool recursive = true, bool exactMatch = true) const;

在.cpp文件中,它的实现具有匹配的签名:

unsigned int Scene::findNodes(const char* id, std::vector<Node*>& nodes, bool recursive, bool exactMatch) const

仍然没有链接。这种特殊方法可能有什么问题?

XCode版本是5.0.2

编辑1: 该库是根据armv7 / armv7s架构的源码构建的,因此也就是应用程序本身。

3 个答案:

答案 0 :(得分:0)

未找到架构armv7的符号

方法gameplay :: Scene :: findNodes不是为armv7构建的(旧版IOS设备的'二进制代码',还有标准)

溶液?

a)不考虑旧设备,只为armv7构建[也许你使用的lib工作]

  

xcode&gt;项目设置/目标设置
       VALID_ARCHS = armv7s

b)向制造商抱怨


如果您不相信错误,请检查 lipo

gmaps的例子

lipo -info /Users/dominik/Documents/work-sapient/project-myAudi/svn/myAudi-IntApp/Vendor/GoogleMaps/GoogleMaps.framework/GoogleMaps

Architectures in the fat file: /Users/dominik/Documents/work-sapient/project-myAudi/svn/myAudi-IntApp/Vendor/GoogleMaps/GoogleMaps.framework/GoogleMaps are: armv7 armv7s i386

答案 1 :(得分:0)

您说您添加了一个新方法,并且链接器找不到此方法。

一种可能的解释是,您要链接旧版本的库,该版本不包含您添加到其中的最新方法。您可以手动重新编译库,也可以指定测试二进制文件和库之间的依赖关系。

它可以帮助清理项目(你甚至可以完全删除“build”目录)并从头开始重新编译。

答案 2 :(得分:0)

问题来自C ++ 11。我的应用程序使用它,但引擎库没有。在库设置中,选项“C ++语言方言”和“C ++标准库”设置为“编译器默认值”。在应用程序设置中,它们分别设置为“C ++ 11 [-std = c ++ 11]”和“编译器默认值”。有了这些选项,我曾经有很多std函数的链接器错误,所以我也在“Link Binary With Libraries”部分中手动指定了libc ++。dylib,一切都运行良好。但是,这种选择的组合导致了这种奇怪的行为。

我通过从列表中删除libc ++。dylib并将“C ++标准库”设置为“libc ++”来解决该问题。图书馆选项保持不变。在比较库的nm输出和我的目标文件之后,我开始寻找这个方向:

$ nm -arch armv7 -A Products/Debug-iphoneos/libgameplay.a | grep findNodes
...
Products/Debug-iphoneos/libgameplay.a:Scene.o: 00000ea0 T __ZNK8gameplay5Scene9findNodesEPKcRNSt3__16vectorIPNS_4NodeENS3_9allocatorIS6_EEEEbb
...
$ c++filt __ZNK8gameplay5Scene9findNodesEPKcRNSt3__16vectorIPNS_4NodeENS3_9allocatorIS6_EEEEbb
gameplay::Scene::findNodes(char const*, std::__1::vector<gameplay::Node*, std::__1::allocator<gameplay::Node*> >&, bool, bool) const

$ nm -arch armv7 -A Intermediates/Rebus.build/Debug-iphoneos/Rebus-ios.build/Objects-normal/armv7/App.o | grep findNodes
<long_path>App.o: U __ZNK8gameplay5Scene9findNodesEPKcRSt6vectorIPNS_4NodeESaIS5_EEbb
$ c++filt __ZNK8gameplay5Scene9findNodesEPKcRSt6vectorIPNS_4NodeESaIS5_EEbb
gameplay::Scene::findNodes(char const*, std::vector<gameplay::Node*, std::allocator<gameplay::Node*> >&, bool, bool) const

(注意std :: vector中的“__1”差异。)

感谢@sergio提供线索。