【iOS】编译与链接

前言

计算机语言分为机器语言、汇编语言和高级语言。

可以将高级语言分为两种:编译语言和解释型语言(直译式语言)。

解释型语言(逐步进行解释执行)

解释语言编写的程序在每次运行时都需要通过解释器对程序进行动态解释和执行,即解释一条代码,执行一条代码

优点:可移植好,因为只需要各种系统有解释器便可运行,不需要乱七八糟的系统库支持

缺点:执行速度慢,因为相比直接执行,多了一个翻译过程。

典型语言:php,javascript

编译型语言(一次性翻译)

编译型语言的程序只要经过编译器编译之后,每次运行程序都可以直接运行,不需要再次“翻译”。

优点:执行速度快

缺点:可移植性差,因为编译需要对操作系统的库做出链接,所以程序运行时需要用到特定的系统库

典型语言:objective-c,swift

编译链接过程

  1. 预处理:处理macro 宏(如#define), import 头文件替换及处理其他的预编译指令,产生.i文件。(都是以#号开头)
  2. 编译:把预处理完的一系列文件进行一系列词法、语法、语义分析,并且优化后生成相应的汇编代码,产生.s文件。
  3. 汇编:汇编器将汇编代码生成机器指令,输出目标文件,产生.o文件。(根据汇编指令和机器指令的对照表一一翻译就可以了)
  4. 链接:在一个文件中可能会到其他文件,因此,还需要将编译生成的目标文件和系统提供的文件组合到一起,这个过程就是链接。经过链接,最后生成可执行文件。

经过编译和链接,才会把写的代码转换成计算机能识别的二进制指令。

iOS编译是啥?

编译其实是一个用代码解释代码的过程。在 Objective-C 和 Swift 的编译过程中,用来解释代码的,使用的是Low Level Virtual Machine 的编译器开发工具套件(LLVM)。简单的说,LLVM 是一个项目,其作用就是提供一个广泛的工具,可以将任何高级语言的代码编译为任何架构的 CPU 都可以运行的机器代码。它将整个编译过程分类了三个模块:前端、公用优化器、后端。

  • 前端:对目标语言代码进行语法分析,语义分析,生成中间代码。在这个过程中,会进行类型检查,如果发现错误或者警告会标注出来在哪一行。我们在开发的过程中,其实 Xcode 也会使用前端工具对你的代码进行分析,并实时的检查出来某些错误。前端是针对特定语言的,如果需要一个新的语言被编译,只需要再写一个针对新语言的前端模块即可。
  • 公用优化器:将生成的中间文件进行优化,去除冗余代码,进行结构优化。
  • 后端:后段将优化后的中间代码再次转换,变成汇编语言,并再次进行优化,最后将各个文件代码转换为机器代码并链接。链接是指将不同代码文件编译后的不同机器代码文件合并成一个可执行文件。

clang 是 LLVM 的一个前端,它的作用是针对 C 语言家族的语言进行编译,像 c、c++、Objective-C。而 Swift 则自己实现了一个前端来进行 Swift 编译,优化器和后端依然是使用 LLVM 来完成。

Xcode 在编译 iOS 项目的时候,使用的正是 LLVM。其实我们在编写代码以及调试的时候,也在使用 LLVM 提供的功能,例如代码高亮(clang)、实时代码检查(clang)、代码提示(clang)、debug 断点调试(LLDB),这些都是 LLVM 前端提供的功能。而对于后端来说,我们接触到的就是关于 arm64、armv7、armv7s 这些 CPU 架构了。

我们的项目是一个 target,一个编译目标,它拥有自己的文件和编译规则,在我们的项目中可以存在多个子项目,这在编译的时候就导致了使用了 Cocoapods 或者拥有多个 target 的项目会先编译依赖库。

iOS编译干了啥?

  1. 写入辅助文件:将项目的文件结构对应表、将要执行的脚本、项目依赖库的文件结构对应表写成文件,方便后面使用;并且创建一个 .app 包,后面编译后的文件都会被放入包中。
  2. 运行预设脚本:Cocoapods 会预设一些脚本,当然你也可以自己预设一些脚本来运行。这些脚本都在 Build Phases 中可以看到。
  3. 编译文件:针对每一个文件进行编译,生成可执行文件 Mach-O,这过程涉及 LLVM 的完整流程,包括前端、优化器、后端。
  4. 链接文件:将项目中的多个可执行文件合并成一个文件。
  5. 拷贝资源文件:将项目中的资源文件拷贝到目标包。
  6. 编译 storyboard 文件:storyboard 文件也是会被编译的。
  7. 链接 storyboard 文件:将编译后的 storyboard 文件链接成一个文件。
  8. 编译 Asset 文件:我们的图片如果使用 Assets.xcassets 来管理图片,那么这些图片将会被编译成机器码,除了 icon 和 launchImage。
  9. 运行 Cocoapods 脚本:将在编译项目之前已经编译好的依赖库和相关资源拷贝到包中。
  10. 对包进行签名
  11. 完成打包

在上述流程中:2 - 9 步骤的数量和顺序并不固定,这个过程可以在Build Phases中指定。Phases:阶段、步骤,这个选项Tab在Xcode中的意思就是编译步骤。其实在Xcode中我们不仅可以设定整个编译步骤和顺序,还可以对编译规则(Build Rules)和具体步骤的参数(Build Settings)进行设定。

iOS整个编译链接过程

在这里插入图片描述

预处理(Prepressing)

处理macro 宏, import 头文件替换及处理其他的预编译指令,产生.i文件(都是以#号开头!)。规则如下:

  1. "#define"删除并展开对应宏定义。
  2. 处理所有的条件预编译指令。如#if/#ifdef/#else/#endif。
  3. "#include/#import"包含的文件递归插入到此处。
  4. 删除所有的注释"//或/**/"。
  5. 添加行号和文件名标识,编译调试会用到。

编译(Compilation)

这个过程就是把上面的main.i文件进行:词法分析、语法分析、静态分析,优化生成相应的汇编代码,最终生成main.s文件。

  1. 词法分析:把源代码的字符序列分割成一个个token(关键字、表示符、字面量、特殊符号),比如把标识符放到符号表里面。
  2. 语法分析:生成抽象语法树AST,此时运算符号的优先级确定了;有些符号具有多重含义也确定了,比如:*是乘号还是对指针取内容;表达式不合法、括号不匹配等等,都会报错。
  3. 静态分析:分析类型声明和匹配问题。比如整型和字符串相加,肯定会报错。
    中间语法生成:CodeGen根据AST自上向下逐步翻译成LLVM IR,并且对在编译期就可以确定的表达式进行优化,比如代码里面的a=1+3,可以优化成a=4。(假如开启了bitcode)
  4. 目标代码生成与优化:根据中间语法生成依赖具体机器的汇编语言;并优化汇编语言。这个过程中,假如有变量且定义在同一个编译单元里,那么就给这个变量分配空间,确定变量的地址。假如变量或者函数不定义在这个编译单元里面,那就等到链接的时候才能确定地址。

汇编(Assembly)

将main.s文件编译成main.o文件。(也就是我们常说的目标文件)

这个过程就是把上面得到的main.s文件里面的汇编指令翻译成机器指令,最终生成等到main.o

链接(Linking)

这个过程就是将main.o编译成对应的Mach-O文件,也就是我们常说的可执行文件。链接的本质就是把一个或多个目标文件和需要的库(静态库/动态库,如果需要的话)组合成一个文件(Mach-O可执行文件)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/2976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【区块链+体育】“数智化”的杭州亚运会,中创助力区块链技术发展

“智能”,是杭州亚运会的办赛理念之一。除了数字藏品开亚运先河,杭州亚组委充分应用区块链、大数据、人工智能等前沿技术,为观众提供从购票、出行、观赛到住宿、美食和旅游等“一站式”服务。 本次亚运会将全程智能陆续落到了实处&#xff0…

CSS 实现 Turbo 官网 3D 网格线背景动画

转载请注明出处,点击此处 查看更多精彩内容 查看 Turbo 官网 时发现它的背景动画挺有意思,就自己动手实现了一下。下面对关键点进行解释说明,查看完整代码及预览效果请 点击这里。 简单说明原理:使用 mask-image 遮罩绘制网格&a…

Python测试框架Pytest的基础入门

Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. 通过官方网站介绍…

ios 通过xib自定义控件

通过xib自定义控件 xib和stroyboayd对比 共同点: 都是用来描述软件界面 都是用interface Builder工具来编辑 本质都是转换成代码去创建控件 不同点: xib是轻量级的,用来描述局部ui界面 创建模型文件 XMGCar 自定义控件 xib 图形设计 …

graylog源码搭建

这里主要讲如何源码安装graylog 下载地址: https://www.graylog.org/downloads/ 下载带有JVM的源码文件源码安装 下载graylog-5.1.3-linux-x64.tgz,并上传到Centos中,执行以下操作 tar -zxvf graylog-5.1.3-linux-x64.tgzcd /etcmkdir -p …

每天一道C语言编程:Cylinder(圆柱体问题)

题目描述 使用一张纸和剪刀,您可以通过以下方式切出两个面形成一个圆柱体: 水平切割纸张(平行于较短的边)以获得两个矩形部分。 从第一部分开始,切出一个最大半径的圆。圆圈将形成圆柱体的底部。 将第二部分向上滚动&…

在 Amazon 上以高可用性模式实现 Microsoft SQL 数据库服务现代化的注意事项

许多企业都有需要 Microsoft SQL Server 来运行关系数据库工作负载的应用程序:一些应用程序可能是专有软件,供应商可使用它强制 Microsoft SQL Server 运行数据库服务;其他应用程序可能是长期存在的、自主开发的应用程序,它们在最…

我们如何在 Elasticsearch 8.6、8.7 和 8.8 中加速数据摄入

作者:Adrien Grand, Joe Gallo, Tyler Perkins 正如你们中的一些人已经注意到的,Elasticsearch 8.6、8.7 和 8.8 在各种数据集上带来了良好的索引加速,从简单的关键字到繁重的 KNN 向量,以及摄取管道繁重的摄取工作负载。 摄取涉及…

2023版7月软件测试面试题(800道)【附带答案】持续更新...

又到了立flag的时候,你的目标是拿下大厂offer?还是多少万年薪?其实这些都离不开日积月累的过程。 为此我特意整理出一份(超详细笔记/面试题)它几乎涵盖了所有的测试开发技术栈,非常珍贵,人手一…

cancal报错 config dir not found

替换classpath中间封号两边的值

1186. 删除一次得到子数组最大和;1711. 大餐计数;1834. 单线程 CPU

1186. 删除一次得到子数组最大和 解题思路:如果没做过还不是很好想,当时自己第一反应是双指针,结果是个动态规划的题。 核心就是dp的定义,dp[i][k]表示以arr[i]结尾删除k次的最大和。看到这里其实就有一点思路了 dp[i][0]表示以…

JVM理论(五)执行引擎--解释器/JIT编译器

概述 首先执行引擎是java虚拟机核心的组成部分之一;而JVM的主要任务是装载字节码到内存,但不能够直接运行在操作系统之上.因为字节码指令并非等价于本地机器指令,它仅仅包含能够被JVM所识别的指令、符号表、以及其他信息;而此时执行引擎就华丽登场,它的任务就是将字节码指令解…

行为型模式 - 策略模式

概述 先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有很多,可以选择Idea进行开发&…

Web 3.0时代,重塑教育与学习方式的可能性

随着科技的快速发展和互联网的普及,教育领域也面临着巨大的机遇和挑战。Web 3.0时代的到来为教育与学习方式带来了全新的可能性。在这个数字化时代,我们可以探索和利用Web 3.0技术,重塑教育的方式,提供更个性化、互动性和灵活性的…

在Illustrator中创建 3D 冰淇淋模型对象

推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 一旦你学会了如何在Illustrator中制作一个对象3D,你可以前往Envato Elements,在那里你可以找到大量的3D设计来激发你的灵感。这个基于订阅的市场拥有超过 2,000 个 Illus…

php实现站群软件权限管理功能示例

1.管理员页面RBAC.php <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>权限管理</title> <script src"bootstrap/js/jquery-1.11.2.min.js"></script> </head>…

项目名称:智能家居边缘网关项目

一&#xff0c;项目介绍 软件环境: C语言 硬件环境: STM32G030C8TX单片机开发板 开发工具: Linux平台GCC交叉编译环境以及ukeil (1)边缘网关概念 边缘网关是部署在网络边缘侧的网关&#xff0c;通过网络联接、协议转换等功能联接物理和数字世界&#xff0c;提供轻量化的联接管…

通过new FormData提交简单数据

通过new FormData提交简单数据 效果示例图代码 效果示例图 代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">* {padding: 0px;margin: 0px;box-sizing: border-…

费尔法克斯水务通过使用 Liquid UI 移动化和定制 SAP PM 来提高收入和数据完整性

背景 费尔法克斯水务是北弗吉尼亚州地区领先的水县。它是华盛顿特区大都会区的三大供水商之一。它每天为近171万居民提供2.<>亿加仑的水。它渴望坚持其愿景&#xff0c;即保持以客户为中心&#xff0c;同时帮助维持该地区的高质量生活和经济状况。 挑战 由于桌面系统&…

【Ceph的部署】

目录 一、基于 ceph-deploy 部署 Ceph 集群1、Ceph 生产环境推荐&#xff1a;2、Ceph 环境规划3、环境准备1、关闭 selinux 与防火墙2、根据规划设置主机名3、配置 hosts 解析4、安装常用软件和依赖包5、在 admin 管理节点配置 ssh 免密登录所有节点6、为每一个服务器配置时间同…