theos中objc/objc++混编链接issue

虽然还没具体去看为什么,不过使用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生成的符号。

屏幕快照 2015-04-02 下午12.35.53

可以看到,以ObjC编译时,plus的符号是_plus
而以ObjC++编译时,plus的符号是__Z4plusii

那么main.mm呢

屏幕快照 2015-04-02 下午12.40.37

可以看到,倒数第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中,这样编译也会报错:

屏幕快照 2015-04-02 下午1.18.07

解决方法就是把文件的类型手动设定为Objective-C++ Source:

屏幕快照 2015-04-02 下午1.19.23

或者直接改后缀为.mm。

Leave a Reply

Your email address will not be published. Required fields are marked *

6 + fifteen =