Date Notes
2019-05-17 首次提交
2019-06-15 增加常用参数列表
2019-11-30 细节补充

Solution

➜  ~ clang --version
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Xcode 中,C/C++/Obj-C/C++ 的编译器是 clang,其通过 -rewrite-objc 参数可以将 Obj-C 代码翻译为 C++ 代码,即 clang -rewrite-objc main.m -o main.cpp;也可以结合 xcrun -sdk 命令设置编译所基于的 SDK。

clang –help | grep -rewrite-objc

Options Usage
-arch arm64 指定编译架构
-framework UIKit 依赖 UIKit 框架
-fobjc-arc 使用 ARC(自动引用计数)模式
-fnoobjc-arc 使用 MRC(手动引用计数)模式
-fobjc-runtime=ios-12.0.0 指定运行时环境

其可以搭配很多参数,如 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp -framework UIKit,即使用 iOS SDK 并集成 UIKit 框架将 main.m 翻译为 arm64 架构的 C++ 代码。

虽然如上图描述 clang 可以将 Obj-C 代码翻译为 C++,但其实翻译后的大部分代码都属于 C 语言,比如 Obj-C 的类,其本质是 C 语言中的结构体。而 -rewrite-objc 的存在是因为 Windows 上的 Visual Studio 并没有可以直接编译 Obj-C 代码的编译器,所以 clang 将 Obj-C 转为 C/C++,便于其他平台的 C/C++ 编译器进行编译。需要注意的是,在使用 Xcode 构建 Obj-C 项目时并不会先将 Obj-C 代码翻译为 C++,这是因为 clang 编译器支持直接编译 Obj-C 代码。

需要注意的是,由于 .m 文件并不兼容 C++,因此部分 C++ 关键字在 .m 文件中可能会作为他用(比如 this),但不影响 Xcode 编译。而此时翻译将出现错误,因此需要翻译的代码要尽量避免使用与 C++ 关键字冲突的命名。

Reference