千家信息网

bazel的基础概念与原理是什么

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,bazel的基础概念与原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。0x01 背景bazel目前已广泛用于云计
千家信息网最后更新 2024年11月23日bazel的基础概念与原理是什么

bazel的基础概念与原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

0x01 背景

bazel目前已广泛用于云计算领域的开源软件的构建如k8s、kubevirt等,本文以一个新手的角度分享下bazel的基础知识,其存在的价值。对比下,它与其他已经存在的构建系统的差别,以及它适用于什么场景。

0x02 构建系统

构建对应的英文是BUILD,也就是大家所说的编译打包,就是将编写出的代码经过编译器处理,产生二进制,形成一个可以正常运行的软件包(如deb或者rpm)。对于编译型语言来说,构建几乎是日常工作的一部分。

  1. 是一个辅助过程,它本身不产生价值。

  2. 又是必须的一个过程,没有它CI是空谈。

基于这两个特点来说,我们希望理想的构建系统具备以下特点:

  1. 尽可能地快。可以方便开发人员,编写代码后快速出包验证改动。

  2. 方便维护,可以清晰地展示依赖关系,在系统中添加一个模块,或者减少一个模块,可以非常容易维护。

对比理想系统,我们看下构建技术的发民。软件构建技术的发展和IT技术的发展保持同步,历经了初期、中期和现代化三个阶段(纯粹个人理解)。

一、初期
软件规模小,软件工程的概念还未被提出。
这时对构建的要求很低,或者说不需要。编写出的代码可以经过汇编编译后直接执行,也没有流水线。这时期的代码就是makefile,或者是直接自己写脚本进行编译执行。软件的特点是,单语言小规模,对构建基本上没有要求。

二、中期
软件规模开始增大。已有的makefile机制已经难以满足需要。以Linux内核为例,makefile已经无法满足,所以内核开发者在内核中添加了自己的构建扩展,以满足日渐增大的内核代码。同时,也涌现出了cmake这样较现代化的构建工具。主要原因是,代码规模增大后,构建这一不增值过程开始消耗掉大量开发人员的精力,以cmake为代表的工具可以半自动化管理依赖,生成makefile,提高编译人员的生产力,减少了重复劳动; 此时的构建系统基本上可以满足要求,但已经开始显现不足了。

三、现代化
软件规模增大的同时,大型系统开始转向多语言协作。使用运行高效率的编译型语言(C、C++、Java等)编写低层(数据面),使用开发高效率的动态非编译型语言编写上层(管理面)。多语言对于cmake来说,无能为力。此时以bazel为代表的现代构建系统出现,可以很好地解决cmake无法解决的问题。

在一个机构逐步增大的过程中,大公司在IT上经历的问题,你同样会遇到,所以了解一门技术的驱动力一定是问题,而不是Google出品的一定就是适合你的。这里也一样,我去了解Bazel是因为遇到了现有技术无法解决的问题。

[bazel](https://www.bazel.build/](https://www.bazel.build/) Google开源的构建工具。它通过将构建过程进行抽象建模,实现了一个接近理解的构建系统。

  1. 快速构建。
    bazel支持增量式编译,支持缓存,支持分布式扩展。这3点就可以满足快速建构。只要有投入足够多的硬件资源,你的构建就可以很快。

  2. 清晰的依赖关系。
    虽然makefile也可以定义出来。但makefile定义的规则,全部需要人工维护,特别是分散在多个代码仓库中的依赖,很难有人能全局把握好依赖关系。但bazel可以清晰地以依赖关系图的方式展现出当前的依赖关系。而且是自动建立地,可查询。

除了以上两个优点,最重要的一点是bazel支持多语言构建。以下将通过介绍bazel的基本对象(概念),来阐述bazel是如何对构建过程进行建模的。

0x03 概念

3.1 构建
构建过程是一个动作。有输入输出,如下图所示。

一个大型系统中有许多构建过程,有顶层的负责产生最终产出物。有底层负责某个小模块的构建。不同的构建之间,有相互依赖。A的产生物是B的输入,那么B就依赖A,构建上则要求A先于B构建。这些依赖最终在大模块里出的就是一个依赖网。如下图,A依赖B C D,但B也依赖C。

3.2 Bazel中主要的概念如下。

名称解释
WORKSPACE每一个工程都需要定义的一个文件,位于工程的根目录下。可以是空文件,也可以加载一些外部依赖。
actionrule中定义的构建动作。全部在运行阶段执行。
BUILD存在每个小代码仓库中,定义当前仓库中的构建要素。输入、输出和构建行为。是最小的构建单位。
bzl自定义的规则后缀。
external rulebazel约定的其他规则库,用skylark语言(Python的子集)编写。
rulebazel的构建规则,位于BUILD文件中。每个规则中包含输入和输出,以及构建动作。目前已有C/C++、Java、Golang、Python等成熟的构建规则库,可以方便地从github上获取。见官方文档已有规则库
package在BUILD文件中定义的一系统目标。包具有可见性属性,可用来控制对外暴露的属性。
build graph构建依赖图,就是前文提到的依赖关系图。由定义在各个BUILD文件中的目标构成。

0x04 原理

有了基础概念之后,解释下bazel的工作原理。bazel以client/server模式工作,server在闲置一段时间后会自动退出。以WORKSPACE[#WORKSPACE]和BUILD文件将整个构建过程模型化。 bazel工作分以下三个阶段(phase)。也就是执行了bazel build ...之后发生的事情。

  1. loading phase 加载阶段
    bazel遍历当前工程下,所有子文件夹,找到其中的BUILD文件,加载外部依赖,生成一个个package和target。

  2. analysis phase 分析阶段
    根据各个BUILD中定义的目标和输入输出信息,建立一个内存中的build graph。

  3. executing phase 执行阶段
    根据build graph逐个运行各个规则定义的动作,产生最终的目标。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

0