mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 04:17:17 +00:00
feature: Weex APM
This commit is contained in:
@@ -10,7 +10,7 @@ LLVM 不是 low level virtual machine 的缩写,就是项目名称。
|
||||
|
||||
## 结构
|
||||
|
||||

|
||||

|
||||
|
||||
LLVM 由三部分构成:
|
||||
|
||||
@@ -22,7 +22,7 @@ LLVM 由三部分构成:
|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
正是由于这样的设计,使得 LLVM 具备很多有点:
|
||||
|
||||
@@ -42,7 +42,7 @@ LLVM 现在被作为实现各种静态和运行时编译语言的通用基础结
|
||||
|
||||
广义上来讲,LLVM 说的是一种架构。狭义上来讲,LLVM 强调的是偏后端部分,如下图的除了 clang 编译前端外的部分,包括优化器和编译后端,统称为 LLVM 后端。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMFullStructure.png" style="zoom:45%">
|
||||
<img src="./../assets/LLVMFullStructure.png" style="zoom:45%">
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Clang 相较于 GCC,具备下面优点:
|
||||
|
||||
- 设计清晰简单,容易理解,易于扩展增强
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ clang -ccc-print-phases main.m
|
||||
|
||||
展示如下:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMDisplayPhases.png" style="zoom:45%">
|
||||
<img src="./../assets/LLVMDisplayPhases.png" style="zoom:45%">
|
||||
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ clang -ccc-print-phases main.m
|
||||
|
||||
查看 preprocessor (预处理)的结果:`clang -E main.m`。预处理主要做的事情就是头文件导入( include、import)、宏定义替换等。展示如下:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMPreProcessorPhase.png" style="zoom:35%">
|
||||
<img src="./../assets/LLVMPreProcessorPhase.png" style="zoom:35%">
|
||||
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ clang -ccc-print-phases main.m
|
||||
|
||||
词法分析阶段,主要生成 Token。使用指令 `clang -fmodules -E -Xclang -dump-tokens main.m` 查看具体做了什么
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMAnalysize.png" style="zoom:35%">
|
||||
<img src="./../assets/LLVMAnalysize.png" style="zoom:35%">
|
||||
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ clang -ccc-print-phases main.m
|
||||
|
||||
语法分析阶段,生成语法树(AST,Abstract Syntax Tree)。使用指令 `clang -fmodules -fsyntax-only -Xclang -ast-dump main.m` 查看
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMASTAnalysis.png" style="zoom:35%">
|
||||
<img src="./../assets/LLVMASTAnalysis.png" style="zoom:35%">
|
||||
|
||||
对 main.m 的代码进行改造
|
||||
|
||||
@@ -142,7 +142,7 @@ void test(int a, int b) {
|
||||
|
||||
再次查看 AST 可以加深理解
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMASTAnalysis2.png" style="zoom:35%">
|
||||
<img src="./../assets/LLVMASTAnalysis2.png" style="zoom:35%">
|
||||
|
||||
其中:
|
||||
|
||||
@@ -154,7 +154,7 @@ void test(int a, int b) {
|
||||
|
||||
也就是先运算蓝色框内的值,然后用结果和红色框内的进行相减。所以这是很标准的树形结构。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMASTTreeDemo.png" style="zoom:10%">
|
||||
<img src="./../assets/LLVMASTTreeDemo.png" style="zoom:10%">
|
||||
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ LLVM IR 有3种表示格式:
|
||||
|
||||
- text:便于阅读的文本格式,类似于汇编语言,推展名为 `.ll`。使用指令 `clang -S -emit-llvm main.m` 进行转换
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMIRType1.png" style="zoom:30%">
|
||||
<img src="./../assets/LLVMIRType1.png" style="zoom:30%">
|
||||
|
||||
学过 arm64 汇编的话看这段 IR 很眼熟,汇编里 `load` 相关的指令都是从内存中装载数据,比如 `ldr`、`ldur` 、`ldp`。`store` 相关的指令是往内存中写入数据,比如 `str`、 `stur`、 `stp`
|
||||
|
||||
@@ -313,15 +313,15 @@ Tips:ninja 如果安装失败,可以直接从 [github]( https://github.com/n
|
||||
```shell
|
||||
mkdir llvm_xcode_build
|
||||
cd llvm_xcode_build
|
||||
cmake -S .https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/llvm-project/llvm -B ./ -G Xcode -DLLVM_ENABLE_PROJECTS="clang"
|
||||
cmake -S ../../llvm-project/llvm -B ./ -G Xcode -DLLVM_ENABLE_PROJECTS="clang"
|
||||
```
|
||||
|
||||
|
||||
因为要编写 Clang 插件,是 c++ 代码,所以需要借助 IDE 的能力,我们选用 Xcode 进行编译。如下图所示,代表编译成功
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMComplieXcode1.png" style="zoom:20%">
|
||||
<img src="./../assets/LLVMComplieXcode1.png" style="zoom:20%">
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMComplieXcode2.png" style="zoom:20%">
|
||||
<img src="./../assets/LLVMComplieXcode2.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -349,11 +349,11 @@ Tips:ninja 如果安装失败,可以直接从 [github]( https://github.com/n
|
||||
|
||||
- 先创建一个插件文件夹 `code-style-validate-plugin`
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMAddConfiguration1.png" style="zoom:20%">
|
||||
<img src="./../assets/LLVMAddConfiguration1.png" style="zoom:20%">
|
||||
|
||||
- 编辑 `CMakeLists.txt` 文件,在最后添加 `add_clang_subdirectory(code-style-validate-plugin)`
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMAddConfiguration2.png" style="zoom:20%">
|
||||
<img src="./../assets/LLVMAddConfiguration2.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -382,17 +382,17 @@ Xcode 打开项目,选择自动创建 Schemes
|
||||
|
||||
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeOpenLLVMProject.png" style="zoom:30%">
|
||||
<img src="./../assets/XcodeOpenLLVMProject.png" style="zoom:30%">
|
||||
|
||||
选择 Target 为 `CodeStyleValidatePlugin`,源代码所在文件夹为 `Sources/Loadable modules`,然后选中 CodeStyleValidatePlugin.cpp` 文件进行编写逻辑
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/ClangPluginSourceCode.png" style="zoom:20%">
|
||||
<img src="./../assets/ClangPluginSourceCode.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
初步编写后 Command + B 进行编译,在 Products 下可以看到编译产物:`CodeStyleValidatePlugin.dylib` 动态库。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/ClangCompileProducts.png" style="zoom:20%">
|
||||
<img src="./../assets/ClangCompileProducts.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ Xcode 打开项目,选择自动创建 Schemes
|
||||
|
||||
此步骤的目的是:在 testLLVM 项目中,加载 `CodeStyleValidatePlugin.dylib` 插件可以成功。因为默认的 Xcode 使用的 clang/clang++ 编译器和编译 `CodeStyleValidatePlugin.dylib` 动态库不是一个版本。不做修改的话,Xcode 加载 `CodeStyleValidatePlugin.dylib` 会报错。所以需要先编译出同一个 LLVM 版本的 clang/clang++。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeCompileClang.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeCompileClang.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ Xcode 打开项目,选择自动创建 Schemes
|
||||
- `-Xclang`
|
||||
- 插件名称
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeLoadPlugin.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeLoadPlugin.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -429,7 +429,7 @@ Xcode 打开项目,选择自动创建 Schemes
|
||||
|
||||
在新创建的 TestLLVM Xcode 项目中加载创建的 `CodeStyleValidatePlugin.dylib` 会报错。原因是:由于 Clang 插件需要使用对应的版本去加载,如果版本不一致则会导致编译错误。如下所示:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeLoadClangPluginError.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeLoadClangPluginError.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -441,17 +441,17 @@ Xcode 打开项目,选择自动创建 Schemes
|
||||
|
||||
如下所示:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeSpecifyClangPath.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeSpecifyClangPath.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
继续编译还是会报错,报错如下:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeLoadClangPluginError2.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeLoadClangPluginError2.png" style="zoom:20%">
|
||||
|
||||
解决方案为:在 `Build Settings` 栏目中搜索 `index`,将 `Enable Index-Wihle-Building Functionality` 的 ` Default` 改为 `NO`。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeLoadClangThenBuildErrorFix.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeLoadClangThenBuildErrorFix.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -463,7 +463,7 @@ Tips: 由于重新修改了插件的源码,所以每次 Build 构建完 FANP
|
||||
|
||||
编译成功,可以看到在日志中输出了我们编写的日志信息。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XcodeLoadClangPluginTest.png" style="zoom:20%">
|
||||
<img src="./../assets/XcodeLoadClangPluginTest.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ NS_ASSUME_NONNULL_END
|
||||
|
||||
利用 Clang 查看 AST 指令为 `clang -fmodules -fsyntax-only -Xclang -ast-dump workaholic_person.m`
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/ClassNameViaClangAST.png" style="zoom:20%">
|
||||
<img src="./../assets/ClassNameViaClangAST.png" style="zoom:20%">
|
||||
|
||||
核心思路为:我们要分析类名不符合规范的情况,要精确报错,首先要识别到类名,利用 AST 的能力可以办到(类名在 AST 的 `ObjCInterfaceDecl` 节点上)。然后获取到类名的行号信息,精确报错。
|
||||
|
||||
@@ -786,7 +786,7 @@ X("CodeStyleValidatePlugin", "This plugin is designed for scanning code styles,
|
||||
- 可以对 Category 名做检测,如果带下划线,则报错提示并给出修改意见
|
||||
- 编写的 `CodeStyleValidatePlugin` Demo 中对不符合规范的做了 `DiagnosticsEngine::Warning` 级别的警告。如果遇到1个警告则不影响,继续编译。如果是 `DiagnosticsEngine::Error` 级别的编译报错,遇到1个则终止编译,请注意该区别,按需编写自己的插件逻辑。
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMClangPluginUseInXcode.png" style="zoom:25%">
|
||||
<img src="./../assets/LLVMClangPluginUseInXcode.png" style="zoom:25%">
|
||||
|
||||
|
||||
|
||||
@@ -834,7 +834,7 @@ X("CodeStyleValidatePlugin", "This plugin is designed for scanning code styles,
|
||||
|
||||
- 使用 LLVM 编写 Clang 插件,解析 AST 拿到所有的 `ObjCInterfaceDecl` 信息,然后结合 `ObjCMethodDecl` 信息便可获取 Category 中的 所有方法,再判断方法是否同名
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/ClangASTCategoryMethod.png" style="zoom:20%">
|
||||
<img src="./../assets/ClangASTCategoryMethod.png" style="zoom:20%">
|
||||
|
||||
|
||||
|
||||
@@ -872,7 +872,7 @@ LLVM 项目中 clang 内置了一堆 checker,用于实现 lint。
|
||||
|
||||
- 自动调用 `[super dealloc]`
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/LLVMGenerateSuperDealloc.png" style="zoom:30%" />
|
||||
<img src="./../assets/LLVMGenerateSuperDealloc.png" style="zoom:30%" />
|
||||
|
||||
- 为每个拥有 ivar 的 Class 合成` .cxx_destructor` 方法来自动释放类的成员变量,代替 MRC 时代的 `self.xxx = nil`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user