Xcode 10 下如何創(chuàng)建可調試的objc4-723、objc4-750.1工程

前言

相信各位iOS開發(fā)愛好者,都會想研究一下runtime底層的一些東西,那么最好的方式莫過于調試。蘋果其實開源了很多的底層庫,詳見:蘋果開源網(wǎng)站首頁、蘋果開源網(wǎng)站下載頁蘋果開源網(wǎng)站瀏覽頁。

objc是蘋果開源的包含runtime等核心邏輯的庫,由于macOS的更新和可能存在的其他原因,下載下來的objc4庫,是無法直接編譯成功的,其中主要的原因是頭文件更換了位置。

本文的初衷是,記錄這樣解決問題的過程,體驗折騰的魅力。文章主要參考了:

objc - 編譯Runtime源碼objc4-706

可調試工程下載

objc4-750.1可調試工程,在macOS Mojave下可運行
objc4-723_Debug

準備工作

本文使用 Xcode 10.0(10A255)

  • 蘋果開源網(wǎng)站下載最新的objc4-723.tar.gz開源庫,該庫就是包含runtime的庫;
  • 蘋果開源網(wǎng)站下載:
  • Libc-1244.50.9.tar.gz
  • Libc-825.40.1.tar.gz、
  • dyld-551.4.tar.gz、
  • launchd-842.92.1.tar.gz
  • libauto-187.tar.gz、
  • libclosure-67.tar.gz
  • libdispatch-913.60.2.tar.gz
  • libpthread-301.50.1.tar.gz、
  • xnu-4570.71.2.tar.gz、

Libc-1244.50.9.tar.gz有些頭文件已經不在,因此也將其舊版本的Libc-825.40.1.tar.gz下載下來(也可只下載它)。下載上述文件的目的是為了方便找尋objc4-723編譯時所缺失的頭文件。

編譯Objc

  • 1、解壓objc4-723.tar.gz,進入objc4-723文件夾,打開工程;點擊編譯,此時會報錯:The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture. (in target 'objc');解決辦法是:將TARGETS->Build Settings->Architectures都改為Standard Archiectures。
  • 2、再次進行編譯,發(fā)現(xiàn)提示'sys/reason.h' file not found;在工程根目錄下面創(chuàng)建一個include文件夾,在TARGETS->Build Settings->Header Seach Paths中添加$(SRCROOT)/include。
  • 3、將準備工作第2步中的壓縮包都解壓并放在同一個文件夾中(可以不在objc4-723的工程文件夾中,假設文件夾名為Source),在Source中搜索reason.h,可以看到之前報錯的地方引入的路徑之前有sys,因此在之前創(chuàng)建的include文件夾中創(chuàng)建sys文件夾,將搜索到的reason.h文件復制到sys目錄下。
  • 4、再次編譯,報錯:'mach-o/dyld_priv.h' file not found,使用相同的方式解決。
  • 5、編譯,報錯:os/lock_private.h' file not found;此時搜索下載的庫時并不能發(fā)現(xiàn)該文件;于是在谷歌進行如下搜索:lock_private.h site:opensource.apple.com,點擊進入搜索結果,在include文件夾下創(chuàng)建相應的os文件夾,并創(chuàng)建lock_private.h文件,將在谷歌搜索到的內容填寫到創(chuàng)建的文件中。
  • 編譯,'os/base_private.h' file not found,使用以上描述的兩種方式解決。
  • 后續(xù)的:
    • pthread/tsd_private.h、
    • cpu_capabilities.h、
    • os/tsd.h
    • spinlock_private.h、
    • pthread_machdep.h
    • workqueue_private.h、
    • pthread/qos_private.h、
    • sys/qos_private.h
    • objc-shared-cache.h、
    • _simple.h,等文件也采用之前的方式進行解決;注意:cpu_capabilities.h使用搜索到的machine文件夾下的文件。
  • 編譯,遇到Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int')),這種redefinition錯誤時,在include文件夾下使用grep命令:
// 如 重復定義 pthread_lock_t
grep -rne "typedef.*pthread_lock_t" .
// 輸出
./pthread/spinlock_private.h:59:typedef volatile OSSpinLock pthread_lock_t __deprecated_msg("Use <os/lock.h> instead");
./System/pthread_machdep.h:214:typedef int pthread_lock_t;

可以看見有兩處定義了pthread_lock_t,注釋掉pthread_machdep.h文件中的定義即可。

  • 編譯,遇到Static declaration of '_pthread_getspecific_direct' follows non-static declaration,這種錯誤本是說如下情況:
// 在一個文件中如下代碼
void sayHello(void);

static void sayHello(void) {
}

上述代碼會使編譯器報出Static declaration of xxx follows non-static declaration錯誤,但是在objc4-723時實際上是因為重復定義(將static去掉之后編譯會發(fā)現(xiàn)Redefinition of錯誤),因此直接將重復定義處注釋就好。

  • 編譯,有一個缺失的文件叫做CrashReporterClient.h,你會發(fā)現(xiàn)在將其放入include后還是會報錯,此時需要:在Build Settings->Preprocessor Macros中加入:LIBC_NO_LIBCRASHREPORTERCLIENT。
  • 編譯,能夠看到objc-os.h文件報錯,在該文件中引入:# include <pthread/qos_private.h>
  • 編譯,看到:Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_11'錯誤;在 dyld_priv.h 文件頂部加入一下宏:
    #define DYLD_MACOSX_VERSION_10_11 0x000A0B00 
    #define DYLD_MACOSX_VERSION_10_12 0x000A0C00 
    #define DYLD_MACOSX_VERSION_10_13 0x000A0D00
  • 編譯,缺少Block_private.h,搜索解壓后的文件,發(fā)現(xiàn)有兩個結果,復制BlocksRuntime中的文件到include下。
  • 編譯,此時 clang報錯:ld: can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/AppleInternal/OrderFiles/libobjc.order;解決辦法:修改工程配置,將Build Settings->Linking->Order File改為工程根目錄下的libobjc.order,即:$(SRCROOT)/libobjc.order。
  • 編譯,ld再次報錯:ld: library not found for -lCrashReporterClient;此時在 Build Settings -> Linking -> Other Linker Flags里刪掉"-lCrashReporterClient"(Debug和Release都刪了)。
  • 再次編譯,會發(fā)現(xiàn) Build Succeeded。

如果在編譯objc過程中遇到cast錯誤,可以直接點擊Fix。

添加Debug Target

  • 1、添加一個target 取名為 objc-debug
添加target
  • 2、為改target添加工程依賴
添加工程依賴
  • 3、在objc-debug中添加你想寫的代碼,或者類,你就可以進行調試了。

為Mojave的更新

由于macOS 10.14 的發(fā)布,objc發(fā)布了新的objc4-750.1開源庫,對應的一些,如:dyld也進行了相關更新。因此針對macOS Mojave需要使用新的開源庫,進行配置。

objc4-750.1可調試工程

為了簡單操作,我直接在objc4-750.1中引用了,之前配置好的objc4-723可調試工程中的頭文件(偷懶。不想一個一個找了)。其中的部分新的錯誤參考了:

最新Runtime源碼objc4-750編譯

可能是由于我直接使用objc4-723工程頭文件的問題出現(xiàn)了:os_unfair_recursive_lock未定義的bug。經過我簡單分析,其作用應該是替換原有的pthread_mutex_t加鎖機制,我直接將其替換成了:objc4-723工程中的pthread加鎖機制(又是偷懶)。

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

友情鏈接更多精彩內容