OC底層原理二:objc源碼的編譯運行

上一篇講到了如何定位底層源碼的方法位置,同時下載了objc4-781源碼。那么試想如果可以讓源碼編譯運行起來,那是不是會大大提高我們探究底層實現(xiàn)的效率,而且會更加直觀。

當(dāng)前環(huán)境

  • mac os 10.15.2
  • Xcode 11.7
  • objc4-781

依賴文件

下圖里的文件通過蘋果開源文檔objc4-781對應(yīng)的macOS 10.15.1里基本都能搜到,除了lauchd-106.10需要在macOS 10.4.4.x86版本中下載。 Libc-583需要在macOS 10.6.2版本下載。

依賴文件.png

下載好objc4-781后,我們首先選中objc,將objc-simulator和objc-tramponlines兩個targets刪掉,防止影響。

objc

objc-delete.png

問題一:unable to find sdk 'macosx.internal'

error-1.png

處理:全局搜索macosx.internal,將macosx.internal替換為當(dāng)前環(huán)境mac os 10.15

deal-1

重新編譯。

問題二:'sys/reason.h' file not found

error-2.png

處理: 在下載的依賴文件夾中,找到文件:xnu-6153.41.3 -> bsd -> sys -> reason.h。在objc4-781的根目錄下新建defaultfile文件夾,在defaultfile中創(chuàng)建sys文件夾,將reason.h文件拷貝到sys文件夾中。最后在頭文件路徑里添加reason.h的路徑,如下圖target->objc->Build Settings 搜索 header_search Paths, 添加$(SRCROOT)/defaultfile。

sy/reason

重新編譯。

問題三:'mach-o/dyld_priv.h' file not found
處理方法和問題二一樣:在defaultfile文件夾中,創(chuàng)建mach-o文件夾。在下載的依賴文件夾中,找到文件:dyld-733.6 -> include -> mach-o -> dyld_priv.h,復(fù)制到defaultfile/mach-o文件夾中。最后AddFile將mach-o添加到bundle的defaultfile文件夾下。

問題四:'os/lock_private.h' file not found
處理方法仍然同上:在defaultfile文件夾中,創(chuàng)建os文件夾。在下載的依賴文件夾中,找到文件:libplatform-220 --> private --> os --> lock_private.h 和 base_private.h,復(fù)制到defaultfile/os文件夾中。最后AddFile將os添加到bundle的defaultfile文件夾下。

重新編譯。

問題五:dyld_priv.h 報了8個 Expected ',' 錯誤,lock_private.h報了1個。

error-5

處理:查了下Bridge OS是Apple獨立的T2安全芯片使用的嵌入式操作系統(tǒng),它能夠提供安全啟動加密存儲,和我們現(xiàn)在用的關(guān)系不大,暫時刪除。

重新編譯。

問題六:'pthread/tsd_private.h' file not found
處理方法:同問題四。在defaultfile文件夾中,創(chuàng)建pthread文件夾。在下載的依賴文件夾中,找到文件:libpthread-416.40.3 --> private --> tsd_private.h 和 spinlock_private.h,復(fù)制到defaultfile/pthread文件夾中。最后AddFile將pthread添加到bundle的defaultfile文件夾下。

問題七:'System/machine/cpu_capabilities.h' file not found
處理方法:同上。在defaultfile文件夾中,創(chuàng)建System文件夾,System文件夾中創(chuàng)建machine文件夾。在下載的依賴文件夾中,找到文件:xnu-6153.41.3 --> osfmk --> machine --> cpu_capabilities.h,復(fù)制到defaultfile/System/machine文件夾中。最后AddFile將System添加到bundle的defaultfile文件夾下。

問題八:'os/tsd.h' file not found
處理方法:在下載的依賴文件夾中,找到文件:xnu-6153.41.3 --> libsyscall --> os --> tsd.h,復(fù)制到defaultfile/os文件夾中。最后AddFile將tsd.h添加到bundle的defaultfile文件夾下的os文件下。

問題九:'System/pthread_machdep.h' file not found
處理方法:在Libc-583,下載找到文件:Libc-583/pthreads/pthread_machdep.h,復(fù)制到defaultfile/System文件夾中。最后AddFile將pthread_machdep.h添加到bundle的defaultfile文件夾下的System文件下。

問題十:'CrashReporterClient.h' file not found
處理方法:在defaultfile文件夾下創(chuàng)建個CrashReporterClient.h文件,復(fù)制CrashReporterClient.h里的內(nèi)容到創(chuàng)建的新的.h文件里。

問題十一:'objc-shared-cache.h' file not found
處理方法:找到文件:dyld-733.6 --> include --> objc-shared-cache.h,拷貝到defaultfile文件夾中。

問題十二:pthread_machdep.h文件報了3個錯誤
處理方法:將193行代碼typedef int pthread_lock_t;到244行代碼#define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val)先注釋,然后替換成以下代碼:

#if TARGET_IPHONE_SIMULATOR || defined(__ppc__) || defined(__ppc64__) || \
    (defined(__arm__) && !defined(_ARM_ARCH_7) && defined(_ARM_ARCH_6) && defined(__thumb__))

#define _pthread_getspecific_direct(key) pthread_getspecific((key))
#define _pthread_setspecific_direct(key, val) pthread_setspecific((key), (val))

#else
#endif

問題十三:Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_11'Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_14'
處理方法:我們在defaultfile/mach-o/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

問題十四:'_simple.h' file not found
處理方法:找到文件libplatform-220 -> private -> _simple.h,復(fù)制到defaultfile文件夾中。

問題十五:'Block_private.h' file not found
處理方法:找到文件libclosure-74 -> Block_private.h,復(fù)制到defaultfile文件夾中。

問題十六:Use of undeclared identifier 'CRGetCrashLogMessage'
處理方法:target -> Build Settings -> Preprocessor Macros 添加LIBC_NO_LIBCRASHREPORTERCLIENT。

CRGetCrashLogMessage

問題十七:'kern/restartable.h' file not found
處理方法:找到文件xnu-6153.41.3 -> osfmk -> kern -> restartable.h,復(fù)制到defaultfile文件夾中。

問題十八:can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/AppleInternal/OrderFiles/libobjc.order
處理方法:target -> objc -> Build Settings搜索 order File,將debug路徑替換為$(SRCROOT)/libobjc.order。

問題十九:library not found for -lCrashReporterClient
處理方法:target -> objc -> BuildSettings搜索Other Linker Flags,刪除刪除Debug和Release的lCrashReporterClient。

問題二十:SDK "macosx.internal" cannot be located
處理方法:target -> objc -> Build Phases -> Run Script(markgc),將macosx.internal改為macosx

終于,在我快要崩潰的時候編譯成功了。

來張全家福:
全家福

下面開始搭建新的target。命名為Detector


Target
Detector

target創(chuàng)建好之后,二進(jìn)制綁定:


二進(jìn)制綁定

編譯下Detector,沒問題,ready go !

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

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