前语

之前,咱们在探求动画及烘托相关原理的时分,咱们输出了几篇文章,解答了iOS动画是怎么烘托,特效是怎么作业的疑惑。咱们深感体系设计者在创作这些体系结构的时分,是如此脑洞大开,也 深深意识到了解一门技能的底层原理关于从事该方面作业的重要性。

因而咱们决议 进一步探求iOS底层原理的任务 ,本文探求的底层原理围绕“编译器LLVM项目ClangSwiftC优化器LLVMXcode编译的进程】”展开

一、概述

工欲善其事必先利其器,咱们要探求iOS的底层原理,需求掌握一定的前常识,如:

  • 编译器项目-LLVM
  • Xcode调试器-LLDB
  • iOS汇编-ARM、x86(待输出)

本文的中心方针便是对LLDB进行简略介绍 且 对其常用的指令进行恰当的实践

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

1.什么是LLVM?

LLVM(全称 “Low Level Virtual Machine” :低级虚拟机),官方对其的描述是:

  • The name “LLVM” itself is not an acronym; it is the full name of the project.(“LLVM”这个名称自身不是首字母缩略词; 它是项目的全名)
  • LLVM项目的创始人是 Chris Lattner(Swift之父)
    02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
  • 官网:llvm.org/
  • The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. (LLVM项目是模块化、可重用的编译器以及东西链技能的调集)
  • 美国计算机协会 (ACM) 将其2012 年软件体系奖项颁给了LLVM,之前曾经获得此奖项的软件和技能包括:Java、Apache、 Mosaic、the World Wide Web、Smalltalk、UNIX、Eclipse等等

2.LLVM项目简述

LLVM项目的架构如图:

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
从上图咱们能够清晰看到,整个程序编译链能够划分为三部分:编译器前端(左面部分)、优化器(中间部分)、编译器后端(右边部分)。(从我的这篇文章能够更具体了解编译相关的常识:计算机编译原理)

  • 编译器前端(Frontend):词法剖析、语法剖析、语义剖析、生成中间代码llvm-ir
  • 优化器(Optimizer):对中间代码进行优化、改造,使之变成功能更加高效的中间代码llvm-ir(内存空间、履行功率)
  • 编译器后端(Backend):生成指定硬件架构的可履行文件

对编译器王者LLVM的进一步认识:

  • 运用一致的中间代码: 不同的编译器前端、编译器后端运用一致的中间代码LLVM Intermediate Representation (LLVM IR)
  • 只需完结一个前端: 假如需求支撑一种新的编程言语,那么只需求完结一个新的前端
  • 只需完结一个后端: 假如需求支撑一种新的硬件设备,那么只需求完结一个新的后端
  • 通用优化器: 优化阶段是一个通用的阶段,它针对的是一致的LLVM IR,不论是支撑新的编程言语,仍是支撑新的硬件设备,都不需求对优化阶段做修正
  • LLVMGCC的比较:
    • 比较之下,GCC的前端和后端没分得太开,前端后端耦合在了一起。所以GCC为了支撑一门新的言语,或许为了支撑一个新的方针渠道,就 变得特别困难
    • LLVM现在被作为完结各种静态和运行时编译言语的通用根底结构(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell等)

3.探求iOS底层,对LLVM项目的重视点

结合LLVM项目的架构图 和 程序编译链 咱们能够知道,咱们在探求iOS底层原理的时分,需求重视

  • OC编译器前端(Clang)、Swift编译器前端(SwiftC)
  • 优化器(了解即可)
  • 编译器后端(模拟器x86、真机arm架构:以arm64为例,因为现代流行运用和近期未来的iOS设备都会朝arm64架构开展,老架构如armv7、armv7s会被逐步筛选)

二、编译器前端Clang

1.什么是Clang?

  • Clang 是 LLVM项目的一个子项目
  • Clang 是 依据LLVM架构的C/C++/Objective-C编译器前端
  • Clang官网:clang.llvm.org/get_started…
  • 苹果开发渠道Xcode之前的编译器前端是gcc后来被替换成了Clang
  • 比较于GCC,Clang具有如下长处:
    • 编译速度快:在某些渠道上,Clang的编译速度明显的快过GCC(Debug模式下编译OC速度比GGC快3倍)
    • 占用内存小:Clang生成的AST所占用的内存是GCC的五分之一左右
    • 模块化设计:Clang选用依据库的模块化设计,易于 IDE 集成及其他用途的重用
    • 确诊信息可读性强:在编译进程中,Clang 创立并保留了很多具体的元数据 (metadata),有利于调试和过错报告
    • 设计清晰简略容易了解易于扩展增强

2.ClangLLVM的联系

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • 广义的LLVM:整个LLVM架构(包括编译器前端(如Clang)、优化器、编译器后端)
  • 狭义的LLVM:LLVM编译器后端(代码优化、方针代码生成等)

3.Clang 作业的首要流程

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • 预处理(Pre-process):include 扩展、符号化处理、去除注释、条件编译、宏删去、宏替换。 对C输出.i, 对C++输出 .ii, 对 OC 输出 .mi, 对Objective-C++ 输出 .mii
  • 词法剖析 (Lexical Analysis):将代码切成一个个 token,比如巨细括号,等于号还有字符串等。是计算机科学中将字符序列转化为符号序列的进程;
  • 语法剖析(Semantic Analysis):验证语法是否正确,然后将一切节点组成笼统语法树 AST 。由 Clang 中 Parser 和 Sema 合作完结;
  • 静态剖析(Static Analysis):运用它来表明用于剖析源代码以便主动发现过错;
  • 中间代码生成(Code Generation):开始 IR 中间代码的生成了,CodeGen 会担任将语法树自顶向下遍历逐步翻译成 LLVM IR。

4.Clang指令行指令

// 假定原始文件为main.m
// 预编译指令
clang -E main.m -o main.mi
// 生成AST语法树
clang -Xclang -ast-dump -fsyntax-only main.m
// 生成IR中间代码
clang -S -emit-llvm main.m -o main.ll
// 生成IR中间代码并优化,
clang -o3 -S -emit-llvm main.m -o main.ll
// 假如敞开bitcode,生成.bc文件,这也是中间码的一种形式
clang -emit-llvm -c main.m -o main.bc
// 产生汇编指令
clang -S main.m -o main.s
// 生成方针.o文件
clang -c main.m -o main.o

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

三、编译器前端SwiftC

1.什么是 SwiftC?

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • SwiftC 是 Swift 言语的编译器前端

2. SwiftCLLVM的联系

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • SwiftC 作为 Swift言语的编译器前端,终究输出中间代码: LLVM-IR ,提供给编译器后端运用
  • LLVM 作为 编译器后端,输出指定硬件架构环境的 可履行文件(软件包)

3.SwiftC的首要作业流程

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • Parse: 词法剖析组件,生成 AST语法树;
  • Sema(Semantic Analysis):对 AST语法树 进行类型查看,转化为格局正确且类型查看齐备的 AST;
  • Clang Importer: 担任导入 Clang 模块,并将导出的 C 或 Objective-C API 映射到相应的 Swift API 中。终究导入的 AST 能够被语义剖析引证。(因为iOS Native环境下 支撑Swift、OC、C、CPP混编)
  • SIL Gen:由 AST 生成 Raw SIL(原生 SIL,代码量很大,不会进行类型查看);
  • SIL 确保转化:SIL 确保转化阶段担任履行额外且影响程序正确性的数据流确诊,转化后的终究结果是标准的 SIL;
  • SIL 优化:该阶段担任对程序履行额外的高档且专用于 Swift 的优化,包括(例如)主动引证计数优化、去虚拟化、以及通用的专业化;
  • Swift 编译进程引入 SIL 有几个长处:
    • 完结的变数程序的语义(Fully represents program semantics );
    • 既能进行代码的生成,又能进行代码剖析(Designed for both code generation and analysis );
    • 处在编译管线的主通道(Sits on the hot path of the compiler pipeline );
    • 架起桥梁连接源码与 LLVM,减少源码与 LLVM 之间的笼统鸿沟(Bridges the abstraction gap between source and LLVM)
  1. Swift Code : 开发者自己编写的代码
  2. Swift AST : 依据swiftc生成语法树
  3. Raw Swift IL : Swift特有的中间代码
  4. Canonical Swift IL : 更加简洁的中间代码版别
  5. LLVM IR : 编译器前端处理完后转交给LLVM生成后端中间代码
  6. Assembly : 后端对代码进行优化转变成汇编代码
  7. Executable : 汇编代码转化成可履行的二进制代码

4. SwiftC 指令行指令

// 假定原始文件为main.swift
// 剖析输出AST
swiftc main.swift -dump-parse
// 剖析而且查看类型输出AST
swiftc main.swift -dump-ast
// 生成中间体言语(SIL),未优化
swiftc main.swift -emit-silgen -o main.sil 
// 生成中间体言语(SIL),优化后的
swiftc main.swift -emit-sil -o main.sil 
// 生成优化后的中间体言语(SIL),并将结果导入到main.sil文件中
swiftc main.swift -emit-sil  -o main.sil 
// 生成优化后的中间体言语(SIL),并将sil文件中的乱码字符串进行还原,并将结果导入到main.sil文件中
swiftc main.swift -emit-sil | xcrun swift-demangle > main.sil
// 生成LLVM中间体言语 (.ll文件)
swiftc main.swift -emit-ir  -o main.ir
// 生成LLVM中间体言语 (.bc文件)
swiftc main.swift -emit-bc -o main.bc
// 生成汇编
swiftc main.swift -emit-assembly -o main.s
// 编译生成可履行.out文件
swiftc main.swift -o main.o 

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

四、编译器后端

首要流程

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • 优化(Optimize):LLVM 会去做些优化作业;
    • 在 Xcode 的编译设置里也能够设置优化等级-01,-03,-0s;
    • 优化级参数坐落参数坐落Build Settings -> Apple Clang - Code Generation ->Optimization Level
    • 优化级参数 是运用 LLVM 的 Pass 去处理的,咱们能够自己去自定义 Pass。
  • 生成方针文件(Assemble):生成 Target 相关 Object(Mach-o);
  • 链接(Link):生成 Executable 可履行文件。

五、Xcode 编译进程

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

如上图所示,在Xcode按下CMD+B之后的作业流程。

  • 预处理(Pre-process):他的首要作业便是将宏替换,删去注释展最初文件,生成.i文件。

  • 词法剖析(Lexical Analysis):将代码切成一个个 token,比如巨细括号,等于号还有字符串等。是计算机科学中将字符序列转化为符号序列的进程。

  • 语法剖析(Semantic Analysis):验证语法是否正确,然后将一切节点组成笼统语法树 AST 。由 Clang 中 Parser 和 Sema 合作完结。

  • 静态剖析(Static Analysis):运用它来表明用于剖析源代码以便主动发现过错。

  • 中间代码生成(Code Generation):生成中间代码 IR,CodeGen 会担任将语法树自顶向下遍历逐步翻译成 LLVM IR,IR 是编译进程的前端的输出,后端的输入。

  • 优化(Optimize):LLVM 会去做些优化作业,在 Xcode 的编译设置里也能够设置优化等级-O1-O3-Os…还能够写些自己的 Pass,官方有比较完好的 Pass 教程: Writing an LLVM Pass 。假如敞开了Bitcode苹果会做进一步的优化,有新的后端架构仍是能够用这份优化过的Bitcode去生成。

    02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • 生成方针文件(Assemble):生成Target相关Object(Mach-o文件)。

  • 链接(Link):生成Executable可履行文件。

经过这一步步,咱们用各种高档言语编写的代码就转化成了机器能够看懂能够履行的方针代码了。

这儿只是作了一个Xcode编译进程的一个简略的介绍,需求深化了解的同学能够查看 深化浅出iOS编译 。

六、经过指令行,了解OC源文件的编译进程

源码:

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

1.指令行查看编译的进程:

cmd指令:

$ clang -ccc-print-phases main.m

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
解读:

  • +- 0: input, "main.m", objective-c:+-0 输入名为“main.m ” 的objc 源码文件
  • +- 1: preprocessor, {0}, objective-c-cpp-output: +-1 预处理器preprocessor 进行预处理操作,生成 并输出 main.cpp 的底层C++代码
  • +- 2: compiler, {1}, ir: +-2 经过编译器compiler(此处为编译器前端clang Fronted) 作业(词法剖析、语法剖析、语义剖析、生成中间代码),输出中间代码 ir(全称为 LLVM IR)
  • +- 3: backend, {2}, assembler: +-3 经过编译器compiler(此处为编译器优化器 Optimizer)作业(对编译器前端生成的中间代码ir进行优化,得到优化过后的中间代码ir)
  • +- 4: assembler, {3}, object:+-4 经过编译器compiler(此处为编译器后端LLVM Backend )作业(:加工优化过后的中间代码ir,生成汇编assembler)生成汇编代码
  • +- 5: linker, {4}, image:+-5 经过编译器compiler(此处为编译器后端LLVM Backend )作业(将汇编代码 以及项目开发进程中 绑定了的体系动态库 进行链接)
  • 6: bind-arch, "x86_64", {5}, image: +-6 经过编译器compiler(此处为编译器后端LLVM Backend )作业(把汇编代码生成对应方针履行环境的机器架构的可履行文件二进制机器码(此处为bind-arch, “x86_64 “))

2.查看preprocessor(预处理)的结果

cmd指令:

$ clang -E main.m

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

3.词法剖析,生成Token

cmd指令:

clang -fmodules -E -Xclang -dump-tokens main.m

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

4.生成语法树-AST(Abstract Syntax Tree)

cmd指令:

$ clang -fmodules -fsyntax-only -Xclang -ast-dump main.m

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

5.生成中间代码LLVM-IR

LLVM IR有3种表明形式(但实质是等价的,就好比水能够有气体、液体、固体3种形状) 1.text格局:便于阅读的文本格局,类似于汇编言语,拓宽名.ll cmd指令:

$ clang -S -emit-llvm main.m

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • IR根本语法
    • 注释以分号 ; 最初
    • 全局标识符以@最初,部分标识符以%最初
    • alloca,在当时函数栈帧中分配内存
    • i32,32bit,4个字节的意思
    • align,内存对齐
    • store,写入数据
    • load,读取数据
  • 官方语法参阅 llvm.org/docs/LangRe… 2.memory:内存格局 3.bitcode:二进制格局,拓宽名.bc cmd指令:
$ clang -c -emit-llvm main.m

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

七、经过个人的本地LLVM项目工程进行项目编译

咱们寻常开发的时分都是凭借官方IDE Xcode 自带的编译器 进行编译的。咱们在前面已经根本了解了llvm、编译器前端、编译器后端、优化器等,咱们也能够经过自己本地的llvm编译器对自己的工程进行编译,进一步探求llvm编译的进程。

我想,很多朋友都想了解,经过自定义的llvm项目进行编译有什么意义呢?它的运用实践价值是什么呢?

1.运用

  • ibclang、libTooling:
    • 运用:语法树剖析言语转化
    • 官方参阅:clang.llvm.org/docs/Toolin…
  • Clang插件开发
    • 运用:代码查看命名标准代码标准)等 (能够结合团队的编程标准,去定义语法中的一些要求,比如类的命名规矩、办法的命名规矩等。让后经过编译器特性来束缚开发团队)
    • 官方参阅
      • clang.llvm.org/docs/ClangP…
      • clang.llvm.org/docs/Extern…
      • clang.llvm.org/docs/RAVFro…
    • Pass开发
      • 运用:代码优化代码混杂 等 (代码混杂属于安全攻防范畴、对代码进行进一步防护)
      • 官方参阅:llvm.org/docs/Writin…
    • 开发新的编程言语 (高档编程言语的源码,经过clang编译器前端编译,生成llvm中间代码,最终输出方针硬件架构的可履行文件)
      • llvm-tutorial-cn.readthedocs.io/en/latest/i…
      • kaleidoscope-llvm-tutorial-zh-cn.readthedocs.io/zh_CN/lates…

2.下载llvm项目的副本到本地

下载LLVM工程:

  • $ git clone git.llvm.org/git/llvm.gi…
    • 上面那个地址无法拜访 要拜访国内 镜像链接:mirror.tuna.tsinghua.edu.cn/help/llvm/ 去里边拿下载地址: git clone mirrors.tuna.tsinghua.edu.cn/git/llvm/ll…
  • 巨细 648.2 M,仅供参阅 下载clang:
  • $ cd llvm/tools:切换到方才下载的llvm工程文件夹中
  • 拉取项目: $ git clone git.llvm.org/git/clang.g…
    • 上面那个地址无法拜访 要拜访国内 镜像链接:mirror.tuna.tsinghua.edu.cn/help/llvm/ 去里边拿下载地址: $ git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/clang.git
  • 巨细 240.6 M,仅供参阅

3.源码编译

完结前面两项进程之后,咱们本地环境就有了两种源码编译的或许:

    1. 经过cmake+ninja,凭借我本地的LLVM项目进行编译
    1. 经过Xcode,凭借我本地的LLVM项目进行编译

3.1 经过cmake+ninja,凭借我本地的LLVM项目进行编译

  • 装置cmake和ninja(先装置brew,brew.sh/)

    • $ brew install cmake
    • $ brew install ninja
  • ninja假如装置失败,能够直接从github获取release版放入【/usr/local/bin】中 github.com/ninja-build…

  • LLVM源码同级目录下新建一个【llvm_build】目录(终究会在【llvm_build】目录下生成【build.ninja】)

    • $ cd llvm_build
    • $ cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=LLVM的编译输出路径! 此处输出路径为llvm-release
      02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
    • 更多cmake相关选项,能够参阅: llvm.org/docs/CMake.…
  • 顺次履行编译、装置指令

    • $ ninja 编译结束后, 【llvm_build】目录大约 21.05 G(仅供参阅)
    • $ ninja install 装置结束后,装置目录大约 11.92 G(仅供参阅)

3.2 经过Xcode,凭借我本地的LLVM项目进行编译

也能够生成Xcode项目再进行编译,但是速度很慢(或许需求1个多小时) 在llvm同级目录下新建一个【llvm_xcode】目录

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

$ cd llvm_xcode
$ cmake -G Xcode ../llvm  

八、编写clang插件,进行语法查看

1.新建插件目录

  • 1.在【clang/tools】源码目录下新建一个插件目录,假定叫做【hp-plugin】

2.编写插件代码

  • 2.clang插件源码为cpp文件,编写一个语法查看插件如下: HPPlugin.cpp

#include <iostream> 
#include "clang/AST/AST.h"  
#include "clang/AST/ASTConsumer.h" 
#include "clang/ASTMatchers/ASTMatchers.h" 
#include "clang/ASTMatchers/ASTMatchFinder.h" 
#include "clang/Frontend/CompilerInstance.h" 
#include "clang/Frontend/FrontendPluginRegistry.h" 
using namespace clang; 
using namespace std; 
using namespace llvm; 
using namespace clang::ast_matchers;
namespace HPPlugin {
  class HPHandler : public MatchFinder::MatchCallback {
  private:
    CompilerInstance &ci;
   
  public:
    HPHandler(CompilerInstance &ci) :ci(ci) {}
   
    void run(const MatchFinder::MatchResult &Result) {
      if (const ObjCInterfaceDecl *decl = Result.Nodes.getNodeAs<ObjCInterfaceDecl>("ObjCInterfaceDecl")) {
        size_t pos = decl->getName().find('_');
        if (pos != StringRef::npos) {
          DiagnosticsEngine &D = ci.getDiagnostics();
          SourceLocation loc = decl->getLocation().getLocWithOffset(pos);
          D.Report(loc, D.getCustomDiagID(DiagnosticsEngine::Error, "HP插件:类名中不能带有下划线"));
        }
      }
    }
  };
 
  class HPASTConsumer: public ASTConsumer {
  private:
    MatchFinder matcher;
    HPHandler handler;
   
  public:
    HPASTConsumer(CompilerInstance &ci) :handler(ci) {
      matcher.addMatcher(objcInterfaceDecl().bind("ObjCInterfaceDecl"), &handler);
    }
   
    void HandleTranslationUnit(ASTContext &context) {
      matcher.matchAST(context);
    }
  }; 
  class HPASTAction: public PluginASTAction {
  public:
    unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &ci, StringRef iFile) {
      return unique_ptr<HPASTConsumer> (new HPASTConsumer(ci));
    }
    bool ParseArgs(const CompilerInstance &ci, const vector<string> &args) {
      return true;
    }
  };
}
static FrontendPluginRegistry::Add<HPPlugin::HPASTAction>
X("HPPlugin", "The HPPlugin is my first clang-plugin.");

3.编写插件装备

  • 3.编写CMakeLists.txt
add_llvm_library( HPPlugin MODULE BUILDTREE_ONLY
    HPPlugin.cpp
)

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

4.将插件增加至clang编译东西

  • 4.在【clang/tools/CMakeLists.txt】最终加入内容: add_clang_subdirectory(hp-plugin),小括号里是插件目录名

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

5.编译方才新加的插件

运用cmake生成的Xcode项目来编译插件(第一次编写完插件,需求运用cmake从头生成一下Xcode项目):

$ cd llvm_xcode
$ cmake -G Xcode ../llvm

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

  • 插件源代码在【Sources/Loadable modules】目录下能够找到,这样就能够直接在Xcode里编写插件代码
  • 挑选HPPlugin这个target进行编译,编译完会生成一个动态库文件
    02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

自此,一个Clang插件编写并输出完结!!!

九、自定义Clang插件的运用

Xcode环境是Xcode11:

1.加载自定义插件

在Xcode项目中指定加载方才编译出来的插件动态库Build Settings > OTHER_CFLAGS

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

2.Hack Xcode

咱们前面想修正编译器为咱们自己本地的LLVM编译器,发现IDE不让咱们这么干!咱们需求凭借一些东西,对Xcode进行Hack:

  • 下载【XcodeHacking.zip】,解压,修正【HackedClang.xcplugin/Contents/Resources/HackedClang.xcspec】的内容,设 置一下自己编译好的clang的路径
    02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】
  • 然后在XcodeHacking目录下进行指令行,将XcodeHacking的内容剪切到Xcode内部
$ sudo mv HackedClang.xcplugin `xcode-select-printpath`/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins
$ sudo mv HackedBuildSystem.xcspec `xcode-select-printpath`/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications

3.修正Xcode的编译器

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

4.编译项目

编译项目后,会在编译日志看到HPPlugin插件的打印信息(假如插件更新了,最好先Clean一下项目)

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

5.其它插件相关

想要完结更杂乱的插件功能,就需求运用clang的API针对语法树(AST)进行相应的剖析和处理
关于AST的资料:

  • clang.llvm.org/doxygen/nam…

  • clang.llvm.org/doxygen/cla…

  • clang.llvm.org/doxygen/cla…

6.引荐书籍

02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM、Xcode编译的过程】

未深化探求的问题

咱们在前面了解到,程序的汇编进程依靠不同的硬件环境,咱们本次没有对不同的硬件环境的不同汇编探求。需求了解其它汇编常识的,需求朋友们依据个人需求去探求。

总结

经过通篇介绍,咱们了解了: LLVM项目 、iOS的整个编译进程:编译器前端Clang、编译器前端SwiftC、编译器后端、Xcode 编译进程;
而且,在前面的根底上,咱们经过指令行东西了解了: OC源文件的编译进程、经过装置和编译本地LLVM工程、编写了clang插件、运用clang插件进行语法查看的实践;
咱们接下来,会用其它篇幅,去了解LLDB、汇编,进而为探求OC、Swift言语底层原理做衬托!

参阅文章

  • Clang Plugin 之 Debug
  • Clang 之旅–完结一个自定义查看标准的 Clang 插件
  • 依据LLVM开发属于自己Xcode的Clang插件
  • Clang Tutorial 第二部分(LibTooling)
  • Clang Tutorial 第三部分(Plugin)
  • Clang之语法笼统语法树AST
  • LLVM与Clang的一些事儿
  • 运用Xcode开发iOS语法查看的Clang插件

引荐文章

  • 深化研究Clang

  • LLVM每日谈

  • clang 中文用户手册 & llvm 文档

    专题系列文章

1.前常识

  • 01-探求iOS底层原理|总述
  • 02-探求iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM】
  • 03-探求iOS底层原理|LLDB
  • 04-探求iOS底层原理|ARM64汇编

2. 依据OC言语探求iOS底层原理

  • 05-探求iOS底层原理|OC的实质
  • 06-探求iOS底层原理|OC目标的实质
  • 07-探求iOS底层原理|几种OC目标【实例目标、类目标、元类】、目标的isa指针、superclass、目标的办法调用、Class的底层实质
  • 08-探求iOS底层原理|Category底层结构、App启动时Class与Category装载进程、load 和 initialize 履行、关联目标
  • 09-探求iOS底层原理|KVO
  • 10-探求iOS底层原理|KVC
  • 11-探求iOS底层原理|探求Block的实质|【Block的数据类型(实质)与内存布局、变量捕获、Block的品种、内存办理、Block的修饰符、循环引证】
  • 12-探求iOS底层原理|Runtime1【isa详解、class的结构、办法缓存cache_t】
  • 13-探求iOS底层原理|Runtime2【音讯处理(发送、转发)&&动态办法解析、super的实质】
  • 14-探求iOS底层原理|Runtime3【Runtime的相关运用】
  • 15-探求iOS底层原理|RunLoop【两种RunloopMode、RunLoopMode中的Source0、Source1、Timer、Observer】
  • 16-探求iOS底层原理|RunLoop的运用
  • 17-探求iOS底层原理|多线程技能的底层原理【GCD源码剖析1:主行列、串行行列&&并行行列、全局并发行列】
  • 18-探求iOS底层原理|多线程技能【GCD源码剖析1:dispatch_get_global_queue与dispatch_(a)sync、单例、线程死锁】
  • 19-探求iOS底层原理|多线程技能【GCD源码剖析2:栅栏函数dispatch_barrier_(a)sync、信号量dispatch_semaphore】
  • 20-探求iOS底层原理|多线程技能【GCD源码剖析3:线程调度组dispatch_group、事件源dispatch Source】
  • 21-探求iOS底层原理|多线程技能【线程锁:自旋锁、互斥锁、递归锁】
  • 22-探求iOS底层原理|多线程技能【原子锁atomic、gcd Timer、NSTimer、CADisplayLink】
  • 23-探求iOS底层原理|内存办理【Mach-O文件、Tagged Pointer、目标的内存办理、copy、引证计数、weak指针、autorelease

3. 依据Swift言语探求iOS底层原理

关于函数枚举可选项结构体闭包特点办法swift多态原理StringArrayDictionary引证计数MetaData等Swift根本语法和相关的底层原理文章有如下几篇:

  • Swift5中心语法1-根底语法
  • Swift5中心语法2-面向目标语法1
  • Swift5中心语法2-面向目标语法2
  • Swift5常用中心语法3-其它常用语法
  • Swift5运用实践常用技能点

其它底层原理专题

1.底层原理相关专题

  • 01-计算机原理|计算机图形烘托原理这篇文章
  • 02-计算机原理|移动终端屏幕成像与卡顿

2.iOS相关专题

  • 01-iOS底层原理|iOS的各个烘托结构以及iOS图层烘托原理
  • 02-iOS底层原理|iOS动画烘托原理
  • 03-iOS底层原理|iOS OffScreen Rendering 离屏烘托原理
  • 04-iOS底层原理|因CPU、GPU资源耗费导致卡顿的原因和解决计划

3.webApp相关专题

  • 01-Web和类RN大前端的烘托原理

4.跨渠道开发计划相关专题

  • 01-Flutter页面烘托原理

5.阶段性总结:Native、WebApp、跨渠道开发三种计划功能比较

  • 01-Native、WebApp、跨渠道开发三种计划功能比较

6.Android、HarmonyOS页面烘托专题

  • 01-Android页面烘托原理
  • 02-HarmonyOS页面烘托原理 (待输出)

7.小程序页面烘托专题

  • 01-小程序结构烘托原理