Xcode:为什么将文件重命名为.mm后,静态库中出现未定义符号"___gxx_personality_sj0"错误?

3

我刚刚把一个静态库/框架中的Objective-C类实现文件从.m改成了.mm,然后链接失败并出现以下错误:

Undefined symbols for architecture armv7s: "___gxx_personality_sj0"

我可以通过在应用程序目标的其他链接器标志中添加 -lc++ (libc++.dylib) 来解决此问题。但我的问题是: 为什么会出现这个问题?为什么只有在静态库代码中才会出现,而重命名应用程序的一个实现文件时却不会出现?

除了添加 -lc++,还有其他解决方案吗?

注意: 此类的实现不包含任何代码。该类也没有使用或导入C++代码,项目中也没有其他地方使用C++代码。


可能是重复的问题:undefined reference to `__gxx_personality_sj0 - Anya Shenanigans
C++代码需要在遇到异常时支持堆栈展开。当您将文件从.m重命名为.mm时,您将其转换为需要支持异常的代码,并且异常处理需要C++运行时正常工作。 - Anya Shenanigans
因此,我在构建设置中禁用了C++和Objective-C异常处理。 - CodeSmile
@Petesh,这并不能解释为什么我可以在应用程序目标中将任何文件重命名为.mm,但无法在静态库目标中进行操作。例如,cocos2d+box2d项目模板没有这个问题,即使Box2D是C++代码,也不链接libc++。 - CodeSmile
1个回答

3
当你创建一个静态库时,不会链接到相关的库。因此,当你将其中一个文件从.m重命名为.mm时,它开始依赖于C++特性,例如在接收异常时进行堆栈展开。即使你告诉编译器不打算使用异常(通过拒绝使用C++异常的编译标志),它仍然需要了解堆栈展开的潜在机制(这就是人格变量的含义)。
Cocos2d+Box2d模板应用程序之所以没有这个问题,是因为它们具有一些.mm文件; 因此,使用c++编译器执行最终链接,在链接时自动引入了c++库。

谢谢!不过我不确定 OpenAL,因为我还将应用程序目标与OpenAL.framework链接。 - CodeSmile
看起来演示应用程序有一些.mm文件。只要有c++文件,代码也会使用c++编译器进行链接。 - Anya Shenanigans
没错,我刚刚验证了这个。只要我将任何应用程序目标文件从.m更改为.mm,链接器错误就会消失,而无需添加-lC++。不过我还是会使用-lC++,因为我不想依赖于那个。 - CodeSmile

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