Runtime源码编译

作者: 偶尔登南山 | 来源:发表于2019-04-08 16:54 被阅读51次

        Objective-C是基于c语言的封装,使C语言具有了面向对象的能力.OC的本质最终还是转换c语言来执行,而这个转换的过程是通过Runtime这个运行时库来完成的.平常我们只需要写面对对象的OC代码,不用太关心一些底层转换原理及过程.但是有些情况.比如需要动态给一个类添加方法,添加成员变量,添加协议,没有实现方法的报错解析定位等,就需要了解这个底层实现来更好的解决实际开发中遇到的问题.

        本文也是对之前编译查看的Runtime源码的一个复习过程,主要有以下几步:

一.下载源码及相关依赖

        苹果开源网站:http://opensource.apple.com/,其为我们提供了Runtime的实现源码objc4,这个objc4有多个版本,版本号越大说明是最新源码.

苹果开源平台

1.下载objc4源码

        首先打开苹果开源网站,可以看到苹果针对不同的设备平台有不同的开源项目已经对应的系统版本,找到对应的平台对应的版本点击下载objc4源码,本文依赖的是objc4-750版本.也可以在https://opensource.apple.com/tarballs/上面搜索所有开源项目源码的压缩包.

objc4源码

2.下载objc4相关依赖库

objc4相关依赖库:Libc,dyld,libauto,libclosure,libdispatch,libpthread,xnu.这些依赖库中包含了Runtime源码库中需要的一些文件.

3.解压缩所有下载的压缩包库.



源码解压后

二.编译&错误解决

1.环境:

target platform:macOS

macOS:10.14

Xcode:10.1

2.遇到的错误&解决

1)error: The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture. (in target 'objc')

解决:找target对应编译设置(Build Settings)->CPU架构(Architecture)->标准(Standard arcgutectures)


错误1
2)在objc-os.h头文件中报'sys/reason.h' file not found错误

解决:工程目录下创建include/sys目录,在编译设置(Build Settings里面搜索,Header Search Paths,然后将include索引添加进去),然后在之前下载的依赖包中搜索reason.h头文件,复制到include/sys目录下


错误2
3)在objc-os.h头文件中报'mach-o/dyld_priv.h' file not found错误

解决:同上一步,创建include/mach-o目录,复制dyld_priv.h头文件到相应目录


错误3
4)在objc-os.h头文件中报'os/lock_private.h' file not found错误

解决:这个文件并没有再我们下载的依赖库中,需要去开源官网下载,然后操作同上一步

5)以下是遇到的类似问题:

'os/base_private.h' file not found;

'pthread/tsd_private.h' file not found;

'System/machine/cpu_capabilities.h' file not found;

'os/tsd.h' file not found;

'pthread/spinlock_private.h' file not found;

'System/pthread_machdep.h' file not found;

'CrashReporterClient.h' file not found;这个需要在编译设置(Build Settings添加宏变量Build Settings->Preprocessor Macros中加入:LIBC_NO_LIBCRASHREPORTERCLIENT)

'Block_private.h' file not found;

'objc-shared-cache.h' file not found;

'isa.h' file not found;

'_simple.h' file not found;

在objc-errors.mm文件中报:Use of undeclared identifier 'CRGetCrashLogMessage'错误;



错误5
6)链接时候错误:

ld: can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/AppleInternal/OrderFiles/libobjc.order
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决:将Build Settings->Linking->Order File改为工程根目录下的libobjc.order,即:$(SRCROOT)/libobjc.order。


错误6
7)编译脚本错误

xcodebuild: error: SDK "macosx.internal" cannot be located.
xcrun: error: unable to find utility "clang++", not a developer tool or in PATH

解决:把Target-objc的Build Phases->Run Script(markgc)里的内容macosx.internal改为macosx,这里猜测macosx.internal为苹果内部的macosx


错误7
8)error: no such public header file: '/tmp/objc.dst/usr/include/objc/ObjectiveC.apinotes'错误

解决:把Text-Based InstallAPI Verification Model里的值改为Errors Only


错误8

3.编译成功

        解决以上错误后,再次编译应该基本Succeeded.


编译成功

三.调试

1.创建调试target

        本文编译针对的是macOS平台,可以创建一个macOS app或者一个 Command Line Tool 来调试.这里我们就创建一个Command Line Tool target:


debug target

2.编写代码调试

        新创建一个class,命名为newClass,打印出class name.可以查看调用栈,确实调用的是我们编译后的Runtime库:

#import <Foundation/Foundation.h>
#import <objc/message.h>
#import <objc/runtime.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(@"%s",class_getName([newObject class]));
        NSLog(@"Hello, World!");
    }
    return 0;
}



debug_1
debug_2

四.编译后源码库

编译后的源码放在Github, 如果对你有帮助,请给一个star吧!

五.博客地址&相关文章

博客地址: https://waitwalker.cn/

系列文章:

1. Runtime源码编译

2. objc_object解读

3. Method解读

4. Class解读

5. Ivar objc_property_t Protocol解读

6. Block解读

7. Retain&Release解读

六.参考文献

https://pewpewthespells.com/blog/buildsettings.html

https://blog.csdn.net/wotors/article/details/52489464

相关文章

  • runtime源码中的类和对象

    本文基于objc4-709源码进行分析。关于源码编译:objc - 编译Runtime源码objc4-706 ob...

  • android studio debug android run

    目标 debug android runtime native code 环境 已经编译好aosp 源码 ...

  • 编译Runtime源码

    原文链接 Runtime,也就是所谓的运行时,是Objective-C语言一个非常重要的特性。了解Runtime,...

  • Runtime源码编译

    Objective-C是基于c语言的封装,使C语言具有了面向对象的能力.OC的本质最终还是转换c语言来执行,而这个...

  • clanclang编译错误: fatal error: 'UIK

    iOS 终端使用Clang编译 重写观察Runtime源码 - 码农的青春 - CSDN博客 clang编译错误:...

  • runtime

    runtime简介 runtime源码地址 运行时(Runtime)是指将数据类型的确定由编译时推迟到了运行时 R...

  • Block源码及案例分析

    源码分析 需要搭建一个可以运行block底层代码的工程,参考objc - 编译Runtime源码objc4-680...

  • objc -编译Runtime 源码

    https://github.com/opensource-apple :Objective-C是基于C加入了面向...

  • Runtime(1)--源码编译

    Runtime,是一套底层的 C 语言 API,是 iOS 系统的核心之一。开发者在编码过程中,可以给任意一个对象...

  • OC各路大神博客、各种知识点博客

    Runtime源码苹果官方Runtime源码能跑的Runtime源码Block实现源码 各路大神博客 南峰子的技术...

网友评论

    本文标题:Runtime源码编译

    本文链接:https://www.haomeiwen.com/subject/ydtpiqtx.html