iOS之objc原始碼編譯報錯解決方案(已提供編譯好的原始碼)

語言: CN / TW / HK

和諧學習!不急不躁!!我是你們的老朋友小青龍~

前言

今天分享一篇關於官方objc原始碼工程編譯錯誤的解決方案。

說來慚愧,之前的很多發文一直都是用的Cooci老師弄好的原始碼庫,作為一個愛學習的程式設計師(呸,臭不要臉),應當學會自己開車(是去幼兒園的那種),自己解決問題。

  • 編譯好的原始碼在文章末尾,可自行下載

環境說明】 - Mac電腦系統:macOS Big Sur 11.5.2 - Xcode版本:13.2.1

官方objc原始碼下載:https://opensource.apple.com/tarballs/objc4/

我下載的是818.2版本

image.png

下載完並解壓

image.png

開啟objc4-818.2工程,我們發現了幾個缺失檔案:

image.png

image.png

先不管它們,直接執行。

1、unable to find sdk 'macosx.internal'

image.png

解決方案Build Settings->搜Base SDK

Targets修改

image.png

Project修改

image.png

如果改完發現還是報這個錯誤,記得clean一下再執行。

2、'sys/reason.h' file not found

image.png

執行發現再次報錯,原因是缺失reason.h這個檔案。

解決方案

開啟網站:https://opensource.apple.com/source/xnu/

複製最新版本名(我這裡是xnu-7195.81.3

image.png

下載地址:https://opensource.apple.com/tarballs/xnu/xnu-7195.81.3.tar.gz (可以參考格式,修改要下的版本號)

下載完會得到一個檔案:xnu-7195.81.3.tar

解壓,找到reason.h (xnu-7195.81.3 -> bsd -> sys -> reason.h)

image.png

在專案根目錄建立檔案結構lostFiles -> sys -> reason.h

image.png

Targets -> Build Setting -> Header Search Paths->新增$(SRCROOT)/lostFiles

image.png

3、'mach-o/dyld_priv.h' file not found

執行繼續報錯

image.png

解決方案】 開啟:https://opensource.apple.com/tarballs/dyld/

image.png

解壓找到檔案dyld_priv.h

image.png

lostFiles下建立一個資料夾mach-o,並拖動dyld_priv.h到資料夾mach-o

image.png

4、dyld_priv.h檔案報錯Expected ','

image.png

解決方案】把這行程式碼註釋了就行。

image.png

5、'os/lock_private.h' file not found

image.png

開啟網站:https://opensource.apple.com/tarballs/libplatform/

image.png

解壓找到檔案:libplatform-177.270.1/private/os/lock_private.h

根目錄檔案增加

image.png

6、'os/base_private.h' file not found

找到檔案:libplatform-177.270.1/private/os/base_private.h

根目錄檔案增加

image.png

7、'pthread/tsd_private.h' file not found

image.png

開啟網站:https://opensource.apple.com/tarballs/libpthread/

image.png

找到檔案:libpthread-416.100.3/private/tsd_private.h

根目錄檔案增加

8、'System/machine/cpu_capabilities.h' file not found

image.png

開啟網站(前面已經下載過了):https://opensource.apple.com/tarballs/xnu/

image.png

找到檔案:xnu-7195.81.3/osfmk/machine/cpu_capabilities.h

根目錄檔案增加

image.png

9、'os/tsd.h' file not found

image.png

找到檔案:xnu-7195.81.3/libsyscall/os/tsd.h

根目錄檔案增加

image.png

10、'pthread/spinlock_private.h' file not found

libpthread-416.100.3庫前面已經下載過了)

找到檔案:libpthread-416.100.3/private/spinlock_private.h

根目錄檔案增加

image.png

11、'System/pthread_machdep.h' file not found

image.png

開啟網站:https://opensource.apple.com/tarballs/Libc/

image.png

找到檔案:Libc-825.40.1/pthreads/pthread_machdep.h

image.png

根目錄檔案增加

image.png

12、'CrashReporterClient.h' file not found

找到檔案:Libc-825.40.1/include/CrashReporterClient.h

image.png

根目錄檔案增加

image.png

13、Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int'))

image.png

字面意思是 使用不同型別重新定義了pthread_lock_t

全域性搜尋pthread_lock_t

image.png

我們發現在spinlock_private.hpthread_machdep.h,都對pthread_lock_t進行了定義。

解決方案】 註釋pthread_machdep.h裡的pthread_lock_t定義這行程式碼。

14、多個declaration錯誤

```js // 錯誤資訊如下

Static declaration of '_pthread_has_direct_tsd' follows non-static declaration

Static declaration of '_pthread_getspecific_direct' follows non-static declaration

Static declaration of '_pthread_setspecific_direct' follows non-static declaration ```

image.png

解決方案】把這三個函式連帶實現內容都註釋掉

image.png

15、Use of undeclared identifier 'OS_UNFAIR_LOCK_ADAPTIVE_SPIN'

image.png

解決方案

```js // uint32_t opts = OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION | OS_UNFAIR_LOCK_ADAPTIVE_SPIN;

// 修改為 uint32_t opts = OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION; os_unfair_lock_lock(&mLock); ```

image.png

16、'objc-shared-cache.h' file not found

image.png

找到檔案:dyld-852.2/include/objc-shared-cache.h

image.png

根目錄檔案增加

image.png

17、'objc-probes.h' file not found

image.png

18、'os/feature_private.h' file not found

image.png

解決方案】 將#include <os/feature_private.h>這行註釋掉

19、找不到未申明的'dyld_fall_2020_os_versions'、'objc4'、'preoptimizedCaches'

```js // 報錯資訊

Use of undeclared identifier 'dyld_fall_2020_os_versions'

Use of undeclared identifier 'objc4'

Use of undeclared identifier 'preoptimizedCaches' ``` 【解決方案

image.png

image.png

20、'objc-bp-assist.h' file not found

解決方案】 註釋這行引用程式碼

image.png

21、Use of undeclared identifier 'dyld_platform_version_macOS_10_13'

解決方案

image.png

22、Use of undeclared identifier 'dyld_platform_version_macOS_10_11'

解決方案

image.png

23、Use of undeclared identifier 'dyld_fall_2018_os_versions'

解決方案

image.png

24、'_simple.h' file not found

image.png

找到檔案:libplatform-177.270.1/private/_simple.h

根目錄檔案增加

image.png

25、'Block_private.h' file not found

開啟網站:https://opensource.apple.com/tarballs/libclosure/

image.png

解壓並找到檔案:libclosure-79/Block_private.h

根目錄檔案增加

image.png

26、'os/linker_set.h' file not found

找到檔案:Libc-1439.40.11/os/linker_set.h

根目錄檔案增加

image.png

27、Use of undeclared identifier 'CRGetCrashLogMessage'

解決方案

Build Settings -> 搜尋Preprocessor Macros, 新增LIBC_NO_LIBCRASHREPORTERCLIENT

image.png

新增完再編譯,就不報這個錯了

image.png

28、'Cambria/Traps.h' file not found

image.png

解決方案】為了避擴音示'Cambria/Cambria.h' file not found,乾脆兩行都註釋了

image.png

29、'kern/restartable.h' file not found

找到檔案:xnu-6153.81.5/osfmk/kern/restartable.h

image.png

根目錄檔案增加

image.png

30、Use of undeclared identifier 'oah_is_current_process_translated'

修改前

image.png

修改後

image.png

31、'os/feature_private.h' file not found

解決方案】 註釋這行程式碼

image.png

32、'os/reason_private.h' file not found | 'os/variant_private.h' file not found

```js // 報錯資訊

'os/reason_private.h' file not found

'os/variant_private.h' file not found ``` 【解決方案

image.png

33、Use of undeclared identifier 'dyld_platform_version_xx_x_x'

```js // 報錯資訊

Use of undeclared identifier 'dyld_platform_version_bridgeOS_2_0'

Use of undeclared identifier 'dyld_platform_version_iOS_10_0'

Use of undeclared identifier 'dyld_platform_version_macOS_10_12'

Use of undeclared identifier 'dyld_platform_version_tvOS_10_0'

Use of undeclared identifier 'dyld_platform_version_watchOS_3_0' ```

解決方案】 註釋選中程式碼

image.png

34、Can't open order file: /Applications/Xcode.app/Contents…OrderFiles/libobjc.order

image.png

js // 報錯資訊 Can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/AppleInternal/OrderFiles/libobjc.order

解決方案Build Settings->搜orderfile->新增$(SRCROOT)/libobjc.order

image.png

35、library not found for -lCrashReporterClient

image.png

解決方案Build Settings->搜other link->刪除-lCrashReporterClient

image.png

36、library not found for -loah

image.png

解決方案】跟35一樣,Build Settings->搜other link->刪除-loah

37、'_static_assert' declared as an array with a negative size

解決方案

image.png

38、SDK "macosx.internal" cannot be located.

解決方案TARGETS->Build Phases->Run Script(markgc)->修改macosx.internalmacosx

image.png

39、Expected function body after function declarator

image.png

很多地方報了一樣的錯誤提示Expected function body after function declarator

終於編譯成功了

經過一系列問題的修復,終於看到了久違了Build Successded(😭)

image.png

新建一個除錯

【點選+號】

image.png

【選擇macOS - Command Line Tool

image.png

【輸入名稱】

image.png

【關聯依賴】

image.png

【執行ing】

IMB_i2u7My.GIF

報錯在這一行

js lock.lock();

錯誤資訊提示是

js Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

錯誤提示看不到什麼有用的提示,但是我們知道肯定是lock方法出了問題。

解決方案】註釋lock方法裡的os_unfair_lock_lock(&mLock);這行程式碼

image.png

【再次執行】

IMB_XofkCl.GIF

成功列印NSLog日誌。

參考文章連結

lock方法錯誤解決

感謝這位小夥伴提供的Demo,我用demo裡面的objc-os.h檔案和我自己工程的objc-os.h檔案對比了下,發現lock方法不太一樣,最終才意識到是多了一行程式碼。

objc4原始碼編譯與除錯
https://www.jianshu.com/p/bffba01690d7

編譯錯誤解決

參考文章:

iOS-objc4-781原始碼編譯配置流程
https://www.jianshu.com/p/4f15c551a0ea

objc原始碼編譯
https://www.jianshu.com/p/5fc26fed9698

由於是在Xcode13.2.1版本上編譯的,所以在配置一些缺失的庫檔案上,我儘可能的選擇最新的。

附一張lostFiles資料夾結構圖

image.png

編譯好的原始碼

連結: https://pan.baidu.com/s/1xt2YuoZm20c55cwWzCXQ_w
提取碼: ov85 --來自百度網盤超級會員v3的分享