浅析鸿蒙中的 Gn 与 Ninja(一)

目录:工具

Ninja简介post

make 的 3 个特性学习

举例说明Ninja 的用法ui

如何向构建工具 Ninja 描述构建图url

后记spa

下载Ninja学习手册及源代码.net

 

鸿蒙系统的编译构建是基于 Gn 和 Ninja 完成的,那么 Gn 和 Ninjia 有什么关系呢?具体又是如何工做的呢?想必大多数热衷于应用开发的同窗都尚未深究过,那么今天就借此机会带着你们扒一扒 Gn 和 Ninja。命令行

 

咱们先来讲说 Ninja 吧!3d

 

Ninja 是借由 Google Chrome 项目而诞生的一个构建工具,它的诞生目标是为了速度。换句话说,在 Google Chrome 项目的开发过程当中,开发者们认为同类型的其它构建工具不给力,因此才会考虑从新开发更高效的工具。要说同类型,那么不得不提构建界的老大哥 make !make 即 GNU Make,一个用于决定如何使用命令完成最终目标构建的程序。blog

 

在这里强调 make 的 3 个特性:

  1. make 只是一个通用程序,它不知道如何具体的完成目标的构建工做
  2. make 须要 makefile 中的描述来决定目标构建的具体方案
  3. make 须要借助其它工具(如:gcc)才能执行方案,最终完成工做

浅析鸿蒙中的 Gn 与 Ninja(一)

这是否是跑题了!不是说好的讨论 Ninja 吗?怎么扯到 make 上去了?!

 

由于 Ninja 能够看做是一个更好的 make !而大多数同窗都熟悉 make ,因此经过对比 make 学习 Ninja 是一个很是好的选择!上述关于 make 的 3 个特性对于 Ninjia 一样适用(理论上,make 有的 Ninjia 都有,而且更好!)。那么,是否是得先学习 make 再学习 Ninja 呢?我以为倒也不是!毕竟咱们最终仍是在鸿蒙上作应用开发,编译构建系统只须要大致了解便可。

 

接下来经过一个简单的例子向你们展现 Ninja 的用法!

 

test.c 是一个简单的 Hello World 程序,用于打印一个字符串和头文件 test.h 中常量 CONST 的值。

浅析鸿蒙中的 Gn 与 Ninja(一)

根据 C 程序的编译方式可知:

  1. 在预处理阶段 test.h 中的代码直接嵌入test.c 中(头文件 .h 最终成为源文件 .c 的一部分)
  2. test.c 编译后获得目标文件 test.o
  3. test.o 连接后获得最终的可执行程序  test.out

 

各个文件在编译过程当中有明显的上下游关系,即:上游文件影响或者产生下游文件。

浅析鸿蒙中的 Gn 与 Ninja(一)

上图即描述了编译过程,同时也反映了这样一个事实:任何一个文件被改动时只可能影响下游文件,而不会影响上游文件。如:test.c 被修改了,那么可能致使编译获得 test.o 发生改变,进而致使最终的可执行程序 test.out 改变。所以,当 test.c 被修改时,那么应该从新触发编译和连接这两个动做。

 

看到这里,有同窗可能存在这样的疑问:怎么知道文件已经被修改了并触发相应动做呢?

 

其实很简单,能够根据文件修改时间判断呀!目前几乎主流的文件系统都会记录文件被修改的时间,因此结合文件的上下游关系可知:上游文件被修改的时间应该老是 小于等于 下游文件被修改的时间。这样,只须要遍历一次上面的构建图就能够知道执行哪些动做产生最终可执行程序了。

浅析鸿蒙中的 Gn 与 Ninja(一)

 

接下来思考这样一个问题:如何向构建工具 Ninja 描述构建图

 

Ninja 的本质是一种通用程序。既然是程序,那么擅长的必然是处理结构化文本!所以,能够用结构化文本(Ninja脚本)来描述构建图。

 

下面直接上代码!

浅析鸿蒙中的 Gn 与 Ninja(一)

解读:

1. Ninja 脚本中的 build 语句描述构建图中的一个文件上下游关系。如:build test.o cc test.c 指明 test.o 由 test.c 经过规则 cc 而构建,test.c 在构建图中位于 test.o 的上游,从 test.c 到 test.o 须要执行的动做经过规则 cc 定义。Ninja 经过判断上下游文件的修改时间决定是否执行规则中定义的动做。多个 build 语句共同描述一个编译构建图。

 

2. Ninja 脚本中经过 rule 定义规则描述构建图中须要执行的动做。如:规则 cc 所定义的具体动做是  gcc -c $in -o $out ,其中 $in 指代上游文件, $out 指代下游文件。对于 build test.o cc test.c 而言,最终执行的动做为:gcc -c test.c -o test.o 。

 

3. 由 C 语言及其编译方式可知:当源文件包含的头文件改动时,源文件须要从新编译。所以,在构建图中头文件瓜熟蒂落的成为了源文件的上游文件,须要考虑的仅仅是如何定义 rule 最终触发编译动做。这里使用的技巧是经过命令 touh 更新源文件的修改时间,因而可定义 rule dp 的执行动做为 touch $out。这样 build test.c : dp test.h 的意思就很清楚了:当 test.h 被修改时,执行 touch test.c 更新修改时间,进而触发从新编译。

 

4. default test.out  指明默认构建的目标是 test.out,即: ninja 执行当前脚本时默认编译构建的是 test.out。

 

理解了 Ninja 脚本的基本构成后就能够经过实验进一步体会了!

 

1. 将上面的脚本另存为文件,并重命名为 build.ninja,且与 test.c 和 test.h 位于同一目录下

浅析鸿蒙中的 Gn 与 Ninja(一)

2. 打开命令行定位到源码目录,执行 ninja > log.txt

浅析鸿蒙中的 Gn 与 Ninja(一)

经过编译输出(log.txt)以及 test.out 的运行结果可知目标构建成功。

 

后记:

这只是一个 Ninja 的入门级介绍,更多的细节你们能够参考附件中的手册。同时,文中的示例代码也能够在附件中下载。你们能够本身动手修改源码(好比:修改 test.h 中 CONST 的值)而后自行编译体会 Ninja 的用法。

 

Enjoy it!

下载Ninja学习手册及源代码

做者:唐佐林

想了解更多内容,请访问: 51CTO和华为官方战略合做共建的鸿蒙技术社区https://harmonyos.51cto.com

相关文章
相关标签/搜索