在Xcode中创建一个Objective-C++静态库

11

我开发了一个 iPhone 引擎,想要用它来制作几个不同的游戏。我不想把引擎的文件复制粘贴到每个游戏项目的目录中,而是想要找到一种方法从每个游戏中链接到引擎,这样如果需要对其进行更改,我只需修改一次。经过一些搜索,似乎在 iPhone 上使用静态库是最好的方法。

我创建了一个名为 Skeleton 的新项目,并将所有引擎文件都拷贝到其中。我使用了这个指南来创建一个静态库,并将该库导入到名为 Chooser 的项目中。但是,当我尝试编译该项目时,Xcode开始抱怨某些C++数据结构,这些数据结构包含在一个名为 ControlScene.mm 的文件中。以下是我的构建错误:

  "operator delete(void*)", referenced from:


      -[ControlScene dealloc] in libSkeleton.a(ControlScene.o)


      -[ControlScene init] in libSkeleton.a(ControlScene.o)


      __gnu_cxx::new_allocator<operation_t>::deallocate(operation_t*, unsigned long)in libSkeleton.a(ControlScene.o)


      __gnu_cxx::new_allocator<operation_t*>::deallocate(operation_t**, unsigned long)in libSkeleton.a(ControlScene.o)


  "operator new(unsigned long)", referenced from:


      -[ControlScene init] in libSkeleton.a(ControlScene.o)


      __gnu_cxx::new_allocator<operation_t*>::allocate(unsigned long, void const*)in libSkeleton.a(ControlScene.o)


      __gnu_cxx::new_allocator<operation_t>::allocate(unsigned long, void const*)in libSkeleton.a(ControlScene.o)


  "std::__throw_bad_alloc()", referenced from:


      __gnu_cxx::new_allocator<operation_t*>::allocate(unsigned long, void const*)in libSkeleton.a(ControlScene.o)


      __gnu_cxx::new_allocator<operation_t>::allocate(unsigned long, void const*)in libSkeleton.a(ControlScene.o)


  "___cxa_rethrow", referenced from:


      std::_Deque_base<operation_t, std::allocator<operation_t> >::_M_create_nodes(operation_t**, operation_t**)in libSkeleton.a(ControlScene.o)


      std::_Deque_base<operation_t, std::allocator<operation_t> >::_M_initialize_map(unsigned long)in libSkeleton.a(ControlScene.o)


  "___cxa_end_catch", referenced from:


      std::_Deque_base<operation_t, std::allocator<operation_t> >::_M_create_nodes(operation_t**, operation_t**)in libSkeleton.a(ControlScene.o)


      std::_Deque_base<operation_t, std::allocator<operation_t> >::_M_initialize_map(unsigned long)in libSkeleton.a(ControlScene.o)


  "___gxx_personality_v0", referenced from:


      ___gxx_personality_v0$non_lazy_ptr in libSkeleton.a(ControlScene.o)


      ___gxx_personality_v0$non_lazy_ptr in libSkeleton.a(MenuLayer.o)


  "___cxa_begin_catch", referenced from:


      std::_Deque_base<operation_t, std::allocator<operation_t> >::_M_create_nodes(operation_t**, operation_t**)in libSkeleton.a(ControlScene.o)


      std::_Deque_base<operation_t, std::allocator<operation_t> >::_M_initialize_map(unsigned long)in libSkeleton.a(ControlScene.o)


ld: symbol(s) not found


collect2: ld returned 1 exit status
如果有人能够提供一些关于为什么出现这些问题的见解,我将不胜感激。
4个回答

25

将"-lstdc++"设置为其他链接器标志


18

问题是你的库与libstdc++动态链接。如何解决这个问题,您应该尝试在构建您的库时使用"-static"、"-static-libstdc++"和"-static-libgcc"以不同的组合(不确定哪些是必需的,但其中某些组合应该使其完全静态)。

编辑
事实证明,在iPhone上允许动态链接libstdc++,因此更好的解决方案是在构建时显式地链接libstdc++,即将"-lstdc++"加入到您的构建中。


@helixed,如果你使用Makefile或者命令行构建库,你可以将这些选项添加到g++的调用中。如果你正在使用Xcode,我相信在项目构建设置中有类似于“其他标志”的东西,你可以在那里输入这些内容。 - Michael Aaron Safyan
1
没错,运行得非常完美。如果有人感到困惑,正确的放置位置是在其他链接器标志中。感谢您的帮助。 - LandonSchropp
1
我必须将此标志添加到使用静态库的应用程序中,而不是库本身。是否有可能以这样的方式构建库,使得无需修改应用程序的构建设置? - Eddy K

1

我通过进入 Chooser 的构建设置,搜索“编译源代码为”并选择 Objective-C++ 来解决了问题。这可能是一个不太优雅的解决方案,但它起作用了。


这是否意味着它有效地执行了添加-lstdc++标志所做的相同操作? - Hari Honor

1
我在尝试链接一个 .framework 时遇到了这个问题。通过添加一个空的 cppstub.mm 文件作为源文件(添加到“编译源代码”阶段),我已经成功解决了这个问题。我猜测这样做可能会强制进行某种类型的 C++ 编译,不要问我为什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接