虽然还没具体去看为什么,不过使用theos编译多个文件时,比如main.mm和一个a.m,会报链接错误。
稍微看了一下,是因为ObjC、ObjC++生成的符号不同,所以无法链接。
分析如下
a.m文件的内容:
#import <Foundation/Foundation.h> #import <stdio.h> int plus(int a, int b){ return a+b; }
下图为分别以ObjC、ObjC++编译a.m生成的符号。
可以看到,以ObjC编译时,plus的符号是_plus
而以ObjC++编译时,plus的符号是__Z4plusii
那么main.mm呢
可以看到,倒数第7行:
0000000000000028 callq __Z4plusii
因为后缀是.mm,所以main.mm是以ObjC++编译的,main中调用plus的函数符号为__Z4plusii
所以,为了生成的函数符号一样,我们对a.m也应该使用ObjC++的方式来编译。
因为编译是按一定规则把每个文件编译成.o文件,最后再来链接、生成可执行文件。
theos中定义这些规则的文件在/opt/theos/makefiles/instance/rules.mk
那么我们修改.m对应的编译规则即可。你可以在这个allobjcpp.patch.gz中了解我是如何修改的。
的确,最简单的方式就是把.m文件直接改名为.mm即可。
虽然这种简单粗暴的改文件后缀可以解决这个问题,不过我们更想知道为什么会出现这个问题。
顺便一提,即使是在Xcode中,这样编译也会报错:
解决方法就是把文件的类型手动设定为Objective-C++ Source:
或者直接改后缀为.mm。