苹果在 OpenSource 官网 上开放了一部分源码,我们可以同过这个官网,下载我们所需要的东西,比如 objc 的源码,通过源码能够方便我们了解iOS的底层原理。想要快速的了解我们的 runtime,搭建一个可以编译调试的 runtime ,能够向我们的效率倍增。下面对针对最新的 objc4-781.2 进行编译
准备工作
- mac OS 10.15
- Xcode 11
- objc4-781.2
- dyld-733.8
- Libc-1353.60.8
- Libc-825.40.1 2
- launchd-106.10
- libauto-187
- libclosure-74
- libdispatch-1173.60.1
- libplatform-220
- libpthread-416.60.2
- xnu-6153.81.5
以上资料都可以通过 Apple source 获取。
将文件解压到同一个目录中,这里用 OpenSource 来作为示例。

开始配置
直接编译 ojbc4-781.2 会出现如下报错
unable to find sdk ‘macosx.internal’
更改 Build Settings 里的 Base SDK 选项卡的内容
解决 i386 报错, 将
objc-trampolines中的Build Setting选项Architectures中的值切换为Standard Architectures(64-bit Intel)
重新编译
文件查漏补缺
这个时候会提示 'sys/reason.h' file not found 错误, 如下图:

在项目目录下创建一个 include 文件夹,用于存放需要导入工程的文件,并且把它添加到项目 Header search Paths 中。操作步骤 objc->TARGETS->ojbc-> Build Settings 搜索 header search paths 添加 $(SRCROOT)/include
接下来,我们用命令 cd 到 OpenSource 文件夹中 (PS: OpenSource 文件夹存放了准备工作中下载的文件). 通过 find . -name 'reason.h' 命令去查找 sys/reason.h 文件. 确认文件个数和名字是否正确,通过以下命令去移动工程所需的文件到 include 文件夹中
1 | cd [OpenSource文件夹的路径] |
根据提示一次将下列文件按照上面的方法导入到 objc4-781.2 里的 include 文件夹中
<sys/reason.h><mach-o/dyld_priv.h><os/lock_private.h><os/base_private.h><pthread/tsd_private.h><System/machine/cpu_capabilities.h>这个选择./xnu-6153.81.5/osfmk/machine/cpu_capabilities.h<os/tsd.h>这个选择./xnu-6153.81.5/libsyscall/os/tsd.h<pthread/spinlock_private.h><System/pthread_machdep.h>这个文件在Libc-825.40.1中可以找到,在最新的Libc中会找不到<CrashReporterClient.h>这个文件在Libc-825.40.1中可以周到,在最新的Libc中会找不到,导入后依旧异常,查看下面的 CrashReporterClient 异常处理<objc-shared-cache.h><_simple.h>这个文件夹在Libc-825.40.1和libplatform-220文件夹中都存在,这里选择libplatform-220这个文件夹中的_simple.h文件<restartable.h><Block_private.h>
CrashReporterClient 异常处理
CrashReporterClient.h文件导入后,依旧会提示错误file not found错误, 需要再Build Settings->Preprocessor Macros中加入:LIBC_NO_LIBCRASHREPORTERCLIENT
其他异常处理
编译时提示 typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int')), 在 include 文件夹下,使用 grep 命令,查找重复定义的文件
1 | grep -rne "typedef.*pthread_lock_t" . |
这里我们选择注释掉 pthread_machdep.h 文件中的定义即可.
同样 提示 Static declaration of '_pthread_has_direct_tsd' follows non-static declaration 我们也通过 grep 命令查重
1 |
|
这里我们都选择注释掉 pthread_machdep.h 文件中的重复定义
编译遇到 Expected ',' 错误的时候,注释掉本行,或者复制上一个值,代替本行代码. 错误如下图:

ps: 解决了半天,暂时还没有找到更好的办法,不影响编译
libobjc.order 路径问题
- 选择
target -> objc -> Build Settings - 在工程目录的
Order File选项中,添加搜索路径$(SRCROOT)/libobjc.order
lCrashReporterClient 编译不到
Library not found for -lCrashReporterClient
- 选择
target -> objc -> Build Settings - 在
Other Linker Flags中删除-lCrashReporterClient(Debug和Release都删了)
_objc_opt_class 无法编译
Undefined symbol: _objc_opt_class
选择一个macOSX 的早期版本
Xcode 脚本编译问题
/xcodebuild:1:1: SDK “macosx.internal” cannot be located.
/xcrun:1:1: sh -c ‘/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk macosx.internal -find clang++ 2> /dev/null’ failed with exit code 16384: (null) (errno=No such file or directory)
/xcrun:1:1: unable to find utility “clang++”, not a developer tool or in PATH
- 选择
target -> objc -> Build Phases -> Run Script(markgc) - 把脚本文本
macosx.internal改成macosx
ObjectiveC.apinotes 异常
- 选择
target -> objc -> Build Settings Text-Based InstallAPI Verification Model中添加搜索路径Errors OnlyOther Text-Based InstallAPI Flags清空所有内容
编译成功
经过重重难关,终于迎来了我们的编译成功Build Success
调试编译
新建一个 Target , 然后添加依赖, 如下图:

Xcode 11 新特性
新建好我们的 Target, 这里需要注意,要进行一下设置
target -> objc -> Build Settings -> Enable Hardened Runtime -> NO`
https://developer.apple.com/documentation/security/hardened_runtime