前言
本人最近學(xué)習(xí)iOS底層原理并鸵,需要編譯源碼鸳粉,在這里,記錄一下遇到的問(wèn)題以及處理的過(guò)程园担,因?yàn)槲业南到y(tǒng)是 11.3.1 的届谈,所以我配置的是最新的 objc源碼。
這里附上objc源碼地址:https://opensource.apple.com/tarballs/objc4/
一弯汰、 準(zhǔn)備
1疼约、環(huán)境
系統(tǒng):macOS Big Sur - 11.3.1
工具:Xcode 12.5
2、資料
- dyld-851.27
- launchd-106.10(需要去mac os 10.4.4中下載)
- libauto-187
- Libc-583(需要去macos 10.6.2中去下載)
- Libc-825.24(需要去macos10.8.1中去下載)
- Libc-1439.100.3
- libclosure-79
- libdispatch-1271.100.5
- libplatform-254.80.2
- libpthread-454.100.8
- xnu-7195.101.1
- objc4-824
以上是需要的材料蝙泼,都可以在 https://opensource.apple.com/releases/ 這里下載。
我也有將這些文件上傳到 git劝枣,下載地址:https://github.com/RegretSF/objc824
二汤踏、 編譯
1、unable to find sdk 'macosx.internal'
把objc824源碼下載下來(lái)之后編譯舔腾,發(fā)現(xiàn)報(bào)錯(cuò):
解決方法:
target → objc/objc-trampolines → Build Setting → Base SDK
將其改為macOS
溪胶,如圖:注意:objc和objc-trampolines的都要改,因?yàn)榫幾g器報(bào)的錯(cuò)誤是這兩個(gè)稳诚。
2哗脖、'os/feature_private.h' file not found
解決方法:這個(gè)聲明報(bào)錯(cuò)直接注釋掉就好了。
3扳还、'sys/reason.h' file not found
解決方法:項(xiàng)目目錄新建文件夾 FNCommon
才避,這個(gè)文件夾的名字可以隨便取,在 FNCommon
里新建 sys
文件夾氨距,將 xnu-7195.101.1/bsd/sys/
路徑下的 reason.h
文件放到新建的 FNCommon/sys/
目錄下桑逝,如圖:
但這個(gè)時(shí)候編譯還是會(huì)報(bào)錯(cuò),解決方法:給我們的工程設(shè)置文件檢索路徑俏让,選擇
target -> objc -> Build Settings
楞遏,在工程的 Header Serach Paths
中添加搜索路徑 $(SRCROOT)/FNCommon
茬暇,如圖:4、'mach-o/dyld_priv.h' file not found
解決方法:其實(shí)方式和第3點(diǎn)一樣寡喝,在
FNCommon
里新建 mach-o
文件夾糙俗,將 dyld-851.27/include/mach-o
路徑下的 dyld_priv.h
文件放到新建的 FNCommon/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
如圖:
5巧骚、'os/lock_private.h' file not found
解決方法:和第3點(diǎn)一樣,在
FNCommon
里新建 os
文件夾珊皿,將 libplatform-254.80.2/private/os
路徑下的 lock_private.h
文件放到新建的 FNCommon/os/
目錄下网缝,如圖:6、bridgeos - 1 報(bào)錯(cuò)
將有關(guān)
bridgeos
報(bào)錯(cuò)的代碼蟋定,刪除掉 bridgeos(3.0)
粉臊,如圖:到這里先編譯,后面還會(huì)出現(xiàn)有關(guān) bridgeos
報(bào)錯(cuò)的代碼驶兜,到時(shí)候用一樣的方式扼仲,刪除掉 bridgeos
即可。
7抄淑、'os/base_private.h' file not found
解決方法:和第3點(diǎn)一樣屠凶,將
xnu-7195.101.1/libkern/os
路徑下的 base_private.h
文件放到新建的 FNCommon/os/
目錄下,如圖:8肆资、bridgeos - 2 報(bào)錯(cuò)
解決方法:刪除掉代碼中的 bridgeos(4.0)
矗愧,如圖:
9、'pthread/tsd_private.h' file not found
解決方法:和第3點(diǎn)一樣郑原,在 FNCommon
里新建 pthread
文件夾唉韭,將 libpthread-454.100.8/private/pthread
路徑下的 tsd_private.h
文件放到新建的 FNCommon/pthread/
目錄下,如圖:
10犯犁、'System/machine/cpu_capabilities.h' file not found
解決方法:和第3點(diǎn)一樣属愤,在
FNCommon
里新建 System
文件夾并在System
里新建文件夾machine
,將 xnu-7195.101.1/osfmk/machine
路徑下的 cpu_capabilities.h
文件放到新建的 FNCommon/System/machine/
目錄下酸役,如圖:
11住诸、'os/tsd.h' file not found
解決方法:和第5點(diǎn)一樣,將 xnu-7195.101.1/libsyscall/os
路徑下的 tsd.h
文件放到新建的 FNCommon/os/
目錄下涣澡,如圖:
12贱呐、'pthread/spinlock_private.h' file not found
解決方法:和第9點(diǎn)一樣,將
libpthread-454.100.8/private/pthread
路徑下的 spinlock_private.h
文件放到新建的 FNCommon/pthread/
目錄下入桂,如圖:13吼句、'System/pthread_machdep.h' file not found
解決方法:和第10點(diǎn)一樣,將 Libc-825.24/pthreads
路徑下的 pthread_machdep.h
文件放到新建的 FNCommon/System/
目錄下事格,如圖:
添加完成后惕艳,重新編譯搞隐,會(huì)出現(xiàn)幾個(gè)報(bào)錯(cuò),如圖:
我們直接把報(bào)錯(cuò)的代碼注釋掉远搪,重新編譯就好了劣纲。
14、'CrashReporterClient.h' file not found
解決方法:將 Libc-825.24/include
路徑下的 CrashReporterClient.h
文件放到新建的 FNCommon/
目錄下谁鳍,如圖:
15癞季、'_simple.h' file not found
解決方法:將 libplatform-254.80.2/private
路徑下的 _simple.h
文件放到新建的 FNCommon/
目錄下,如圖:
16倘潜、'Cambria/Traps.h' file not found绷柒, 'Cambria/Cambria.h' file not found
解決方法:這兩個(gè)聲明直接注釋掉就好了挎塌。
17桐臊、'os/linker_set.h' file not found
解決方法:將 Libc-1439.100.3/os
路徑下的 linker_set.h
文件放到新建的 FNCommon/os/
目錄下艾岂,如圖:
18蔼啦、'kern/restartable.h' file not found
解決方法:和第3點(diǎn)一樣,在 FNCommon
里新建 kern
文件夾璧微,將 xnu-7195.101.1/osfmk/kern
路徑下的 restartable.h
文件放到新建的 FNCommon/kern/
目錄下戳吝,如圖:
19定躏、Use of undeclared identifier 'CRGetCrashLogMessage'澜掩,Use of undeclared identifier 'CRSetCrashLogMessage'
解決方法:將代碼注釋掉即可购披,如圖:
20、Use of undeclared identifier 'oah_is_current_process_translated'肩榕,
解決方法:將代碼注釋掉即可刚陡,如圖:
21、Use of undeclared identifier 'dyld_fall_2020_os_versions'
解決方法:將代碼注釋掉即可株汉,如圖:
22筐乳、'Block_private.h' file not found
解決方法:將 ``libclosure-79/路徑下的
Block_private.h 文件放到新建的
FNCommon/``` 目錄下,如圖:
23郎逃、Use of undeclared identifier 'dyld_platform_version_macOS_10_13',Use of undeclared identifier 'dyld_platform_version_macOS_10_11'挺份,Use of undeclared identifier 'dyld_fall_2018_os_versions'
解決方法:將代碼注釋掉即可褒翰,如圖:
24、'objc-shared-cache.h' file not found
解決方法:將 dyld-851.27/include
路徑下的 objc-shared-cache.h
文件放到新建的 FNCommon/
目錄下匀泊,如圖:
25优训、'os/reason_private.h' file not found, 'os/variant_private.h' file not found
解決方法:將 xnu-7195.101.1/libkern/os
路徑下的 reason_private.h
文件和Libc-1439.100.3/os
路徑下的 reason_private.h
文件放到新建的 FNCommon/os/
目錄下各聘,如圖:
26揣非、bridgeos - 3 報(bào)錯(cuò)
解決方法:將 bridgeos
刪掉即可,其他代碼有也一樣躲因,如圖:
27早敬、Use of undeclared identifier 'dyld_platform_version_bridgeOS_2_0'...
解決方法:將有關(guān)的代碼注釋掉即可忌傻,如圖:
28、'_static_assert' declared as an array with a negative size
解決方法:將有關(guān)的代碼注釋掉即可搞监,如圖:
29水孩、ld: can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/AppleInternal/OrderFiles/libobjc.order
libobjc.order 路徑問(wèn)題。
解決方法:選擇 target -> objc -> Build Settings
琐驴,在工程的 Order File
中添加搜索路徑 $(SRCROOT)/libobjc.order
俘种,如圖:
30、library not found for -lCrashReporterClient
解決方法:需要在 TARGETS -> objc -> Build Settings -> Preprocessor Macros
中加入: LIBC_NO_LIBCRASHREPORTERCLIENT
绝淡,如圖:
如果還是報(bào)錯(cuò)宙刘,找到TARGETS -> objc -> Build Setting -> Other Link Flags
,刪除-lCrashReporterClient
和-loah
牢酵,如圖:
31悬包、xcodebuild:1:1: SDK "macosx.internal" cannot be located.,/xcrun:1:1: sh -c '/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk macosx.internal -find clang++ 2> /dev/null' failed with exit code 16384: (null) (errno=No such file or directory)茁帽,/xcrun:1:1: unable to find utility "clang++", not a developer tool or in PATH
解決方法:選擇 target -> objc -> Build Phases -> Run Script(markgc)
把腳本文本macosx.internal
改成 macosx
玉罐,如圖:
到這里,就編譯成功啦潘拨!
我已經(jīng)老血吐了一地了吊输!的確配置過(guò)程還是相對(duì)來(lái)說(shuō)有點(diǎn)惡心,尤其是文件的查漏補(bǔ)缺铁追。
三季蚂、 objc 編譯調(diào)試
1、新建一個(gè) Target : FNTest琅束,如圖:
2扭屁、綁定二進(jìn)制依賴(lài)關(guān)系
運(yùn)行代碼進(jìn)入源碼,可以自由編譯調(diào)試涩禀!