苹果在 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 Only
Other 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