简介程序员
程序员编写的是源代码,而计算机运行的则是CPU能识别的机器指令,所以必需要有一系列工具或程序来将源代码转化为机器指令,这个转化的过程须要经历编译和连接两个主要阶段。所谓编译就是将源代码文件转化为中间的目标文件(Object file)。目标文件的后缀通常为.o。iOS系统的目标文件也是一种mach-o格式的文件,mach-o文件的头部结构体:struct mach_header中的filetype成员字段用来描述当前文件的类型,目标文件所对应的类型是MH_OBJECT。目标文件中的布局结构和内容和可执行文件中的布局结构和内容很是类似,编译后造成的目标文件中的代码段(__TEXT Segment)中的节(__text Section) 中的内容存放的是已经被编译为机器指令的二进制代码了。面试
iOS开发交流技术群:563513413,无论你是大牛仍是小白都欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 你们一块儿交流学习成长!segmentfault
静态库和动态库的存在形式安全
静态库和动态库的区别app
image.png函数
重定位表(Relocation table)工具
系统的编译操做是针对一个个源文件的独立行为。一般状况下在编写程序时会引用其余源文件或者动态库中定义的函数或者类方法以及全局变量,所以在编译阶段全部的外部引用符号的地址是没法被肯定的,此时生成的目标文件中的段(Segment)中的节(Section)中的外部函数调用指令的操做数部分以及外部全局变量符号的地址的值都将是0。在后续的连接过程当中须要调整这些指令的操做数的值来进行重定位(Relocation),为此系统在编译的目标文件中的对那些有外部符号引用的节(Section)中都会创建一个重定位表(Relocation table)。这个重定位表中的每一个条目会将全部须要进行重定位的指令或者数据访问的位置信息以及引用的外部符号的信息记录起来,以便在连接时进行更新处理。下面的图表展现了这个结构:布局
image学习
简要的说一下连接步骤所作的事情ui
当编译器对全部的源代码文件编译完成后,接下来的步骤就是连接了。连接的主要功能就是将全部目标文件中的各个相同段和节的信息依次链接起来拼装成一个单独的可执行文件。同时还会将全部目标文件中须要Relocation的部分的指令进行调整,由于此时能够知道每一个引用符号的位置了。在连接时系统会分析每一个目标文件中的依赖信息,也就是说连接成一个可执行文件中各段各节的内容老是无依赖的目标文件放在前面而有依赖的目标文件放置在后面。
静态库的做用
每当咱们build一个工程项目时,系统老是会先将全部源代码编译为目标文件,再将目标文件连接为可执行程序。即便是咱们改变其中某一个文件中的源代码,而其余文件没有改变也是如此。所以为了加快编译速度,有些文件将再也不以源代码的形式提供,而是能够将一部分目标文件先集中起来造成一个静态库。这样就能够对这部分文件略过编译而直接进行连接从而加快编译的速度。
对于iOS系统来讲由于不支持第三方以动态库的形式集成到咱们的工程中以及上传到appstore。而第三方提供的库由于安全和知识产权以及保密的特性不大可能以源代码的形式提供给咱们,而是以静态库的形式提供给咱们。
可见静态库的做用主要是为了加快编译速度、进行模块划分、以及代码安全的功能。静态库是一个编译产生的结果,而动态库则是编译连接产生的结果。静态库的组成实际上是一个个目标文件。