IOS了解底層代碼非常重要, 無(wú)論是我們 了解OC原理或者應(yīng)付大廠面試等, 那么第一步肯定是能運(yùn)行起來(lái)蘋(píng)果源碼
這邊主要介紹下蘋(píng)果開(kāi)源源碼的編譯以及調(diào)試
源碼下載地址:
蘋(píng)果objc4-781源碼 https://opensource.apple.com/tarballs/objc4/
由于目前這邊最新的就是 objc4-781, 所以就拿它開(kāi)刀吧 :)

下載之后解壓得到

運(yùn)行objc.xcodeproj, 因?yàn)槲覀兡康氖窃创a上面我們選擇objc, 得到我們第一個(gè)錯(cuò)誤
問(wèn)題1: unable to find sdk 'macosx.internal'

- 解決方法
target → objc → Build Setting → Base SDK → macOS
因?yàn)槟J(rèn)的是 macosx.internal 但是這個(gè)SDK是找不到的, 所以換成macOS的 - 注意:
objc , obc-trampolines這兩個(gè)必須改, 但其實(shí)剩余objc-simulator, objc4_tests 也是macosx.internal找不到的, 所以我建議一起都改下

解決完繼續(xù)運(yùn)行, 得到我們第二個(gè)錯(cuò)誤, 文件找不到問(wèn)題
問(wèn)題2: 'sys/reason.h' file not found

- 解決方法
既然提示找不到, 那我們就造一個(gè), 項(xiàng)目里面創(chuàng)建文件夾, SACommon(名字隨便起)
統(tǒng)一存放找不到文件, 后面還有幾個(gè)提示文件找不到的問(wèn)題
- SACommon下建立sys文件夾, 然后去找reason.h文件

找到 10.15, 當(dāng)然依舊下最新的10.15.6, 別問(wèn)為什么, 老渣男了, 喜歡喜新厭舊

找到xnu這里面有我們想要的reason.h, 可以 command + f 模糊搜索xnu , 找到后點(diǎn)擊下載

(先別著急關(guān)頁(yè)面, 我們之后還會(huì)用到下載其他資源)
- xnu 中找到
bsd → sys → reason.h放入我們剛才建立的SACommon → sys文件夾內(nèi)


- 配置文件檢索路徑:
target → objc → Build Setting → Header Serach Paths中添加搜索路徑$(SRCROOT)/SACommon

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第三個(gè)錯(cuò)誤
問(wèn)題3: mach-o/dyld_priv.h' file not found

- 照舊 SACommon下新建mach-o文件夾, 然后去找dyld_priv.h文件
Apple source10.15.6: https://opensource.apple.com/release/macos-10156.html
2.找到dyld里面有我們想要的dyld_priv.h, command + f 模糊搜索dyld , 找到后點(diǎn)擊下載

- dyld 中找到
include → mach-o → dyld_priv.h放入我們剛才建立的文件夾內(nèi)SACommon → mach-o → dyld_priv.h


- 放入之后, 還需要修改 dyld_priv.h ,在 dyld_priv.h文件頂部加入一下宏:
#define DYLD_MACOSX_VERSION_10_11 0x000A0B00
#define DYLD_MACOSX_VERSION_10_12 0x000A0C00
#define DYLD_MACOSX_VERSION_10_13 0x000A0D00
#define DYLD_MACOSX_VERSION_10_14 0x000A0E00
這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第四個(gè)錯(cuò)誤
問(wèn)題4: 'os/lock_private.h' file not found , dyld_priv.h中 bridgeos(3.0) 報(bào)錯(cuò)


-
先解決這個(gè)bridgeos 3.0這個(gè), Bridge OS是Apple獨(dú)立的T2安全芯片使用的嵌入式操作系統(tǒng), 而在這里我們用不到這個(gè)系統(tǒng)所以刪掉即可
問(wèn)題4-bridgeos(3.0)修改 照舊 SACommon下新建os文件夾, 然后去找lock_private.h文件
Apple source10.15.6: https://opensource.apple.com/release/macos-10156.html
3.找到libplatform里面有我們想要的lock_private.h, command + f 模糊搜索libplatform , 找到后點(diǎn)擊下載

- libplatform 中找到
private → os → lock_private.h放入我們剛才建立的文件夾內(nèi)SACommon → os → lock_private.h


這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第五個(gè)錯(cuò)誤
問(wèn)題5: 'os/base_private.h' file not found
其實(shí)5跟4可以放一起解決, 因?yàn)槎荚?libplatform里面
libplatform 中找到private → os → base_private.h 放入我們剛才建立的文件夾內(nèi) SACommon → os → base_private.h


同樣之后運(yùn)行l(wèi)ock_private也會(huì)報(bào)bridgeos這個(gè)錯(cuò)誤, 去掉即可

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第六個(gè)錯(cuò)誤
問(wèn)題6: 'pthread/tsd_private.h' file not found

- 照舊 SACommon下新建pthread文件夾, 然后去找tsd_private.h文件
Apple source10.15.6: https://opensource.apple.com/release/macos-10156.html
2.找到libpthread里面有我們想要的tsd_private.h, command + f 模糊搜索libpthread , 找到后點(diǎn)擊下載

- libpthread 中找到
private → tsd_private.h放入我們剛才建立的文件夾內(nèi)SACommon → pthread → tsd_private.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第七個(gè)錯(cuò)誤
問(wèn)題7: 'System/machine/cpu_capabilities.h' file not found

- 照舊 SACommon下新建System文件夾,進(jìn)入System在創(chuàng)建machine文件夾, 然后去找cpu_capabilities.h文件
Apple source10.15.6: https://opensource.apple.com/release/macos-10156.html
2.找到xnu們想要的cpu_capabilities.h, command + f 模糊搜索xnu , 找到后點(diǎn)擊下載

- xnu 中找到
osfmk → machine → cpu_capabilities.h放入我們剛才建立的文件夾內(nèi)SACommon → System → machine → cpu_capabilities.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第八個(gè)錯(cuò)誤
問(wèn)題8: 'os/tsd.h' file not found

tsd.h也是在問(wèn)題7 xnu 中,
xnu 中找到
libsysycall → os → tsd.h放入之前建立的文件夾內(nèi)SACommon → os → tsd.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第九個(gè)錯(cuò)誤
問(wèn)題9: 'pthread/spinlock_private.h' file not found

照舊 去找spinlock_private.h文件, 這個(gè)跟問(wèn)題6一樣都在libpthread里面
libpthread 中找到
private → spinlock_private.h放入之前建立的文件夾內(nèi)SACommon → pthread → spinlock_private.h(圖片箭頭標(biāo)錯(cuò)了, 應(yīng)該指向spinlock_private.h :) )

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十個(gè)錯(cuò)誤
問(wèn)題10: 'System/pthread_machdep.h' file not found
- 照舊 去找pthread_machdep.h文件, 這個(gè)在 Libc中
Apple source Libc: https://opensource.apple.com/tarballs/Libc/
2.這里留意下Libc不能下最新的, 里面沒(méi)有這個(gè)spinlock_private.h文件, 這個(gè)里面要下583的這個(gè)command + f 模糊搜索Libc-583 找到后點(diǎn)擊下載

- Libc-583 中找到
pthreads → os → pthread_machdep.h放入之前建立的System內(nèi)SACommon → System → pthread_machdep.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十一個(gè)錯(cuò)誤
問(wèn)題11: 'CrashReporterClient.h' file not found

- 照舊 去找'CrashReporterClient.h文件, 這個(gè)在也在Libc中, 這里也是留意下Libc不能下最新的, 也是沒(méi)有這個(gè) CrashReporterClient.h文件, 在 Libc-825.24中
Apple source Libc: https://opensource.apple.com/tarballs/Libc/

- Libc-825.24 中找到
include → CrashReporterClient.h放入SACommon內(nèi)SACommon → CrashReporterClient.h

3.引入之后CrashReporterClient.h 還是報(bào)找不到問(wèn)題

方法① 需要在 Build Settings -> Preprocessor Macros 中加入LIBC_NO_LIBCRASHREPORTERCLIENT

如果還是報(bào)錯(cuò)(網(wǎng)上看到的)
方法② 直接更改了里面的宏信息 #define LIBC_NO_LIBCRASHREPORTERCLIENT
方法③ 如果還是報(bào)錯(cuò)CrashReporterClient 的問(wèn)題,解決方法是 在BuildSetting --> Other Linker Flags 中去掉CrashReporterClient .
因?yàn)槲疫@邊只是方法① 就已經(jīng)修復(fù)好, 方法②, 方法③我這邊沒(méi)試 :)
這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十二個(gè)錯(cuò)誤
問(wèn)題12: pthread_machdep.h 中 Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int')), Static declaration of '_pthread_has_direct_tsd' follows non-static declaration, Static declaration of '_pthread_getspecific_direct' follows non-static declaration

把報(bào)錯(cuò)的地方注釋掉, 這里注意下一定要注釋全, 別漏代碼

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十三個(gè)錯(cuò)誤
問(wèn)題13: 'objc-shared-cache.h' file not found

- 在之前問(wèn)題3下載的dyld里面找到
include → objc-shared-cache.h放入SACommon內(nèi)SACommon → objc-shared-cache.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十四個(gè)錯(cuò)誤
問(wèn)題14: objc-errors.mm中報(bào)錯(cuò) '_simple.h' file not found
- 在之前問(wèn)題4下載的libplatform里面找到
private → _simple.h放入SACommon內(nèi)SACommon → _simple.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十五個(gè)錯(cuò)誤
問(wèn)題15: kern/restartable.h

- SACommon 中新建kern文件夾, 在之前問(wèn)題2下載的xnu里面找到
osfmk → kern放入SACommon內(nèi)SACommon → kern → restartable.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十六個(gè)錯(cuò)誤
問(wèn)題16: 'Block_private.h' file not found

Apple source : https://opensource.apple.com/release/macos-1015.html
1.command + f 模糊搜索libclosure 找到后點(diǎn)擊下載, 里面有我們想要的Block_private.h

- 在剛才下載的 libclosure 找到
Block_private.h放入SACommon內(nèi)SACommon → Block_private.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十七個(gè)錯(cuò)誤
問(wèn)題17: Mismatch in debug-ness macros

這個(gè)簡(jiǎn)單, 注釋掉objc-runtime.mm中的#error mismatch in debug-ness macros即可
這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十八個(gè)錯(cuò)誤
問(wèn)題18: libobjc.order 路徑問(wèn)題

targets → Build Settings → Order File 添加 $(SRCROOT)/libobjc.order

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十九個(gè)錯(cuò)誤
問(wèn)題19: /xcodebuild:1:1: SDK "macosx.internal" cannot be located. 編譯腳本問(wèn)題

targets → Build Phases → Run Script 中macosx.internal 改成 macosx

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, OK, 沒(méi)有再報(bào)錯(cuò), 那么接下來(lái)我們就可以加些東西來(lái)進(jìn)行編譯調(diào)試
編譯調(diào)試環(huán)節(jié)
targets 點(diǎn)擊 "+" 新建 target: SATest



綁定依賴(lài)關(guān)系 Dependencies → objc, Link Binary With Libraries → libobjc.A.dylib



源碼調(diào)試環(huán)節(jié)
在之前建立的SATest中 創(chuàng)建 SAPerson對(duì)象(名字隨便取)

targets → SATest → Build Phases → Compile Sources 中main.m 放在最上面方便斷點(diǎn)調(diào)試

接下來(lái)main.m 中引入 SAPerson.h頭文件, 運(yùn)行項(xiàng)目選擇SATest 就可以愉快的進(jìn)行源碼調(diào)試

需要總共下載項(xiàng)目

