IOS了解底層代碼非常重要, 無論是我們 了解OC原理或者應(yīng)付大廠面試等, 那么第一步肯定是能運行起來蘋果源碼
這邊主要介紹下蘋果開源源碼的編譯以及調(diào)試
源碼下載地址:
由于目前這邊最新的就是 objc4-781, 所以就拿它開刀吧 :)
下載之后解壓得到
運行objc.xcodeproj, 因為我們目的是源碼上面我們選擇objc, 得到我們第一個錯誤
問題1: unable to find sdk 'macosx.internal'
- 解決方法
target → objc → Build Setting → Base SDK → macOS
因為默認的是 macosx.internal 但是這個SDK是找不到的, 所以換成macOS的 - 注意:
objc , obc-trampolines
這兩個必須改, 但其實剩余objc-simulator, objc4_tests 也是macosx.internal找不到的, 所以我建議一起都改下
解決完繼續(xù)運行, 得到我們第二個錯誤, 文件找不到問題
問題2: 'sys/reason.h' file not found
- 解決方法
既然提示找不到, 那我們就造一個, 項目里面創(chuàng)建文件夾, SACommon(名字隨便起)
統(tǒng)一存放找不到文件, 后面還有幾個提示文件找不到的問題
- SACommon下建立sys文件夾, 然后去找reason.h文件
找到 10.15, 當(dāng)然依舊下最新的10.15.6, 別問為什么, 老渣男了, 喜歡喜新厭舊
找到xnu這里面有我們想要的reason.h, 可以 command + f
模糊搜索xnu
, 找到后點擊下載
(先別著急關(guān)頁面, 我們之后還會用到下載其他資源)
- xnu 中找到
bsd → sys → reason.h
放入我們剛才建立的SACommon → sys
文件夾內(nèi)
- 配置文件檢索路徑:
target → objc → Build Setting → Header Serach Paths
中添加搜索路徑$(SRCROOT)/SACommon
這個問題解決, 我們再運行, 得到我們第三個錯誤
問題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
, 找到后點擊下載
- 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
這個問題解決, 我們再運行, 得到我們第四個錯誤
問題4: 'os/lock_private.h' file not found
, dyld_priv.h中 bridgeos(3.0) 報錯
-
先解決這個bridgeos 3.0這個, Bridge OS是Apple獨立的T2安全芯片使用的嵌入式操作系統(tǒng), 而在這里我們用不到這個系統(tǒng)所以刪掉即可
問題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
, 找到后點擊下載
- libplatform 中找到
private → os → lock_private.h
放入我們剛才建立的文件夾內(nèi)SACommon → os → lock_private.h
這個問題解決, 我們再運行, 得到我們第五個錯誤
問題5: 'os/base_private.h' file not found
其實5跟4可以放一起解決, 因為都在 libplatform里面
libplatform 中找到private → os → base_private.h
放入我們剛才建立的文件夾內(nèi) SACommon → os → base_private.h
同樣之后運行l(wèi)ock_private也會報bridgeos這個錯誤, 去掉即可
這個問題解決, 我們再運行, 得到我們第六個錯誤
問題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
, 找到后點擊下載
- libpthread 中找到
private → tsd_private.h
放入我們剛才建立的文件夾內(nèi)SACommon → pthread → tsd_private.h
這個問題解決, 我們再運行, 得到我們第七個錯誤
問題7: 'System/machine/cpu_capabilities.h' file not found
- 照舊 SACommon下新建System文件夾,進入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
, 找到后點擊下載
- xnu 中找到
osfmk → machine → cpu_capabilities.h
放入我們剛才建立的文件夾內(nèi)SACommon → System → machine → cpu_capabilities.h
這個問題解決, 我們再運行, 得到我們第八個錯誤
問題8: 'os/tsd.h' file not found
tsd.h也是在問題7 xnu 中,
xnu 中找到
libsysycall → os → tsd.h
放入之前建立的文件夾內(nèi)SACommon → os → tsd.h
這個問題解決, 我們再運行, 得到我們第九個錯誤
問題9: 'pthread/spinlock_private.h' file not found
照舊 去找spinlock_private.h文件, 這個跟問題6一樣都在libpthread里面
libpthread 中找到
private → spinlock_private.h
放入之前建立的文件夾內(nèi)SACommon → pthread → spinlock_private.h
(圖片箭頭標錯了, 應(yīng)該指向spinlock_private.h :) )
這個問題解決, 我們再運行, 得到我們第十個錯誤
問題10: 'System/pthread_machdep.h' file not found
- 照舊 去找pthread_machdep.h文件, 這個在 Libc中
Apple source Libc: https://opensource.apple.com/tarballs/Libc/
2.這里留意下Libc不能下最新的, 里面沒有這個spinlock_private.h文件, 這個里面要下583的這個command + f
模糊搜索Libc-583
找到后點擊下載
- Libc-583 中找到
pthreads → os → pthread_machdep.h
放入之前建立的System內(nèi)SACommon → System → pthread_machdep.h
這個問題解決, 我們再運行, 得到我們第十一個錯誤
問題11: 'CrashReporterClient.h' file not found
- 照舊 去找'CrashReporterClient.h文件, 這個在也在Libc中, 這里也是留意下Libc不能下最新的, 也是沒有這個 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 還是報找不到問題
方法① 需要在 Build Settings -> Preprocessor Macros
中加入LIBC_NO_LIBCRASHREPORTERCLIENT
如果還是報錯(網(wǎng)上看到的)
方法② 直接更改了里面的宏信息 #define LIBC_NO_LIBCRASHREPORTERCLIENT
方法③ 如果還是報錯CrashReporterClient 的問題,解決方法是 在BuildSetting --> Other Linker Flags 中去掉CrashReporterClient .
因為我這邊只是方法① 就已經(jīng)修復(fù)好, 方法②, 方法③我這邊沒試 :)
這個問題解決, 我們再運行, 得到我們第十二個錯誤
問題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
把報錯的地方注釋掉, 這里注意下一定要注釋全, 別漏代碼
這個問題解決, 我們再運行, 得到我們第十三個錯誤
問題13: 'objc-shared-cache.h' file not found
- 在之前問題3下載的dyld里面找到
include → objc-shared-cache.h
放入SACommon內(nèi)SACommon → objc-shared-cache.h
這個問題解決, 我們再運行, 得到我們第十四個錯誤
問題14: objc-errors.mm中報錯 '_simple.h' file not found
- 在之前問題4下載的libplatform里面找到
private → _simple.h
放入SACommon內(nèi)SACommon → _simple.h
這個問題解決, 我們再運行, 得到我們第十五個錯誤
問題15: kern/restartable.h
- SACommon 中新建kern文件夾, 在之前問題2下載的xnu里面找到
osfmk → kern
放入SACommon內(nèi)SACommon → kern → restartable.h
這個問題解決, 我們再運行, 得到我們第十六個錯誤
問題16: 'Block_private.h' file not found
Apple source : https://opensource.apple.com/release/macos-1015.html
1.command + f
模糊搜索libclosure
找到后點擊下載, 里面有我們想要的Block_private.h
- 在剛才下載的 libclosure 找到
Block_private.h
放入SACommon內(nèi)SACommon → Block_private.h
這個問題解決, 我們再運行, 得到我們第十七個錯誤
問題17: Mismatch in debug-ness macros
這個簡單, 注釋掉objc-runtime.mm中的#error mismatch in debug-ness macros即可
這個問題解決, 我們再運行, 得到我們第十八個錯誤
問題18: libobjc.order
路徑問題
targets → Build Settings → Order File
添加 $(SRCROOT)/libobjc.order
這個問題解決, 我們再運行, 得到我們第十九個錯誤
問題19: /xcodebuild:1:1: SDK "macosx.internal" cannot be located.
編譯腳本問題
targets → Build Phases → Run Script
中macosx.internal
改成 macosx
這個問題解決, 我們再運行, OK, 沒有再報錯, 那么接下來我們就可以加些東西來進行編譯調(diào)試
編譯調(diào)試環(huán)節(jié)
targets
點擊 "+" 新建 target: SATest
綁定依賴關(guān)系 Dependencies → objc
, Link Binary With Libraries → libobjc.A.dylib
源碼調(diào)試環(huán)節(jié)
在之前建立的SATest中 創(chuàng)建 SAPerson對象(名字隨便取)
targets → SATest → Build Phases → Compile Sources
中main.m
放在最上面方便斷點調(diào)試
接下來main.m 中引入 SAPerson.h頭文件, 運行項目選擇SATest 就可以愉快的進行源碼調(diào)試
需要總共下載項目