clang 跨平台编译 iOS/macOS arm64/x86_64

May 19, 2021 • 预计阅读时间 2 分钟

Target

不同的目标平台对应不同的 -target $triple 参数:

iOS 平台:

armv7:-target arm64-apple-darwin

arm64:-target armv7-apple-darwin

macOS 平台:

i386:-target i386-apple-macos

x86_64:-target x86_64-apple-macos

arm64:-target arm64-apple-macos

Mac Catalyst(UIKit for macOS):

x86_64:-target x86_64-apple-ios-macabi

arm64:-target arm64-apple-ios-macabi

Arch

还需要指定 -arch $arch 参数:

x86_64:-arch x86_64

i386:-arch i386

arm64:-arch arm64

armv7:-arch armv7

以上架构中的 armv7 i386 常用于 iPhone5 和其对应的模拟器,现在已经被淘汰了。

相同平台(target 和 sysroot 需要一样)下可以指定多个 arch 参数,比如:-arch armv7 -arch arm64

Sysroot

交叉编译中,在使用 -I-L 指定头文件和库文件的目录时,clang 会基于 -isysroot $path 为根路径进行查找,所以还需要正确的配置这个参数:

iOS:xcrun --sdk iphoneos --show-sdk-path

iOS 模拟器:xcrun --sdk iphonesimulator --show-sdk-path

macOS:xcrun --sdk macosx --show-sdk-path

也可以通过环境变量 SDKROOT 的值指定路径。

Deployment target

Apple 的程序有个特点就是限定运行的最低平台版本。

iOS:-miphoneos-version-min=$version

iOS 模拟器:-miphonesimulator-version-min=$version

macOS:-mmacosx-version-min=$version

也可以通过环境变量指定:

iOS:IPHONEOS_DEPLOYMENT_TARGET

macOS:MAXOSX_DEPLOYMENT_TARGET

BitCode

-fembed-bitcode

Example

iOS 模拟器(i386):

clang -target i386-apple-darwin \
      -arch i386 \
      -isysroot `xcrun --sdk iphonesimulator --show-sdk-path` \
      -miphonesimulator-version-min=9.0 \
      -fembed-bitcode \
      main.c

iOS 模拟器(x86_64):

clang -target x86_64-apple-darwin \
      -arch x86_64 \
      -isysroot `xcrun --sdk iphonesimulator --show-sdk-path` \
      -miphonesimulator-version-min=9.0 \
      -fembed-bitcode \
      main.c

iOS (armv7):

clang -target armv7-apple-darwin \
      -arch armv7 \
      -isysroot `xcrun --sdk iphoneos --show-sdk-path` \
      -miphoneos-version-min=9.0 \
      -fembed-bitcode \
      main.c

iOS (arm64):

clang -target arm64-apple-darwin \
      -arch arm64 \
      -isysroot `xcrun --sdk iphoneos --show-sdk-path` \
      -miphoneos-version-min=9.0 \
      -fembed-bitcode \
      main.c

以上 4 条命令可以简化合并,对于相同的 sysroot,可以一次指定多个 arch:

clang -target x86_64-apple-darwin \
      -arch x86_64 -arch i386 \
      -isysroot `xcrun --sdk iphonesimulator --show-sdk-path` \
      -miphonesimulator-version-min=9.0 \
      -fembed-bitcode \
      main.c
clang -target arm64-apple-darwin \
      -arch arm64 -arch armv7 \
      -isysroot `xcrun --sdk iphoneos --show-sdk-path` \
      -miphoneos-version-min=9.0 \
      -fembed-bitcode \
      main.c

同时编译支持 Intel 和 Apple Silicon 的 macOS 程序:

clang -target x86_64-apple-macos \
      -arch arm64 -arch x86_64 \
      -isysroot `xcrun --sdk macosx --show-sdk-path` \
      -mmacosx-version-min=10.9 \
      -fembed-bitcode \
      main.c

Mac Catalyst(UIKit for macOS):

clang -target x86_64-apple-ios-macabi \
      -arch arm64 -arch x86_64 \
      -isysroot `xcrun --sdk macosx --show-sdk-path` \
      -miphoneos-version-min=13.0 \
      -fembed-bitcode \
      main.c

参考资料

https://clang.llvm.org/docs/CrossCompilation.html

clang
版权声明:如果转发请带上本文链接和注明来源。

lvv.me

iOS/macOS Developer

Swift:了解一下 defer

从包含多架构的 framework 生成 xcframework