扩展—配置objc4源码编译调试方法
本文为L_Ares个人写作,包括图片皆为个人亲自操作,以任何形式转载请表明原文出处。
主要用来编译苹果官方开源出来的一些源码,针对objc4的源码可以进行LLDB调试,流程的跟踪,可以更好的学习oc的底层源码和思路。
附带我已经配置好的objc4-781
可调试源码,免得看完以后觉得配置起来太麻烦了,直接下载就可以用,提取码: tpje
一、准备工作。
-
先找到 objc4 的下载网址。本文以最新的
objc4-781
进行配置。 -
这里是你所需要的所有依赖文件,将整个文件夹放进去,修改Header Search Paths,如果出错,根据下面的错误修改方法修改。提取码 : qeag
-
想要自己找的,可以去 Apple Open Source 中的MacOS下面的 MacOS 10.15和MacOS 10.15.1找到大多数的依赖文件。
-
pthread_machdep.h
文件,进去直接用浏览器的commond
+F
寻找到就可以,一定是.h
文件。 -
CrashReporterClient.h
文件,进去第一个好像就是。 -
下载好的需要的文件,与2的区别是 : 这个是官网下载的文件,没有挑出来需要的头文件,需要自己按照下面的步骤去挑选。提取码 : aces
二、配置
先看好objc4-781
的原始目录结构,如下图2.0所示:
下面开始正式的配置。
首先,我们确定一个规则,就是每解决一个问题,都要再运行一次,这样才会显示新的问题,直到成功。
运行objc4-781
项目,然后就会出现各种错误,下面依次的解决。
1. 找不到macosx.internal
的sdk文件。
unable to find sdk 'macosx.internal'
解决办法 :
2.1.2.png注意 : objc
和objec-trampolines
都要修改,步骤一样,如下:
target
--> Build Settings
--> All
和Combined
--> Architectures
--> Base SDK
--> macOS 10.15
2. 各种找不到头文件
首先,在工程中先创建一个JDHeaders
文件夹,JDHeaders
这个名字自己随意写,用以存放所有导入的依赖文件。
设置文件检索路径,即在target
--> objc
--> Build Settings
--> Search Paths
--> Header Search Paths
中添加$(SRCROOT)/JDHeaders
这里注意 :
但凡是这种带有"/"的,表明路径都不止一层,所以都要在
JDHeaders
的文件夹下,再根据缺少的头文件的路径的名字,创建一个文件夹。
我拿问题(1)举个例子,后面的跟问题(1)的处理方式一模一样。
问题(1). 'sys/reason.h' file not found
将xnu-6153.11.26/bsd/sys
中的reason.h
文件放入自己在JDHeaders
文件夹下创建的sys
文件夹下。
缺少的是sys/reason.h
,所以必须在JDHeaders
下再创建一个sys
文件夹,这才符合这个路径。
问题(2). 'mach-o/dyld_priv.h' file not found
将dyld-733.6/include/mach-o/
中的dyld_priv.h
文件放入自己在JDHeaders
文件夹下创建的mach-o
文件夹下。
这时候会发现,本来只是1个问题,现在变成9个了。
2.2.2.pngdyld_priv.h
中 bridgeos(3.0)
报错,直接删除, bridgeos(3.0)
,逗号别忘了删。
然后在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
问题(3). 'os/lock_private.h' file not found
和'os/base_private.h' file not found
这两个丢失的文件可能不是一起报错的,但是一定会需要,所以一起加进来就行了,免得啰嗦。
将libplatform-220/private/os/
中的lock_private.h
文件和base_private.h
放入自己在JDHeaders
文件夹下创建的os
文件夹下。
在你的lock_private.h
可能又报bridgeos(4.0)
,处理方法一样,直接删除bridgeos(4.0)
。
问题(4). 'pthread/tsd_private.h' file not found
和'pthread/spinlock_private.h' file not found
一起说掉,这两个也是肯定会需要的,只不过可能不是一起报错,一起说。
将libpthread-416.11.1/private/
中的tsd_private.h
文件和spinlock_private.h
放入自己在JDHeaders
文件夹下创建的pthread
文件夹下。
问题(5). 'System/machine/cpu_capabilities.h' file not found
将xnu-6153.11.26/osfmk/machine/
中的cpu_capabilities.h
文件放入自己在JDHeaders
文件夹下创建的System/machine
文件夹下。
问题(6). 'os/tsd.h' file not found
将xnu-6153.11.26/libsyscall/os/
中的tsd.h
文件放入自己在JDHeaders
文件夹下创建的os
文件夹下。
问题(7). 'System/pthread_machdep.h' file not found
将pthread_machdep.h
文件放入自己在JDHeaders
文件夹下创建的System
文件夹下。
然后提示:
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
Static declaration of '_pthread_setspecific_direct' follows non-static declaration
遇到这种问题,把他们,包括函数的实现都注释掉就行。
问题(8). 'CrashReporterClient.h' file not found
将CrashReporterClient.h
文件放入JDHeaders
文件夹下。
并且在Build Settings
-> Preprocessor Macros
中添加LIBC_NO_LIBCRASHREPORTERCLIENT
。
问题(9). 'objc-shared-cache.h' file not found
将dyld-733.6/include/
中的objc-shared-cache.h
文件放入JDHeaders
文件夹下。
问题(10). Mismatch in debug-ness macros
2.2.6.png
直接把这一行注释掉。
问题(11). '_simple.h' file not found
将libplatform-220/private/
中的_simple.h
文件放入自己在工程JDHeaders
文件夹下。
问题(12). 'Block_private.h' file not found
将libclosure-74/
中的Block_private.h
文件放入自己在工程JDHeaders
文件夹下。
问题(13). 'kern/restartable.h' file not found
将xnu-6153.11.26/osfmk/kern/
中的restartable.h
文件放入自己在JDHeaders
文件夹下创建的kern
文件夹下。
至此,缺少头文件的问题全部都解决了。
3. 文件动态库问题
ld: 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
,在其下添加$(SRCROOT)/libobjc.order
。
4. 找不到lCrashReporterClient
ld: library not found for -lCrashReporterClient
。
解决办法 :
在target
-> objc
-> Build Settings
中,搜索Other Linker Flags
,在其下删除-lCrashReporterClient
,Debug
和Release
中的都要删除掉。
5. Xcode的脚本编译问题
(1). SDK "macosx.internal" cannot be located.
(2). 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)
(3). unable to find utility "clang++", not a developer tool or in PATH
解决办法 :
在target
-> objc
-> Build Phases
-> Run Script(markgc)
中,将脚本文本macosx.internal
改成macosx
。
到此为止,所有的出现过的error都搞定了。command + B
,应该是Build Succeeded
,如果不是,请留言错误。
如果是的话,你的目录结构应该是这样的了:
成功的目录结构.png三、 编译调试
(1). 新建一个TARGET
3.1.1.png
3.1.2.png
注意画了红色方框的,别选错了。
3.1.3.png点击Finish就行了,然后目录结构多了一个JDObjc
文件夹了。TARGETS里面也多出来了一个JDObjc
的可执行文件。
(2). 设置依赖,导入动态库
在TARGETS
-> JDObjc
-> Build Phases
中设置。
设置完以后的 :
3.2.3.png(3). Xcode 11 以上版本的新特性
在target
--> objc
--> Build Settings
里找到Enable Hardened Runtime
将它的值设置成NO
。
(4). 在JDObjc
文件夹下创建一个iOS的类进行调试
alloc
挂上断点,进alloc
里面,一直到callAlloc
方法实现里面,挂上断点。
显示Build Succeeded,并且可以跳入断点的话就是成功配置了objc4-781
的源码。
至此,我的配置方法就完成了,如果还有什么问题的话,可以在下面留言,大家一起讨论。