前言
为什么会想要调试源码?
苹果开源了部分源码, 但相似内容太多, 根本找不到代码见的对应联系, 如果能像自己工程相同进行跳转那多好哇~~
苹果源码开源地址: opensource.apple.com/
本文将以macOS 11.2/objc4-818.2的源码进行装备

源码装备
首要选中运转target: objc > My Mac
然后⌘+b进行编译
翻一下爆红的点看看都有哪些错误, 然后找到下面对应的解决方案~
编译报错 ‘sys/reason.h’ file not found

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


解决方案: 谷歌中输入reason.h site:opensource.apple.com定向检索

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


点进去查找成果里边, 进行”文件另存为”下载
下载后, 在objc源码根目录中创立一个文件夹”ZKLib”,
然后由于reason.h文件是在sys目录下的, 所以咱们在”ZKLib”目录下创立”sys”文件夹, 并把reason.h放到该目录里边(如下图)

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


接下来咱们在源码工程 target >objc > Build Settings中查找”Header Search Paths”, 给Debug和Release都加上$(SRCROOT)/ZKLib即可
(不需要把ZKLib拉进源码Xcode工程里哦! )\

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理

然后继续⌘+b编译

其它文件缺失
咱们会发现相同的报错还有\

'mach-o/dyld_priv.h' file not found
'os/lock_private.h' file not found
'os/base_private.h' file not found
'pthread/tsd_private.h' file not found
'System/machine/cpu_capabilities.h' file not found
'os/tsd.h' file not found
'pthread/spinlock_private.h' file not found
'System/pthread_machdep.h' file not found
'CrashReporterClient.h' file not found
'objc-shared-cache.h' file not found
'_simple.h' file not found
'Block_private.h' file not found

这些报错的解决方案都跟上面的相同处理

objc源码文件代码修正
CrashReporterClient明明放进去了还是”file not found”
打开CrashReporterClient.h文件,

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理

在#ifdef前面加上以下代码:

#define LIBC_NO_LIBCRASHREPORTERCLIENT

注释掉一些妨碍编译的代码
总的来说一共有这么多:

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理

详细都有:
objc-cache.mm

87行:
#if TARGET_OS_OSX
//#include <Cambria/Traps.h>
//#include <Cambria/Cambria.h>
#endif
1120行:
//#if TARGET_OS_OSX
// if (oah_is_current_process_translated()) {
// kern_return_t ret = objc_thread_get_rip(threads[count], (uint64_t*)&pc);
// if (ret != KERN_SUCCESS) {
// pc = PC_SENTINEL;
// }
// } else {
// pc = _get_pc_for_thread (threads[count]);
// }
//#else
pc = _get_pc_for_thread (threads[count]);
//#endif

NSObject.mm

42行:
//#include <os/feature_private.h>
extern "C" {
//#include <os/reason_private.h>
//#include <os/variant_private.h>
}
1185行:
// if (DebugPoolAllocation || sdkIsAtLeast(10_12, 10_0, 10_0, 3_0, 2_0)) {
// // OBJC_DEBUG_POOL_ALLOCATION or new SDK. Bad pop is fatal.
// _objc_fatal
// ("Invalid or prematurely-freed autorelease pool %p.", token);
// }

objc-runtime.mm

36行:
//#include <os/feature_private.h> // os_feature_enabled_simple()
379行:
// if (!dyld_program_sdk_at_least(dyld_fall_2020_os_versions))
// DisableAutoreleaseCoalescingLRU = true;
444行:
// if (!os_feature_enabled_simple(objc4, preoptimizedCaches, true)) {
// DisablePreoptCaches = true;
// }

objc-class.mm

896行:
// LINKER_SET_FOREACH(_dupi, const objc_duplicate_class **, "__objc_dupclass") {
// const objc_duplicate_class *dupi = *_dupi;
//
// if (strcmp(dupi->name, name) == 0) {
// return;
// }
// }

objc-os.mm

31行:
//#include "objc-bp-assist.h"
\
567行:
// if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_13)) {
// DisableInitializeForkSafety = true;
// if (PrintInitializing) {
// _objc_inform("INITIALIZE: disabling +initialize fork "
// "safety enforcement because the app is "
// "too old.)");
// }
// }

objc-runtime-new.mm

3547行:
// if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_11)) {
// DisableNonpointerIsa = true;
// if (PrintRawIsa) {
// _objc_inform("RAW ISA: disabling non-pointer isa because "
// "the app is too old.");
// }
// }
8328行:
if (!DisableTaggedPointerObfuscation /**&& dyld_program_sdk_at_least(dyld_fall_2018_os_versions)*/) {



编译报错 Can’t open order file: libobjc.order
详细来说是这么一个报错:

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


解决方案:
在源码工程 target >objc > Build Settings中查找”Order File”, 把Debug和Release的内容都改成$(SRCROOT)/libobjc.order即可

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理



编译报错 Library not found for -lCrashReporterClient
在源码工程 target >objc > Build Settings中查找”Other Linker Flags”, 把Debug和Release中的-lCrashReporterClient都删掉

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理



编译报错 SDK “macosx.internal” cannot be located.
详细来说是这么一个报错:

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


解决方案:
在源码工程 target >objc > Build Phases中找到Run Script(markgc)里边, 把脚本中的macosx.internal改成macosx即可

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理



编译报错 library not found for -loah
详细来说是这么一个报错:

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


解决方案:
在源码工程 target >objc > Build Settings中查找”Other Linker Flags”, 把Debug和Release里的-loah删掉

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理



编译报错 ‘_static_assert’ declared as an array with a negative size
详细来说是这么一个报错:

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


解决方案:
把报错的这两行注释掉~~

编译成功!
诶嘿嘿~
是不是突然间看到”Build Successed”就很振奋了, 横竖我是振奋了


编译调试
新建一个target
选择macOS里边的Command Line Tool (咱们这儿不需要界面)

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理

将target命名为ZKBuild (如下图)

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理



绑定依赖联系
在源码工程 target >ZKBuild > Build Phases中
在Dependencies 增加objc

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理



打断点进行调试
切换运转target: ZKBuild > My Mac
在main.m代码中打断点, 并按⌘+r运转

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理

此时按

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理

(step into)进入这一行代码里边

objc4-818.2源码太爽了,没什么比苹果的源码更直接更真理


来到objc源码里边, 则表示现已能成功调试objc源码