最新Runtime源码objc4-750编译


最新版本的Runtime源码已经出来了,是不急不可耐的想用用它呢?在这里我将一步步教大家如何编译它,首先贴个自己的环境配置:

  • mac OS 10.14
  • Xcode 10.1
  • objc4-750

首先给出我已编译好的objc4-750地址,可以直接使用。

Runtime源码地址

  • 苹果开源网站上可以下载到很多开源项目,可以看到当前最新mac OS系统为10.14.1,最新的Xcode版本为10,安装Xcode 10.0提示mac OS系统需要10.13.6:
  • 通常所说的Runtime源码就是objc4文件,由于iOS中开源项目非常少,所以选择最新mac OS系统10.14.1,command+f键在浏览器页面右上角输入objc4:
  • 可以看到最新的objc4文件为objc4-750.1,点击右边的下载按钮可以下载压缩包:
  • 也可以点击objc4-750.1,可以看到包里的具体内容,用Xcode可以打开它:


  • 此时显示的网页地址为https://opensource.apple.com/source/objc4/objc4-750.1/
  • 去掉最后的objc4-750.1/路径,进入网页地址https://opensource.apple.com/source/objc4/,可以看到以往objc4历史版本:
  • 其中source替换成tarballs,http://opensource.apple.com/tarballs/objc4/,就可以下载自己想要的objc4版本:

Runtime源码编译

下载好源码之后用Xcode打开是这个样子:


这里的libobjc.A.dylib就是我们要编译的目标-Runtime库,编译好之后自己可以再添加一个Target用于测试里面的Runtime源码,但是现在编译会报错,大部分错误是缺少头文件,这些头文件都在苹果开源的其它项目里。接下来依依解决这些问题:

  1. 准备工作
    进入苹果开源网站,下载依赖的开源项目:
  • Libc-825.40.1.tar.gz
  • dyld-551.3.tar.gz
  • libauto-187.tar.gz
  • libclosure-73.tar.gz
  • libdispatch-1008.220.2.tar.gz
  • xnu-4903.221.2.tar.gz
  • libpthread-330.220.2.tar.gz
  • launchd-842.92.1.tar.gz
  • libplatform-177.200.16.tar.gz
    把他们下载好并解压之后放入同一个文件夹中,方便查找。
  1. 提示'sys/reason.h' file not found
    在当前项目下创建一个文件夹Common,里面用于存放所有缺失的头问题件:

    并且把它添加到项目的Header Search Paths中,依次选择objc->TARGETS->objc->Build Settings,搜索框中输入header search path,然后加入$(SRCROOT)/Common

接下来需要去已下载好的开源项目中寻找reason.h头文件了,方式有两种:

  • 使用命令行:
    进入目录cd /Users/gcf/Desktop/OpenSource
    搜索文件名find . -name ‘reason.h’
    image.png

    可以看到搜索结果显示在./xnu-4903.221.2/bsd/sys/reason.h中,按照这个路径找到reason.h文件,根据编译错误提示知道,这个reason.h文件在路径sys下,那么在已创建的Common文件下创建一个新的sys文件夹,里面放入找到的reason.h文件:

  • 普通搜索
    直接在Opensource中搜索reason.h文件:

    接下来处理和上述一样。
  1. 再次编译,提示'mach-o/dyld_priv.h' file not found
    选择./dyld-551.3/include/mach-o/dyld_priv.h,和上述同样操作,不再重述。
  2. 提示'os/lock_private.h' file not found
    选择./libplatform-177.200.16/private/os/lock_private.h
  3. 提示'os/base_private.h' file not found
    选择./libplatform-177.200.16/private/os/base_private.h
  4. 提示'pthread/tsd_private.h' file not found
    选择./libpthread-330.220.2/private/tsd_private.h
  5. 提示'System/machine/cpu_capabilities.h' file not found
    选择./xnu-4903.221.2/osfmk/machine/cpu_capabilities.h
  6. 提示'os/tsd.h' file not found
    选择./xnu-4903.221.2/libsyscall/os/tsd.h
  7. 提示'pthread/spinlock_private.h' file not found
    选择./libpthread-330.220.2/private/spinlock_private.h
  8. 提示'System/pthread_machdep.h' file not found
    选择./Libc-825.40.1 2/pthreads/pthread_machdep.h
  9. 提示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文件中的定义即可。

  1. 提示Static declaration of '_pthread_getspecific_direct' follows non-static declaration
    这里有三个函数定义重复了:
  • _pthread_has_direct_tsd(void)
  • _pthread_getspecific_direct(unsigned long slot)
  • _pthread_setspecific_direct(unsigned long slot, void * val)
grep -re "_pthread_has_direct_tsd(void)” .
//输出
./pthread/tsd_private.h:_pthread_has_direct_tsd(void)
./System/pthread_machdep.h:_pthread_has_direct_tsd(void)
 grep -re "_pthread_getspecific_direct(unsigned long slot)” .
//输出
./pthread/tsd_private.h:_pthread_getspecific_direct(unsigned long slot)
./System/pthread_machdep.h:_pthread_getspecific_direct(unsigned long slot)
grep -re "_pthread_setspecific_direct(unsigned long slot, void \* val)” .
//输出
./pthread/tsd_private.h:_pthread_setspecific_direct(unsigned long slot, void * val)
./System/pthread_machdep.h:_pthread_setspecific_direct(unsigned long slot, void * val)

这里选择把pthread_machdep.h文件中的定义注释掉。

  1. 提示'CrashReporterClient.h' file not found
    选择./Libc-825.40.1 2/include/CrashReporterClient.h,放入Common文件夹下之后还是报错,需要在Build Settings->Preprocessor Macros中加入:LIBC_NO_LIBCRASHREPORTERCLIENT
  2. 提示'Block_private.h' file not found
    选择./libdispatch-1008.220.2/src/BlocksRuntime/Block_private.h
  3. 提示'objc-shared-cache.h' file not found
    选择./dyld-551.3/include/objc-shared-cache.h
  4. 提示Use of undeclared identifier ‘DYLD_MACOSX_VERSION_10_13
    在 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
  1. 提示'_simple.h' file not found
    选择./libplatform-177.200.16/private/_simple.h
  2. 提示'isa.h' file not found
    isa.h文件在项目的runtime文件夹中,新加入的一个头文件:

    我们把它引入Commone文件夹中去:
  3. 提示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。
  4. 提示library not found for -lCrashReporterClient
    此时在 Build Settings -> Linking -> Other Linker Flags里删掉"-lCrashReporterClient"(Debug和Release都删了)
  5. 提示SDK "macosx.internal" cannot be located.unable to find utility "clang++", not a developer tool or in PATH
    把Target-objcBuild Phases->Run Script(markgc)里的内容macosx.internal改为macosx,这里我猜测macosx.internal为苹果内部的macosx,说的不对,大家指出来。
  6. 提示no such public header file: '/tmp/objc.dst/usr/include/objc/ObjectiveC.apinotes’
    这里需要把Target-objcBuild Settings->Other Text-Based InstallAPI Flags里的内容设为!

    并且一定记得要把Text-Based InstallAPI Verification Model里的值改为Errors Only

相关警告

  1. 警告Traditional headermap style is no longer supported; please migrate to using separate headermaps and set 'ALWAYS_SEARCH_USER_PATHS' to NO. (in target 'objc-trampolines')Traditional headermap style is no longer supported; please migrate to using separate headermaps and set 'ALWAYS_SEARCH_USER_PATHS' to NO. (in target 'objc’)
    在项目Target->objc-trampolinesobjc中的Build Settings下设置ALWAYS_SEARCH_USER_PATHSNo
  2. 警告'_PTHREAD_TSD_SLOT_PTHREAD_SELF' macro redefined
    pthread_machdep.h头文件中共有四个宏定义重复了:
  • _PTHREAD_TSD_SLOT_PTHREAD_SELF
  • __PTK_LIBC_TTYNAME_KEY
  • LOCK_INIT
  • LOCK_INITIALIZER
    这里选择把pthread_machdep.h文件中的宏定义注释掉。
  1. 警告objc-exception.mm:584:5: Code will never be executed
    把不会执行到的代码__builtin_trap();注释掉
  2. 警告objc-class.mm:558:33: Possible misuse of comma operator here
    使用Xcode提示的Fix修复
  3. 还有一些Fixme...之类的警告,是苹果在自己代码里定义的一些警告提示,就不处理了。

添加Debug Target

  1. 添加一个target 取名为 objc-test


  2. 为改target添加工程依赖


  3. 在objc-test中添加测试代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class newClass = objc_allocateClassPair(objc_getClass("NSObject"), "newClass", 0);
                objc_registerClassPair(newClass);
        id newObject = [[newClass alloc]init];
        NSLog(@"%@",newObject);
    }
    return 0;
}

参考文章:

总结

  1. 所有头文件


  2. 所有其它开源项目


  3. 推荐给技巧,从别人博客中看到的:
    当缺少头文件时,不知道在哪个开源项目中,比如缺少CrashReporterClient.h,那么在谷歌中输入CrashReporterClient.h site:opensource.apple.com,搜索结果:
    看搜索结果的链接,很容易可知道它来自Libc项目。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 最新版本的Runtime源码已经出来了,是不急不可耐的想用用它呢?在这里我将一步步教大家如何编译它,首先贴个自己的...
    Cooci_和谐学习_不急不躁阅读 3,721评论 8 19
  • 1、准备工作 2、下载源码 --https://opensource.apple.com/tarballs/obj...
    青年fw阅读 907评论 0 0
  • 目前objc4最新的源码是750.1版本,看网上也没人写了这个版本的编译方法,所以这里记录一下。编译方法都大同小异...
    政在coding阅读 1,053评论 1 1
  • 前言 相信各位iOS开发爱好者,都会想研究一下runtime底层的一些东西,那么最好的方式莫过于调试。苹果其实开源...
    己庚辛壬癸阅读 3,384评论 14 15
  • 9/365 情绪流经——回到真相——做零极限和解 今天中午在姑姑家吃饭,她的儿媳妇问我的儿子学习成绩怎么样?有没有...
    风清云淡_8b20阅读 332评论 0 0