Bazel中的Symbol, Rule, Macro, Target, Provider, Aspect 等概念

学习Bazel ,就要学习Bazel 的规则定义, 弄清各个概念是重要的一个步骤。 在 Bazel 规则定义中,SymbolRuleMacro 是常见的概念。除此之外,Bazel 还有 TargetProviderAspect Repository、Package、 Workspace、 Configuration、Build Event Protocol、 Starlark、Transition、Action 等重要概念。

概念类别作用
Symbol(符号)基础概念Bazel 规则、目标、属性等命名的标识符。
Rule(规则)规则定义 Bazel 构建逻辑,如 cc_librarypy_binary
Macro(宏)代码复用通过 Starlark 编写的函数,封装多个规则以简化 BUILD 文件。
Target(目标)构建单元BUILD 文件中的规则实例,如 cc_library(name = "lib")
Provider(提供者)数据传递规则间传递构建信息的方式,如 DefaultInfo(files = depset([...]))
Aspect(切面)依赖扩展扩展规则行为,访问依赖的构建信息,如 bazel_aspect()
Repository(仓库)外部依赖管理定义和下载外部依赖,如 http_archive()git_repository()
Package(包)代码组织BUILD 文件为单位的代码组织单元,每个 BUILD 目录即一个 package。
Workspace(工作区)项目根目录WORKSPACE 文件定义的 Bazel 项目,管理外部依赖。
Configuration(构建配置)编译参数影响构建方式,如 --cpu=x86_64--compilation_mode=opt
Build Event Protocol(BEP)日志分析记录 Bazel 构建事件,生成 JSON 或 Proto 格式日志。
Starlark(Bazel 语言)语言Bazel 使用的 Python 语法子集,编写规则、宏和构建逻辑。
Transition(配置转换)配置管理允许在不同规则间修改构建配置,如改变 --cpu
Action(构建动作)执行单元最小的构建执行单位,如 ctx.actions.run_shell() 运行 shell 命令。

下面将对它们做详细的解释:

1. Symbol(符号)

在 Bazel 中,symbol(符号) 指的是 .bzl 文件中定义的变量、函数、规则、宏等。

当你使用 load() 语句时,你在导入的就是 symbols

示例:

load("@rules_python//python:packaging.bzl", "py_package", "py_wheel")

  • 这里 py_packagepy_wheel 就是 packaging.bzl 文件中定义的 symbols

  • symbols 可以是宏(macro)规则(rule),或者普通的 函数/变量


2. Rule(规则)

Bazel rule(规则) 是 Bazel 构建系统的核心,用于定义如何构建目标(target)

特性:

  • 规则(rules)是 Starlark 代码,它们通常由 native.rule() 定义。

  • 每个规则都能创建一个或多个 targets(构建目标),并由 Bazel 执行。

  • 规则可以使用 providers 来定义输入/输出关系。

规则示例

Bazel 内置了一些规则,比如 cc_binarypy_binary

cc_binary( 
name = "hello",
srcs = ["hello.cc"],
deps = [":hello_lib"],
) 

  • cc_binary 是一个规则(rule),用于编译 C++ 可执行文件。

  • name 是目标名称,srcs 是源代码文件,deps 是依赖项。

自定义规则(User-defined Rule)

def _my_rule_impl(ctx):# 规则的核心逻辑 passmy_rule = rule( implementation = _my_rule_impl, attrs = { "srcs": attr.label_list(allow_files=True),}, 
)

  • my_rule 是 Bazel 自定义规则,用于处理 srcs 作为输入。

  • implementation 是规则的实现函数 _my_rule_impl

官方文档:
Build Rules Guide


3. Macro(宏)

宏(macro)封装多个 Bazel 规则的函数,用于提高可复用性。

  • Macros 只是 Starlark 层面的封装,不会创建新的 build actions

  • 它们只是规则的组合,而不修改规则本身

宏示例

def my_py_library(name, srcs, deps = []):native.py_library(name = name,srcs = srcs,deps = deps + ["//common:utils"],)

 

使用时:

load("//build_defs:my_macros.bzl", "my_py_library")my_py_library(name = "my_lib",srcs = ["lib.py"],
)

 

  • my_py_library封装了 py_library 规则,并默认加上 //common:utils 作为 deps 依赖项。

  • 与规则(rule)不同,宏不会创建新类型的 build target,只是对已有规则的包装


4. Target(目标)

Target(构建目标) 是 Bazel 构建系统的最小单位,它由 BUILD 文件中的规则实例化生成。

cc_library(name = "hello_lib",srcs = ["hello_lib.cc"],
)

 

  • 这里 hello_lib 是一个 target,它是 cc_library 规则的一个实例。

Target vs Rule

  • Rule 是构建的“蓝图”(定义构建逻辑)。

  • Target 是具体的构建对象(每个 name 定义一个 target)。


5. Provider(提供者)

Provider(提供者) 是规则之间的数据传递机制
它允许规则将信息传递给依赖项。

示例

MyProvider = provider(fields = ["output"])def _my_rule_impl(ctx):output_file = ctx.actions.declare_file(ctx.label.name + ".out")ctx.actions.run_shell(outputs = [output_file],command = "echo 'Hello' > " + output_file.path,)return [MyProvider(output = output_file)]my_rule = rule(implementation = _my_rule_impl,
)

 

  • MyProvider 是一个自定义提供者,它包含 output 字段。

  • _my_rule_impl 生成一个 output_file 并通过 MyProvider 返回它。

  • 在规则之间,提供者用于共享构建信息

官方文档:
Bazel Providers


6. Aspect(切面)

Aspect(切面) 允许在不修改规则的情况下为规则添加额外的行为
它们通常用于分析或生成额外的输出。

Aspect 示例

def _my_aspect_impl(target, ctx):for src in target[DefaultInfo].files.to_list():print("Analyzing file:", src)my_aspect = aspect(implementation = _my_aspect_impl,
)

 

应用 aspect

cc_binary(name = "hello",srcs = ["hello.cc"],
)my_aspect(target = "//:hello",
)

 

  • my_aspect 允许分析 cc_binary 目标的输入文件,而不修改 cc_binary 规则。

官方文档:
Bazel Aspects

7. Repository(外部仓库)

Repository(仓库) 是 Bazel 外部依赖管理的机制,用于拉取和管理外部代码库(如第三方库、工具链等)。

Bazel 支持多种类型的仓库,包括:

  • http_archive(下载 tar/zip 并解压)

  • git_repository(从 Git 拉取)

  • local_repository(使用本地路径)

  • new_local_repository(定义新的本地仓库)

示例

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")http_archive(name = "rules_vcc",url = "https://example.com/rules_vcc.tar.gz",sha256 = "abc123...",strip_prefix = "rules_vcc-main",
)

 

  • @rules_vcc 就是一个 外部仓库,可用于 load("@rules_vcc//...")

官方文档:
Bazel External Repositories


8. Package(包)

Package(包)Bazel 代码的组织单元,即一个 BUILD 文件及其所在目录。

  • 一个 Bazel 工作区(workspace)可以有多个 package

  • 每个 package 都有一个 BUILD 文件,用于定义规则和目标。

示例

/workspace_root/WORKSPACE/src/BUILD         # 这是一个 packagemain.cc/lib/BUILD       # 这是另一个 packagelib.cc

 

  • src/src/lib/ 都是 package,因为它们各自有 BUILD 文件。

官方文档:
Bazel Packages


9. Workspace(工作区)

Workspace(工作区)Bazel 项目的根目录,由 WORKSPACE 文件定义。

  • 所有 Bazel 构建都发生在某个工作区中

  • WORKSPACE 文件 用于声明外部依赖,如 http_archive()git_repository() 等。

示例

/my_project/WORKSPACE        # 定义 Bazel 工作区/src/BUILDmain.cc/third_party/BUILD

 

  • my_project/Bazel 工作区,因为它有 WORKSPACE 文件。

官方文档:
Bazel Workspaces


10. Configuration(构建配置)

Configuration(构建配置) 指的是 Bazel 对构建参数的管理,如:

  • CPU/架构 (--cpu=x86_64)

  • 编译模式 (--compilation_mode=opt/debug)

  • 工具链选择 (--host_crosstool_top=@bazel_tools//tools/cpp:toolchain)

示例

bazel build //src:main --cpu=arm64 --compilation_mode=opt

 

  • --cpu=arm64 选择 ARM64 架构

  • --compilation_mode=opt 进行优化编译

官方文档:
Bazel Configurations


11. Build Event Protocol(构建事件协议, BEP)

BEP 用于 跟踪和分析 Bazel 构建过程,常用于 CI/CD 系统集成。

BEP 可以输出 构建日志、失败原因、性能数据等,并提供 JSON 或 Proto 格式。

示例

bazel build //src:main --build_event_json_file=build_events.json

 

  • 生成 build_events.json,可用于分析构建信息。

官方文档:
Bazel Build Event Protocol


12. Starlark(Bazel 语言)

Starlark 是 Bazel 的 配置语言,基于 Python 语法但有严格限制

  • 无副作用(不能修改全局变量)

  • 无 I/O 操作(不能读写文件)

  • 只能调用 ctx.actions 进行构建

示例

def _my_rule_impl(ctx):output = ctx.actions.declare_file(ctx.label.name + ".txt")ctx.actions.write(output, "Hello, Bazel!")return [DefaultInfo(files = depset([output]))]my_rule = rule(implementation = _my_rule_impl)

官方文档:
Bazel Starlark


13. Transition(配置转换)

Transition(配置转换) 允许修改构建配置,比如 改变目标平台或优化级别

示例

def _my_transition_impl(settings, attr):return {"//command_line_option:cpu": "arm64"}my_transition = transition(implementation = _my_transition_impl,inputs = [],outputs = ["//command_line_option:cpu"],
)

 

  • 默认情况下,Bazel 规则会继承全局构建配置

  • 使用 transition 可以修改某些规则的配置,如强制某些目标在 ARM64 上构建。

官方文档:
Bazel Transitions


14. Action(构建动作)

Action(构建动作) 是 Bazel 执行构建的最小单位,如:

  • 编译(gcc、clang)

  • 链接(ld)

  • 拷贝文件

  • 执行 Shell 脚本

每个 rule多个 action 组成

示例

def _my_rule_impl(ctx):output = ctx.actions.declare_file("output.txt")ctx.actions.run_shell(outputs = [output],command = "echo Hello > " + output.path,)return [DefaultInfo(files = depset([output]))]

 

  • ctx.actions.run_shell() 定义了一个 Action,用于执行 shell 命令。

官方文档:
Bazel Actions

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/75547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入探究 Hive 中的 MAP 类型:特点、创建与应用

摘要 在大数据处理领域,Hive 作为一个基于 Hadoop 的数据仓库基础设施,提供了方便的数据存储和分析功能。Hive 中的 MAP 类型是一种强大的数据类型,它允许用户以键值对的形式存储和操作数据。本文将深入探讨 Hive 中 MAP 类型的特点,详细介绍如何创建含有 MAP 类型字段的表…

基于Java的区域化智慧养老系统(源码+lw+部署文档+讲解),源码可白嫖!

摘 要 时代在飞速进步,每个行业都在努力发展现在先进技术,通过这些先进的技术来提高自己的水平和优势,区域化智慧养老系统当然不能排除在外。区域化智慧养老系统是在实际应用和软件工程的开发原理之上,运用Java语言、JSP技术以及…

关于JVM和OS中的指令重排以及JIT优化

关于JVM和OS中的指令重排以及JIT优化 前言: 这东西应该很重要才对,可是大多数博客都是以讹传讹,全是错误,尤其是JVM会对字节码进行重排都出来了,明明自己测一测就出来的东西,写出来误人子弟… 研究了两天&…

VS2022远程调试Linux程序

一、 1、VS2022安装参考 VS Studio2022安装教程(保姆级教程)_visual studio 2022-CSDN博客 注意:勾选的时候,要勾选下方的选项,才能调试Linux环境下运行的程序! 2、VS2022远程调试Linux程序测试 原文参…

WPF设计学习记录滴滴滴4

<Button x:Name"btn"Content"退出"Width" 100"Height"25"Click"btn_Click" IsDefault"True"/> <Button x:Name"btn" <!-- 控件标识&#xff1a;定义按钮的实例名称为"btn&…

JVM 有哪些垃圾回收器

垃圾收集算法 标记-复制算法(Copying): 将可用内存按容量划分为两个区域,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面, 然后再把已使用过的内存空间一次清理掉。 标记-清除算法(Mark-Sweep): 算法分为“标记” 和“清除”两个…

React DndKit 实现类似slack 类别、频道拖动调整位置功能

一周调试终于实现了类 slack 类别、频道拖动调整位置功能。 历经四个版本迭代。 实现了类似slack 类别、频道拖动调整功能 从vue->react &#xff1b;更喜欢React的生态及编程风格&#xff0c;新项目用React来重构了。 1.zustand全局状态 2.DndKit 拖动 功能视频&…

新浪财经股票每天10点自动爬取

老规矩还是先分好三步&#xff0c;获取数据&#xff0c;解析数据&#xff0c;存储数据 因为股票是实时的&#xff0c;所以要加个cookie值&#xff0c;最好分线程或者爬取数据时等待爬取&#xff0c;不然会封ip 废话不多数&#xff0c;直接上代码 import matplotlib import r…

使用Android 原生LocationManager获取经纬度

一、常用方案 1、使用LocationManager GPS和网络定位 缺点&#xff1a;个别设备,室内或者地下停车场获取不到gps定位,故需要和网络定位相结合使用 2、使用Google Play服务 这种方案需要Android手机中有安装谷歌服务,然后导入谷歌的第三方库&#xff1a; 例如&#xff1a;i…

验证码实现

验证码案例 学了Spring MVC &#xff0c;配置 相关章节&#xff0c; 现可以尝试写一个前后端交互的验证码 文章目录 验证码案例前言一、验证码是什么&#xff1f;二、需求1.引入依赖2.导入前端页面3.约定前后段交互接口 三、代码解析Controllermodelapplication.xml 四丶结果五…

查询当前用户的购物车和清空购物车

业务需求&#xff1a; 在小程序用户端购物车页面能查到当前用户的所有菜品或者套餐 代码实现 controller层 GetMapping("/list")public Result<List<ShoppingCart>> list(){List<ShoppingCart> list shoppingCartService.shopShoppingCart();r…

(多看) CExercise_05_1函数_1.2计算base的exponent次幂

题目&#xff1a; 键盘录入两个整数&#xff1a;底(base)和幂指数(exponent)&#xff0c;计算base的exponent次幂&#xff0c;并打印输出对应的结果。&#xff08;注意底和幂指数都可能是负数&#xff09; 提示&#xff1a;求幂运算时&#xff0c;基础的思路就是先无脑把指数转…

【nacos安装指南】

Nacos安装指南 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; GitHub主页&#xff1a;https://github.com/alibaba/nacos GitHub的Release下载…

通过发音学英语单词:从音到形的学习方法

&#x1f4cc; 通过发音学英语单词&#xff1a;从音到形的学习方法 英语是一种 表音语言&#xff08;phonetic language&#xff09;&#xff0c;但不像拼音文字&#xff08;如汉语拼音、西班牙语等&#xff09;那么规则&#xff0c;而是 部分表音部分表意。这意味着我们可以通…

列表某个字段由多个值组成,使用id匹配展示

说明&#xff1a;列表中字段A的值由多个值组成&#xff0c;但是后端返回的是这多个值的id字符串&#xff0c;需要前端拿着多个id组成的字符串去另一个接口数据源匹配展示 列表后端返回多个字符串如下&#xff1a; sectorName: "1899292545382895618,1907311191514636289…

MQL5教程 05 指标开发实战:双色线、双线变色MACD、跨时间周期均线

文章目录 一、双色线指标二、双线变色MACD指标三、跨时间周期均线 一、双色线指标 这里的类型中&#xff0c;Color开头的&#xff0c;是可以选择多个颜色的。 #property indicator_chart_window #property indicator_buffers 18 #property indicator_plots 7 //--- plot xian…

Java全栈面试宝典:线程安全机制与Spring Boot核心原理深度解析

目录 一、Java线程安全核心原理 &#x1f525; 问题1&#xff1a;线程安全的三要素与解决方案 线程安全风险模型 线程安全三要素 synchronized解决方案 &#x1f525; 问题2&#xff1a;synchronized底层实现全解析 对象内存布局 Mark Word结构&#xff08;64位系统&…

【Cursor】设置语言

Ctrl Shift P 搜索 configure display language选择“中文-简体”

【新能源汽车整车动力学模型深度解析:面向MATLAB/Simulink仿真测试工程师的硬核指南】

1. 前言 作为MATLAB/Simulink仿真测试工程师,掌握新能源汽车整车动力学模型的构建方法和实现技巧至关重要。本文将提供一份6000+字的深度技术解析,涵盖从基础理论到Simulink实现的完整流程。内容经过算法优化设计,包含12个核心方程、6大模块实现和3种验证方法,满足SEO流量…

Java 线程池与 Kotlin 协程 高阶学习

以下是Java 线程池与 Kotlin 协程 高阶学习的对比指南&#xff0c;结合具体代码示例&#xff0c;展示两者在异步任务处理中的差异和 Kotlin 的简化优势&#xff1a; 分析&#xff1a; 首先&#xff0c;我们需要回忆Java中线程池的常见用法&#xff0c;比如通过ExecutorService创…