IOS底層(一): objc4-781 源碼編譯以及調(diào)試

OC底層源碼/原理合集

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)刀吧 :)

objc4-781源碼

下載之后解壓得到

objc4-781項(xiàng)目

運(yùn)行objc.xcodeproj, 因?yàn)槲覀兡康氖窃创a上面我們選擇objc, 得到我們第一個(gè)錯(cuò)誤

問(wèn)題1: unable to find sdk 'macosx.internal'

問(wèn)題1
  • 解決方法 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找不到的, 所以我建議一起都改下
問(wèn)題1解決方法

解決完繼續(xù)運(yùn)行, 得到我們第二個(gè)錯(cuò)誤, 文件找不到問(wèn)題

問(wèn)題2: 'sys/reason.h' file not found

問(wèn)題2
  • 解決方法

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

  1. SACommon下建立sys文件夾, 然后去找reason.h文件
問(wèn)題2-建立文件夾

Apple source: https://opensource.apple.com

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


問(wèn)題2-找macOs10.15

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

問(wèn)題2-找xnu

(先別著急關(guān)頁(yè)面, 我們之后還會(huì)用到下載其他資源)

  1. xnu 中找到bsd → sys → reason.h 放入我們剛才建立的SACommon → sys 文件夾內(nèi)
問(wèn)題2-找到reason.png

問(wèn)題2-放入reason.png
  1. 配置文件檢索路徑: target → objc → Build Setting → Header Serach Paths中添加搜索路徑 $(SRCROOT)/SACommon
問(wèn)題2-配置路徑

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第三個(gè)錯(cuò)誤

問(wèn)題3: mach-o/dyld_priv.h' file not found

問(wèn)題3
  1. 照舊 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)擊下載

問(wèn)題3-找到dyld
  1. dyld 中找到include → mach-o → dyld_priv.h 放入我們剛才建立的文件夾內(nèi) SACommon → mach-o → dyld_priv.h
問(wèn)題3-找到dyld_priv.h
問(wèn)題3-放入dyld_priv.h
  1. 放入之后, 還需要修改 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ò)

問(wèn)題4.png
問(wèn)題4-bridgeos(3.0).png
  1. 先解決這個(gè)bridgeos 3.0這個(gè), Bridge OS是Apple獨(dú)立的T2安全芯片使用的嵌入式操作系統(tǒng), 而在這里我們用不到這個(gè)系統(tǒng)所以刪掉即可


    問(wèn)題4-bridgeos(3.0)修改
  2. 照舊 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)擊下載

問(wèn)題4-libplatform

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

這個(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

問(wèn)題5-base_private
問(wèn)題5-放入base_private.png

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


bridgeos(4.0).png

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第六個(gè)錯(cuò)誤

問(wèn)題6: 'pthread/tsd_private.h' file not found

問(wèn)題6.png
  1. 照舊 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)擊下載

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

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第七個(gè)錯(cuò)誤

問(wèn)題7: 'System/machine/cpu_capabilities.h' file not found

問(wèn)題7
  1. 照舊 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
  1. xnu 中找到osfmk → machine → cpu_capabilities.h 放入我們剛才建立的文件夾內(nèi) SACommon → System → machine → cpu_capabilities.h
放入cpu_capabilities.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第八個(gè)錯(cuò)誤

問(wèn)題8: 'os/tsd.h' file not found

問(wèn)題8.png
  1. tsd.h也是在問(wèn)題7 xnu 中,

  2. xnu 中找到libsysycall → os → tsd.h 放入之前建立的文件夾內(nèi) SACommon → os → tsd.h

放入tsd

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第九個(gè)錯(cuò)誤

問(wèn)題9: 'pthread/spinlock_private.h' file not found

問(wèn)題9.png
  1. 照舊 去找spinlock_private.h文件, 這個(gè)跟問(wèn)題6一樣都在libpthread里面

  2. libpthread 中找到private → spinlock_private.h 放入之前建立的文件夾內(nèi) SACommon → pthread → spinlock_private.h (圖片箭頭標(biāo)錯(cuò)了, 應(yīng)該指向spinlock_private.h :) )

放入spinlock_private

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十個(gè)錯(cuò)誤

問(wèn)題10: 'System/pthread_machdep.h' file not found

  1. 照舊 去找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
  1. Libc-583 中找到pthreads → os → pthread_machdep.h 放入之前建立的System內(nèi) SACommon → System → pthread_machdep.h
放入pthread_machdep.h

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十一個(gè)錯(cuò)誤

問(wèn)題11: 'CrashReporterClient.h' file not found

問(wèn)題11
  1. 照舊 去找'CrashReporterClient.h文件, 這個(gè)在也在Libc中, 這里也是留意下Libc不能下最新的, 也是沒(méi)有這個(gè) CrashReporterClient.h文件, 在 Libc-825.24中

Apple source Libc: https://opensource.apple.com/tarballs/Libc/

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

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


CrashReporterClient.h not found

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

Preprocessor Macros

如果還是報(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

pthread_machdep

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


注釋

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十三個(gè)錯(cuò)誤

問(wèn)題13: 'objc-shared-cache.h' file not found

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

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十四個(gè)錯(cuò)誤

問(wèn)題14: objc-errors.mm中報(bào)錯(cuò) '_simple.h' file not found

  1. 在之前問(wèn)題4下載的libplatform里面找到private → _simple.h 放入SACommon內(nèi) SACommon → _simple.h
放入_simple.h

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

問(wèn)題15: kern/restartable.h

問(wèn)題15
  1. SACommon 中新建kern文件夾, 在之前問(wèn)題2下載的xnu里面找到osfmk → kern 放入SACommon內(nèi) SACommon → kern → restartable.h
5960B4FC-535A-4817-AB89-72FB12B72E12.png

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十六個(gè)錯(cuò)誤

問(wèn)題16: 'Block_private.h' file not found

問(wèn)題16

Apple source : https://opensource.apple.com/release/macos-1015.html

1.command + f 模糊搜索libclosure 找到后點(diǎn)擊下載, 里面有我們想要的Block_private.h

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

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十七個(gè)錯(cuò)誤

問(wèn)題17: Mismatch in debug-ness macros

問(wèn)題17

這個(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)題

問(wèn)題18.png

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

libobjc.order

這個(gè)問(wèn)題解決, 我們?cè)龠\(yùn)行, 得到我們第十九個(gè)錯(cuò)誤

問(wèn)題19: /xcodebuild:1:1: SDK "macosx.internal" cannot be located. 編譯腳本問(wèn)題

問(wèn)題19

targets → Build Phases → Run Scriptmacosx.internal 改成 macosx

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

編譯1
編譯2
編譯3

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

編譯4
編譯5
編譯6

源碼調(diào)試環(huán)節(jié)

在之前建立的SATest中 創(chuàng)建 SAPerson對(duì)象(名字隨便取)

源碼調(diào)試1

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

源碼調(diào)試2

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


源碼調(diào)試3

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


總結(jié).png

編譯好的objc4-781源碼下載
編譯好的objc4-818源碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容