辽宁鲲鹏建设集团网站/国家免费技能培训有哪些
简介
Bazel Google开源的,是一款与 Make、Maven 和 Gradle 类似的开源构建和测试工具。 它使用人类可读的高级构建语言。Bazel 支持多种语言的项目,可为多个平台构建输出。Bazel支持任意大小的构建目标,并支持跨多个代码库和大量用户的大型代码库。是Google主推的一种构建工具。
Googl的bazel历史和计划
Timeline
上面这张图主要讲述了 Bazel 和 AOSP 的发展时间线。这里解读一下,基本上对 Bazel 和 AOSP 的构建相关的历史可以有一个大致的了解。
大家可能知道,与世界上 99.99% 的公司不同,Google 将几乎整个公司所有项目(据说不包括 Chrome 和 Android),数十亿行代码都放在一个代码仓库中,这个仓库我们就叫它 monorepo。从上面得图上可见,这个 monorepo 项目的时间大致起始于 2003 年。
而 Android 项目,即我们本文中的 AOSP,在 Google 公司内部代码仓库的建立起始于 2005 年,也正是在这一年,Google 花了五千万美金收购了 Andy Rubin 创建的 Android Inc.。和所有很多其他软件项目一样,早期的 Android 的构建系统也是基于 Make 建立的,那还是在有点遥远的 2006 年,到了 2015 年的时候随着 Android 代码体积的迅速膨胀,Google 发现 Make 已经不堪大用,于是发起了 Soong 项目来替代 Make。当然整个替代过程比我们想象的要复杂的多,有关这些内容,下文还会谈到,也可以参考我们以前发布的另外一篇介绍 Soong 的文章 "AOSP Build 背后涉及的相关知识汇总"。
而那时 Bazel 项目还没有开始,直到 2007 年,才开始有了创建一个公司内部的构建系统(也就是 Blaze)的想法。Blaze 作为 Google 公司内部使用构建工具,目前已经发展成为 Google 的整个 momorepo 生态链中不可或缺,乃至最重要的一环。因为整个 Google 的 monorepo 代码库有几百万个代码文件,几十 TB 的数据,加上大家是代码级依赖,如果按照传统的开发和编译方法,即使只 check out 直接和间接依赖的代码,其数据规模和编译时间也不可接受。而 Blaze 配合 CitC 可以做到开发时只需 check out 需要修改的代码,编译时将所有依赖进行分布式编译,编译上万 C++ 文件也只需几分钟。Blaze还有一个好处就是为全公司提供了整齐划一的编译环境,使得编译器、三方库版本等都不再是问题。到了 2015 年的时候,Google 在 Blaze 的基础上发布了其开源移植版本,并命名为 Bazel。
时间到了 2019 年,Google 又发起了一个将 Android 的 Build 系统迁移到 Bazel 的计划。在此不得不对 Google 工程师的文化翘起我的大拇指,敢于创新,追求卓越已经深深地根植在这家公司的文化精髓中。但由于 Android 系统构建的复杂性,此迁移尚处于早期阶段。从 AOSP 12 开始,会发现 AOSP 的源码仓库下出现了一些和 bazel 有关的内容,这引起了我的好奇心,找了些资料来看了一下,于是总结了这篇文章与大家分享。
before
看一下没有加入 Bazel 支持之前 AOSP 项目的构建系统组成和构建的大致过程。如下图所示:
这张图上内容分成三部分,其中灰色的模块是 AOSP 构建系统的组成部分,我们可以发现包含了 Kati,Soong 和 ninja 好几个东东,还是比较复杂的。黄色的可以认为是整个构建过程中各个构建组件的输出和输入:
-
最左边的内容指得是对 “产品配置信息” 的处理。所谓产品,就是形如我们在执行
lunch aosp_arm-eng
时指定的aosp_arm-eng
就是一个 product。这个 product 定义了我们要构建的系统 image 中具体的组成内容。定义的内容目前是按照 Makefile 的语法写在一系列Product.mk
文件中,然后通过 Kati 系统处理后输出生成一系列的配置信息(图上的 Config Vars),以 Make 变量和环境变量的形式保存下来并作为中间部分的输入。Kati 系统是 Google 为了提高构建速度,自己采用 C++ 开发的用来代替 Make 的一套构建系统,但是后来又给 Soong 替代了,只可惜一直到现在为止 Soong 都没有能够完全替换 Kati。所以就成了目前这个尴尬的局面。 -
中间部分体现的是对 “模块构建动作(action)” 的处理。总体上就是输入构建软件模块的描述,输出是供 ninja 读取的
.ninja
文件。而.ninja
文件中的内容可以理解为就是实际的构建动作(action)描述,简单的打个比方就好像我们自己在命令行中输入的那些形如gcc ... -o a.out xxx.c
这些命令,这些命令驱动了 ninja 完成最终的编译链接动作。在中间部分的处理上存在两套并行的处理系统。一套是 Soong,这是 Google 采用自家的 Go lang 编写的第二代构建系统(如果把 Kati 看成是第一代的话)。其输入的描述信息采用的是遵循 Blueprint 语法的定义,和上面我们介绍的 Bazel 系统的 BUILD 文件中的语法非常类似。这些 Blueprint 格式的描述存放在 AOSP 源码树下各个模块的子目录下的Android.bp
文件中,每一个Android.bp
描述了本模块构建的规则。和 Soong 并行的另外一套系统就是 Kati,它承接了剩下的那些还没有完全转为采用Android.bp
描述的模块,这些没有完成的模块仍然采用 Makefile 语法描述的.mk
文件来描述自身的构建规则,然后作为输入被 Kati 读取,输出供 ninja 使用的.ninja
文件。同时在 Soong 和 Kati 以上的转化过程中还会参考左边产品配置信息构建产生的 Config vars 信息,决定哪些模块需要处理,哪些不需要。 -
最右边指的就是最终的 “实际构建动作的执行”,这部分在目前 AOSP 上在第一代 Kati 系统时已经采用了 ninja 并一直延续到现在。ninja 读入 Soong 和 Kati 生成的
.ninja
描述文件,驱动实际的工具链程序完成最终模块的构架和系统 Image 的组装。
after
在 Google Open Source Live "Bazel day" 中 Google 希望的第三代基于 Bazel 的 AOSP 构建系统完成后整个构建过程是变成如下情况,见下图所示:
也就是说上一节中涉及的 “产品配置信息” 的定义信息(见图中左边下部标注为 “product config” )和涉及 “模块构建动作(action)”(见图中左边上部标注为 “code” )统一采用 BUILD 文件进行描述和定义。由 Bazel 统一处理后,并由 Bazel 负责驱动实现上一节中的第三部分 “实际构建动作的执行”(ninjia 也不再需要了)。整个构建过程全部统一由 Bazel 完成。
而且根据 Bazel 的文档说明,现有 AOSP 中的自动化测试部分的驱动组件也由 Bazel 系统承接,整个替换是全方位的,更详细的针对 Android buid system component 执行 Bazel 替换的对比,可以看 android.googlesource.com
now
虽然理想很丰满,但现实却是骨感的。完整的替换过程相当的复杂,不仅仅在于现有 Android 构建系统的复杂性,也在于 Android 系统本身就是一个巨型复杂系统。
Google 的计划是逐步完成这个过程的替换,就像当初从 Kati 到 Soong 的转变一样。替换的方案还是从上面提到的三个方向入手:
- 对 “产品配置信息” 的处理
- 对 “模块构建动作(action)” 的处理
- 最终的 “实际构建动作的执行”
而且为了保证替换不会影响现有用户的使用体验,包括构建速度和使用习惯。
大致的替换方案如下图所示,我根据我的而理解解释一下,如果有什么不对的地方请大家不吝指出。其中注意下图中增加啊的绿色部分就是为实现 Bazel 替换引入的新组件。
-
在对 “产品配置信息” 的处理上,Google 会引入两个新的工具
convert
和product_config
。convert
负责将含有产品配置信息处理的.mk
文件转换为以 Starlark 语法描述的替代文件,在图上标识为后缀为.bzl
的 文件,我理解就是对应 图(4) 中标识为(product config)的 BUILD 文件。而product_config
则负责将.bzl
文件进一步转化为 Config vars。我猜想分成两步的方式可能是为了在演变成最终的 图 (4) 后,.bzl
文件可以作为包含 product config 信息的 BUILD 文件保留下来。 -
在对 “模块构建动作(action)” 的处理上,Google 会新开发一个叫做 bp2build 的工具,负责将现有系统中的
Android.bp
文件转化为 BUILD 文件。而为了兼容目前在该阶段生成.ninja
文件的需要,Bazel 系统还要改造一下,能够输入 BUILD 文件,输出.ninja
文件(目前的 Bazel,读入 BUILD 就直接驱动构建了,并没有 ninja 的介入)。从图上来看,会存在一段时间,AOSP 构建系统中将同时存在三套处理系统。是不是很复杂 :(。 -
在对最终的 “实际构建动作的执行”上,同样需要改动 Bazel,使其能够像 ninja 一样读入
.ninja
文件,即基于.ninja
文件驱动实际的构建动作。也就是说在过渡阶段,AOSP 的构建系统将同时支持两种构建模式:一种是 legacy mode with ninja;另一种是 the new mode with Bazel。 -
Bazel for AOSP 进展状态
仍然是基于 Google Open Source Live "Bazel day" , 注意视频时间标注为 2021 年 4 月 2 日 。所以不能说是最新的,而是截至本文完成前一年的状态,我看了一下大致和我们移植 AOSP 12 的 aosp-riscv 采用的 tag:
android-12.0.0_r3
差不多的时间。从当时的进展来看,只能说 “任重而道远” 啊!不多说了,大家可以对照上面的介绍估计一下 Google 的进度。最近的状态我们还是要等 13 的代码放出来再看。也希望本文的介绍能对大家了解 Bazel for AOSP 有所帮助。
优劣势
优势
官方说明:
-
高级构建语言。Bazel 使用人类可读的抽象语言,在较高的语义级别描述项目的构建属性。与其他工具不同,Bazel 的运作涉及库、二进制文件、脚本和数据集的概念,可以避免将单个调用编写到编译器和链接器等工具的复杂性。
-
Bazel 既快速又可靠。Bazel 会缓存之前完成的所有工作,并跟踪文件内容和 build 命令的更改。这样,Bazel 就会知道何时需要重新构建应用,并且只会重新构建。为了进一步加快构建速度,您可以将项目设置为以高度并行的方式进行构建。
-
Bazel 是多平台的。Bazel 可在 Linux、macOS 和 Windows 上运行。Bazel 可以从同一项目为多个平台(包括桌面设备、服务器和移动设备)构建二进制文件和可部署软件包。
-
Bazel 支持扩缩。在处理包含 10 万个以上源文件的构建时,Bazel 可保持敏捷性。它可以处理数以万计的多个代码库和用户群。
-
Bazel 可扩展。它支持许多语言,您可以扩展 Bazel,以支持任何其他语言或框架。
其它人总结:
-
很方便地获取第三方依赖;
-
构建多语言的软件系统,One Tool,All Languages;
-
优秀的缓存和依赖计算,编译速度非常优异;
-
DevOps部署云构建,可极大复用宝贵的计算资源;
快(Fast)
Bazel的构建过程很快,它集合了之前构建系统的加速的一些常见做法。包括:
1.增量编译。只重新编译必须的部分,即通过依赖分析,只编译修改过的部分及其影响的路径。
2. 并行编译。将没有依赖的部分进行并行执行,可以通过--jobs来指定并行流的个数,一般可以是你机器CPU的个数。遇到大项目马力全开时,Bazel能把你机器的CPU各个核都吃满。
3. 本地缓存+远程缓存。Bazel将构建过程视为函数式的,只要输入给定,那么输出就是一定的。而不会随着构建环境的不同而改变(当然这需要做一些限制),这样就可以分布式的缓存/复用不同模块,这点对于超大项目的速度提升极为明显。
4. 远程构建。默认情况下,Bazel 会在本地机器上执行构建和测试。通过 Bazel 构建的远程执行,您可以将构建和测试操作分散到多个机器(例如数据中心)。
可伸缩(scalable)
Bazel号称无论什么量级的项目都可以应对,无论是超大型单体项目monorepo、还是超多库的分布式项目multirepo。Bazel还可以很方便的集成CD/CI ,并在云端利用分布式环境进行构建。
它使用沙箱机制进行编译,即将所有编译依赖隔绝在一个沙箱中,比如编译golang项目时,不会依赖你本机的GOPATH,从而做到同样源码、跨环境编译、输出相同,即构建的确定性。
跨语言(multi-language)
如果一个项目不同模块使用不同的语言,利用Bazel可以使用一致的风格来管理项目外部依赖和内部依赖。典型的项目如 Ray。该项目使用C++构建Ray的核心调度组件、通过Python/Java来提供多语言的API,并将上述所有模块用单个repo进行管理。如此组织使其项目整合相当困难,但Bazel在此处理的游刃有余,大家可以去该repo一探究竟。
可扩展(extensible)
Bazel使用的语法是基于Python裁剪而成的一门语言:Startlark。其表达能力强大,往小了说,可以使用户自定义一些rules(类似一般语言中的函数)对构建逻辑进行复用;往大了说,可以支持第三方编写适配新的语言或平台的rules集,比如rules go。 Bazel并不原生支持构建golang工程,但通过引入rules go ,就能以比较一致的风格来管理golang工程。
劣势
-
隔离未遵循程惯例:从策略上看,Bazel从其他遗留库获取代码,这是必须的,否则Bazel自己完蛋了;其他库要想从Bazel获取,用户也必须使用Bazel,用户真的被强绑定了。
-
依赖于JVM。
本文属于如下文章中的子章节
bazel学习系列章节汇总_m0_74043383的博客-CSDN博客
相关文章:

bazel介绍以及其发展历史
简介 Bazel Google开源的,是一款与 Make、Maven 和 Gradle 类似的开源构建和测试工具。 它使用人类可读的高级构建语言。Bazel 支持多种语言的项目,可为多个平台构建输出。Bazel支持任意大小的构建目标,并支持跨多个代码库和大量用户的大型代…...

固定资产管理分析怎么写?
对企业内的固定资产进行全面的统计和分析,包括设备、装修、维修等方面的信息,有助于企业进行资产管理和风险控制。 通过该软件,用户可以实现对资产的跟踪和管理,如实时监测设备的使用情况,提高设备利用率和维护效率…...

【项目源码】一套基于springboot+Uniapp框架开发的智慧医院3D人体导诊系统源码
智慧医院3D人体导诊系统源码 开发语言:java 开发工具:IDEA 前端框架:Uniapp 后端框架:springboot 数 据 库:mysql 移 动 端:微信小程序、H5 “智慧导诊”以人工智能手段为依托,为…...

可能的二分法 -- 二分图判定【DFS、BFS分别实现】
886. 可能的二分法 class PossibleBipartition:"""可能的二分法「其实考察的就是二分图的判定」用dfs和bfs 两种方法分别实现https://leetcode.cn/problems/possible-bipartition/"""def __init__(self):self.success Trueself.color []self.…...

六级翻译备考
classical 经典的 Chinese literature 中国文学 朝代dynasty 统治 rule 社会稳定 steady society 治理有序 orderly governance 伟大的greatest 时代 times或者periods 被人们描绘成人类历史上伴随着治理有序,社会稳定的最伟大的时代之一 more and more越来越多 …...

Vue框架--Vue中的数据绑定
Vue中有两种数据绑定的方式 1.单向数据绑定(v-band):数据只能够从data流向页面 2.双向数据绑定(v-model):数据不仅仅能够从data流向页面,也可以从页面流向data。 备注: 1.双向绑定一般都应用在表单类元素上。(如:input、select等有value属性值的标签上) 2.…...

Unity——热更新浅析
热更新的思想从本质上来讲,要考虑一些问题。例如,一个完整的游戏最多可以有多大比例的资源通过网络加载?能否让尽可能多的资源通过网络加载? 通过网络加载有很多好处,不仅可以极大减小安装包的体积,而且有…...

IMPLEMENT_DYNCREATE的分析
一、介绍 IMPLEMENT_DYNCREATE 是一个宏(macro),通常与DECLARE_DYNCREATE宏一起在MFC框架中使用。它的作用是为一个派生自 CObject 的MFC类提供运行时类型信息(RTTI)和对象的动态创建支持。 具体来说,IMP…...

Java实现根据短连接获取1688商品详情数据,1688淘口令接口,1688API接口封装方法
要通过1688的API获取商品详情数据,您可以使用1688开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例,展示如何通过1688开放平台API获取商品详情属性数据接口: 首先,确保您已注册成为1688开放平台的开发者…...

ABAP FICO 凭证替代 凭证校验
凭证校验 1.T-CODE--->GGX2--->GBLR-->ZRGGBR000 2.将程序RGGBR000 复制为ZRGGBR000 3.GGB0--》财务会计--》凭证抬头或者行项目维护检验规则 4.OB28 维护特定的公司代码和调用点和确认,活动等级设置为1 5.GGB4-->激活校验 凭证替代 1.T-CODE--->GG…...

项目验收有哪些流程?
验收流程 科技计划项目验收/课题验收测试服务的被测对象是国家重大专项、科研课题的软件成果物,可以是一个模块、软件或系统等,也可以是软件套件或软件原型等。测试范围主要来源于课题的合同书/可行吧报告/申报书中的技术指标要求。所出具的科技项目验收…...

C++,类的继承
一、继承的基本概念 继承使得C能够从已有的类派生出新的类,而派生类继承了原有类的特征,包括方法。被继承者称为父类或基类,继承者称为子类或派生类。 继承的目的: 实现代码的重用性建立父类和子类之间的联系在实现多态的时候&a…...

作业33333333
一、正向解析 在开启DNS服务之前先将防火墙关闭。 systemctl stop firewalld.service 开启DNS服务,需要开启端先进行安装主软件,以及配置包管理软件 配置包管理软件一般会跟随主软件一起安装,如果没有手动安装一次就可以了。 安装完成之后&…...

Spring Cloud--从零开始搭建微服务基础环境【二】
😀前言 本篇博文是关于Spring Cloud–从零开始搭建微服务基础环境【二】,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,…...

算法工程题(中序遍历)
* 题意说明: * 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 * * 示例 1: * 输入:root [1,null,2,3] * 输出:[1,3,2] * * 示例 2: * 输入:root [] * 输出:[] * *…...

jsch网页版ssh
使用依赖 implementation com.jcraft:jsch:0.1.55Server端代码 import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.TimeUnit; import o…...

教程i.MX8MPlus开发板SPI转CAN操作
飞凌嵌入式OKMX8MP-C核心板有两路原生CAN总线,但用户在开发产品时可能需要用到更多的CAN,这该如何解决呢?今天小编将为大家介绍一种SPI转CAN的方法,供各位工程师小伙伴参考。 说明 OKMX8MP-C核心板有两路原生的SPI总线,…...

Docker中容器的随机命名方式
使用 docker 创建容器时,如果没有用 --name 指定,docker 会为用户选择一个名称, 格式是两个带有下划线的单词,如xxx_yyyy 其相关的实现在此处 pkg/namesgenerator/names-generator.go[1] 源码中有两个数组,第一个是一个…...

大数据Flink实时计算技术
1、架构 2、应用场景 Flink 功能强大,支持开发和运行多种不同种类的应用程序。它的主要特性包括:批流一体化、精密的状态管理、事件时间支持以及精确一次的状态一致性保障等。在启用高可用选项的情况下,它不存在单点失效问题。事实证明&#…...

数学中的自由与我们的生活
数学中的这些自由可以帮助我们养成很多优秀的品格。具体来说,知识的自由使我们变得足智多谋,让我们可以根据问题的具体情况选择恰当的工具和方法。探索的自由使我们在集体讨论时敢于大声发言,积极提问,让我们在为探索发现而欢呼雀…...

8 python的迭代器和生成器
概述 在上一节,我们介绍了Python的模块和包,包括:什么是模块、导入模块、自定义模块、__name__、什么是包、创建包、导入包等内容。在这一节中,我们将介绍Python的迭代器和生成器。在Python中,迭代器是一个非常重要的概…...

Git的基本使用笔记——狂神说
版本控制 版本迭代, 版本控制( Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。 实现跨区域多人协同开发 追踪和记载一个或者多个文件的…...

【小程序】外部二维码扫码打开微信小程序并跳转到指定页面
外部二维码扫码打开微信小程序并跳转到指定页面 您需要使用微信提供的跳转链接和相关参数。以下是实现的步骤: 生成跳转链接:使用以下链接格式生成跳转链接,其中APPID是您的小程序的 AppID,PATH是您要跳转的页面路径,…...

bazel安装
安装 首先安装一下 Bazel 环境。参考 https://bazel.build/install。我是在 Ubuntu 上实验的,所以安装过程参考的是:https://bazel.build/install/ubuntu,有很多种安装方法,我选择的是使用二进制安装程序。这个具体参考的又是 ht…...

Typescript的class语法[类]的操作和应用
TypeScript 是一种面向对象的编程语言,它扩展了 JavaScript,为其添加了类型系统和其他一些特性。TypeScript 的 class 语法可以让开发者更加方便地使用面向对象的编程方式。本文将详细介绍 TypeScript 的 class 语法的操作和应用,并提供代码案…...

OPENCV实现暴力特征匹配
# -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/9/1 """ import cv2 import numpy as np# 读...

揭秘亚马逊Amazon测评,掌握细节和技巧,提升产品销量和评论数量
亚马逊是全球最大的跨境电商平台,拥有全球65个国家的几十个网站。对于跨境卖家来说,亚马逊是最值得选择的平台之一。 亚马逊的八大站点分别是美国、加拿大、墨西哥、欧洲、澳大利亚、日本、中东和巴西。 美国站点是全球最大的零售市场,拥有…...

Linux线程互斥
目录 一、线程不安全 1.线程不安全现象 2.线程不安全程序的特质 3.线程不安全程序的原因 二、线程互斥 1.基本概念 2.锁 (1)认识锁 (2)互斥锁的使用 (3)代码的改造 3.锁的本质 (1&a…...

【仿写spring之ioc篇】三、检查是否实现了Aware接口并且执行对应的方法
Aware接口 Aware接口中只是设置了对应的set方法,目前只定义了三个Aware 以BeanNameAware为例 package com.ez4sterben.spring.ioc.factory.aware;/*** bean名字清楚** author ez4sterben* date 2023/08/31*/ public interface BeanNameAware {/*** 设置beanName* …...

C++ 异常处理
C 异常(Exception)是指在程序运行时产生的特殊情况,例如,尝试除以零的操作。异常提供了一种转移程序控制权的方式,异常处理涉及到三个关键字:try、catch、throw。 throw: 当问题出现时,程序会抛出一个异常。这是通过…...