Ninja简介-Android10.0编译系统(九)_google's ninja build system-程序员宅基地

技术标签: 安卓  aosp源码编译之路  aosp  android  源码  

摘要:Ninja具体干了什么?

1 概述

    在 Android 7.0 之前,Android 编译系统使用 GNU Make 描述和shell来构建编译规则,模块定义都使用Android.mk进行定义,Android.mk的本质就是Makefile,但是随着Android的工程越来越大,模块越来越多,Makefile组织的项目编译时间越来越长。这样下去Google工程师觉得不行,得要优化。

    因此,在Android7.0开始,Google采用ninja来代取代之前使用的make,由于之前的Android.mk数据实在巨大,因此Google加入了一个kati工具,用于将Android.mk转换成ninja的构建规则文件buildxxx.ninja,再使用ninja来进行构建工作。

    ninja的网址:https://ninja-build.org

   编译速度快了一些,但是既然要干, 那就干个大的,最终目标要把make都取代,于是从Android8.0开始,Google为了进一步淘汰Makefile,因此引入了Android.bp文件来替换之前的Android.mk。

     Android.bp只是一个纯粹的配置文件,不包括分支、循环语句等控制流程,本质上就是一个json配置文件。Android.bp  通过Blueprint+soong转换成ninja的构建规则文件build.ninja,再使用ninja来进行构建工作。

   Android10.0上,mk和bp编译的列表可以从 \out\.module_paths中的Android.bp.list、Android.mk.list中看到,Android10.0还有400多个mk文件没有被替换完,Google任重道远。

    Android编译演进过程:

     1)Android7.0之前 使用GNU Make

     2)Android7.0 引入ninja、kati、Android.bp和soong构建系统

     3)Android8.0 默认打开Android.bp

     4)Android9.0 强制使用Android.bp

   Google在 Android 7.0之后,引入了Soong构建系统,旨在取代make,它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

    Make 构建系统得到了广泛的支持和使用,但在 Android 层面变得缓慢、容易出错、无法扩展且难以测试。Soong 构建系统正好提供了 Android build 所需的灵活性。

Ninja是一个注重速度的小型构建系统。它与其他构建系统在两个主要方面不同:它被设计为使其输入文件由更高级别的构建系统生成,并且被设计为尽可能快地运行构建。

    Android系统的编译历程:

2 Make与ninja的对比

    在传统的C/C++项目中,通常采用make系统使用Makefile来进行整个项目的编译构建,Makefile指定的编译依赖规则会使编译流程简单,但是make的依赖大而且复杂,在大型项目编译时,使用的模块越来越多,Makefile组织的项目编译时间越来越长,这个对于编译效率来说是一个极大的浪费。

Ninja是由Google员工Evan Martin 开发的小型构建系统。Ninja注重速度,它在两个主要方面与其他构建系统有所不同:Ninja被设计为使其输入文件由更高级别的构建系统生成,并且其被设计为尽可能快地运行构建。

    本质上,Ninja旨在替换Make,这在执行增量(或无操作)构建时很慢。这可能会大大降低开发人员在大型项目上的工作速度,例如Google Chrome将40,000个输入文件编译为单个可执行文件。实际上,谷歌浏览器是忍者的主要用户和动机。它也用于构建Android ,并且被大多数从事LLVM的开发人员所使用。

    与Make相比,Ninja缺少诸如字符串操作之类的功能,因为Ninja生成文件不是要手工编写的。相反,应使用“生成生成器”生成Ninja生成文件。Gyp,CMake,Meson和gn 是流行的构建管理软件工具,它们支持为Ninja创建构建文件。

 

Ninja开发时,认为make由以下几点导致编译慢:

  • 隐式规则,make包含很多默认

  • 变量计算,比如编译参与应该如何计算出来

  • 依赖对象计算

 

ninja相对于make增加了下面这些功能:

  • 如果构建命令发生变化,那么这个构建也会重新执行。

  • 所依赖的目录在构建之前都已经创建了,如果不是这样的话,我们执行命令之前都要去生成目录。

  • 每条构建规则,除了执行命令之外,还允许有一个描述,真正执行打印这个描述而不是实际执行命令。

  • 每条规则的输出都是buffered的,也就是说并行编译,输入内容不会被搅和在一起。

 

    针对这点所以基本上可以认为ninja就是make的最最精简版。

    Make编译使用的文件名为Makefile、makefile或者以.make、.mk结尾的文件,Ninja的文件名一般为build.ninja或者以.ninja结尾的文件。

 

3 ninja的用法

3.1 ninja代码位置

    Android自带ninja,ninja路径:


 
 
  
  1. prebuilts/build-tools/darwin-x86/bin/ninja
  2. prebuilts/build-tools/linux-x86/bin/ninja
  3. prebuilts/build-tools/linux-x86/asan/bin/ninja

3.2 命令的用法

    执行ninja -h 后,可以得到ninja的使用帮助说明

 我们在编译时,常用的是-t参数。我们执行一下ninja -t list会得到相应的指令说明:

    例如 ninja -t clean 用来清除编译中间文件,相比make clean减少了研发人员的开发过程。

指令说明:


 
 
  
  1. ninja subtools :
  2. browse # 在浏览器中浏览依赖关系图。(默认会在 8080 端口启动一个基于python的http服务)
  3. clean # 清除构建生成的文件
  4. commands # 罗列重新构建制定目标所需的所有命令
  5. deps # 显示存储在deps日志中的依赖关系
  6. graph # 为指定目标生成 graphviz dot 文件。
  7. # 如 ninja -t graph all |dot -Tpng -ograph.png
  8. query # 显示一个路径的inputs/outputs
  9. targets # 通过DAG中rule或depth罗列target
  10. compdb # dump JSON兼容的数据库到标准输出
  11. recompact # 重新紧凑化ninja内部数据结构

4 ninja的实践

4.1 下载ninja

下载地址:

git clone https://github.com/ninja-build/ninja.git
 
 
  

4.2 编译ninja


 
 
  
  1. cd ninja
  2. ./configure.py --bootstrap #在ninja目录中执行

4.3 安装ninja

    编译结束后,会在ninja目录中生成ninja的可执行程序ninja。可以直接将ninja程序拷贝到/usr/bin中。cp ./ninja /usr/bin #在ninja目录中执行

    现在就可以在任意位置使用ninja了。

4.4 ninja实践

    1)mkdir test

    2)vim test/main.c

   填入代码内容:


 
 
  
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main() {
  4. printf( "This is my first Ninja Project!\n");
  5. return 0;
  6. }

    3)配置build.ninja

      vim build.ninja

    填入内容:


 
 
  
  1. cc = g++
  2. cflags = -Wall
  3. rule cc
  4. command = gcc $cflags -c $in -o $out
  5. description = compile .cc
  6. build foo.o: cc foo.c

    4)编译:


 
 
  
  1. cd test
  2. ninja

 

5 ninja编译流程

5.1 AOSP编译过程

 

5.2.ninja生成过程

    在编译过程中,Android.bp会被收集到out/soong/build.ninja.d,blueprint以此为基础,生成out/soong/build.ninja

    Android.mk会由kati/ckati生成为out/build-aosp_arm.ninja

    两个ninja文件会被整合进入out/combined-aosp_arm.ninja

    最终由ninja -t out/combined-aosp_arm.ninja来完成最终的编译

    out/combined-aosp_arm.ninja内容如下所示:


 
 
  
  1. builddir = out
  2. pool local_pool
  3. depth = 42
  4. build _kati_always_build_: phony
  5. subninja out/build-aosp_arm.ninja
  6. subninja out/build-aosp_arm- package.ninja
  7. subninja out/soong/build.ninja

6 总结

    Ninja的诞生,主要是为了提升编译速度,Ninja中去除了变量的计算,没有默认规则, 依赖必须显式声明,从而提升编译速度。基本上可以认为ninja就是make的最最精简版。

 

参考:

《The Ninja build system》

《Ninja 构建系统》

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mingmigndfds/article/details/125280028

智能推荐

CareerCup1.6-程序员宅基地

文章浏览阅读395次。Question1.6:Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place?从最外层到最里层逐层反转顺时针的话:

概述C语言中的关键字_什么是关键字c语言-程序员宅基地

文章浏览阅读1.1k次,点赞6次,收藏12次。数据类型关键字(12个)char 声明字符型变量或函数 double 声明双精度浮点数变量或函数 long 声明长整型变量或函数 short 声明短整型变量或函数 signed 声明有符号变量或函数 unsigned 声明无符号函数或变量 enud..._什么是关键字c语言

AC旁挂组网-程序员宅基地

文章浏览阅读4.4k次。设备清单:1、AR2240C--出局2、S5720-28TP-PWR-LI-AC--接入交换机3、AC6507S——wu'xiang

Edge/Chrome浏览器强制将http转https的解决方案_edge 访问http-程序员宅基地

文章浏览阅读4.6k次,点赞7次,收藏15次。Edge版本:120.0.2210.133 (正式版本) (64 位)(此时会自动转成https,这一步不能跳过,接下来继续)(不带http://前缀)(不带http://前缀)该版本下成功,仅供参考。(带http://前缀)_edge 访问http

非常详细的 Docker 学习笔记_docker配置volumes: xx:xx-程序员宅基地

文章浏览阅读575次。一、Docker 简介Docker 两个主要部件:Docker: 开源的容器虚拟化平台Docker Hub: 用于分享、管理 Docker 容器的 Docker SaaS 平台 -- Docker HubDocker 使用客户端-服务器 (C/S) 架构模式。Docker 客户端会与 Docker 守护进程进行通信。Docker 守护进程会处理复杂繁重的任务,例如建立、_docker配置volumes: xx:xx

杭电ACM——HDU-1108最小公倍数_acm 杭电最小公倍数-程序员宅基地

文章浏览阅读602次。HDU 1108此题有两种方法:(1)欧几里德求最大公约数,再求最小公倍数#includeusing namespace std;int fun(int a,int b){while(a!=b){if(a>b) a=a-b;//欧几里德法,只要两个数不相等,就反复要大数减小数,直到相等为止if(a}return a;}int ma_acm 杭电最小公倍数

随便推点

Android——动态申请权限_xxpermission 申请动态权限activity-程序员宅基地

文章浏览阅读299次。android动态申请权限_xxpermission 申请动态权限activity

[ACTF新生赛2020]crypto-rsa3_[actf新生赛2020]crypto-rsa3 buuctf-程序员宅基地

文章浏览阅读263次。BUUCTF·[ACTF新生赛2020]crypto-rsa3`·WP_[actf新生赛2020]crypto-rsa3 buuctf

嵌入式小试-程序员宅基地

文章浏览阅读56次。stm32的点灯是,通过使能外设GPIO时钟,发出指令给外设GPIO,外设GPIO收到指令后,着手配置自己的寄存器,然后给IO口模式,让其实现各种功能。5:生成的hex文件下载到仿真中,右键仿真中的51(用的AT89C52)芯片,选择编辑属性,打开Program File 选择写好的hex文件。分别设置GPIOA推挽输出,以及定义A0口为输出口,配置速率50HZ。1:配置软件环境,需要用到Keil和FlyMcu(烧录程序)2:keil写好相关代码,并生成hex文件。4:定时器配置函数如下。

[MSP430]入门之中的一个 总体认识-程序员宅基地

文章浏览阅读164次。这是由TI公司推出的一款比較单片机, 相对stm32来说简单些, 由于它是16位的, 所以我们在学习中可能也会像51一样, 直接操纵寄存器.TI设计这款单片机的初衷是, 让它用于低功耗的嵌入式设备中.Reduced instruction set computing, or RISC (pronounced 'risk'), is aCPU design strateg..._conseq_2

小白在mac安装eclipse及Java和karel全记录1_maclctetrls是什么意思-程序员宅基地

文章浏览阅读371次。小白在mac安装eclipse及Java和karel全记录1系统版本: macOS Mojave 10.14.2你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。第一步下载java下载java1.8版本 (我们需要先下载java的1.8版本,确认可以运行eclipse后再下载Java的1.6版本,保证Karel在eclipse内可以正常运行)java1.8官方链接:h..._maclctetrls是什么意思

react源码解析3.react源码架构_react前端架构图-程序员宅基地

文章浏览阅读109次。react源码解析3.react源码架构视频讲解(高效学习):进入学习往期文章:1.开篇介绍和面试题2.react的设计理念3.react源码架构4.源码目录结构和调试5.jsx&核心api6.legacy和concurrent模式入口函数7.Fiber架构8.render阶段9.diff算法10.commit阶段11.生命周期12.状态更新流程13.hooks源码14.手写hooks15.scheduler&Lane16.concurrent模式17._react前端架构图