bazel工程介绍和demo构建

news2024/11/29 4:29:41

参考官方示例项目:git clone https://github.com/bazelbuild/examples

项目结构

使用Bazel管理的项目一般包含以下几种Bazel相关的文件:WORKSPACE(同WORKSPACE.bazel),BUILD(同BUILD.bazel),.bzl 和 .bazelrc 等。

具体结构如下:

examples
└── cpp-tutorial
    ├──stage1
    │  ├── main
    │  │   ├── BUILD
    │  │   └── hello-world.cc
    │  └── WORKSPACE
    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── WORKSPACE
    └──stage3
       ├── main
       │   ├── BUILD
       │   ├── hello-world.cc
       │   ├── hello-greet.cc
       │   └── hello-greet.h
       ├── lib
       │   ├── BUILD
       │   ├── hello-time.cc
       │   └── hello-time.h
       └── WORKSPACE

例子分三个 stage,由简单到复杂介绍了一些 Bazel 构建的基本概念,我这里就直接根据第三个 stage3 例子来总结一下: 

WORKSPACE文件--项目(工作区)

一个 workspace 可以认为就是一个 project。譬如上面 cpp-tutorial 目录下分别由 stage1、stage2 和 stage3 三个项目,每个项目的根目录下有一个 WORKSPACE 文件,空的就行,Bazel 就会将包含一个 WORKSPACE 文件的目录识别为一个项目。每个项目之间互不干扰是完全独立的。一个 workspace 里可以包含多个 packages。

WORKSPACE文件也可能定义加载 Bazel 工具和 rules 集,以及包含对构建输出所需的外部依赖项的引用。

BUILD文件--软件包

软件包可以认为是一个软件模块,譬如一个库等,指包含名为BUILD或BUILD.bazel的ef="https://bazel.build/concepts/build-files?hl=zh-cn">BUILD文件的目录。代码库中的主要代码组织单元是软件包。软件包是相关文件的集合,以及如何使用这些文件生成输出工件的规范。软件包中包含其目录中的所有文件及其下的所有子目录,但包含BUILD文件的文件除外。根据该定义,任何文件或目录都不得是两个不同软件包的一部分。

BUILD 文件采用 Starlark 语言对模块构建进行描述,包含 Bazel 的几种不同类型的指令。每个 BUILD 文件都需要至少一条规则作为一组指令,告诉 Bazel 如何构建所需的输出,例如可执行文件或库。BUILD 文件中的 build 规则的每个实例都称为一个目标target,并指向一组特定的源文件和依赖项。 目标还可以指向其他目标。从逻辑上来说即每个 package 可以包含多个 Targets,而具体的 target 则采用 Starlark 语法定义在一个 BUILD 文件中。

查看 stage3/lib/BUILD 文件:

cc_library(
    name = "hello-time",
    srcs = ["hello-time.cc"],
    hdrs = ["hello-time.h"],
    visibility = ["//main:__pkg__"],
)

在 stage3/main/BUILD 文件:

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
        "//lib:hello-time",
    ],
)

在此示例中,hello-world 目标会实例化 Bazel 的内置 cc_binary rule。该规则指示 Bazel 从hello-world.cc 源文件和两个依赖项hello-greet和//lib:hello-time构建独立的可执行文件。

为使构建成功,您可以使用可见性属性让 lib/BUILD 中的 //lib:hello-time 目标明确显示给 main/BUILD 中的目标。这是因为默认情况下,目标仅对同一 BUILD 文件中的其他目标可见。Bazel 使用目标可见性来防止出现包含有实现细节的库泄露到公共 API 等问题。

target定义--目标

软件包是目标软件包的容器,在软件包的BUILD文件中定义。大多数目标是两种主要类型之一:文件和规则。如示例中的hello-world和hello-greet等。

文件进一步分为两种。源文件通常由用户编写并签入代码库。生成的文件(有时称为派生文件或输出文件)不会被签入,但是从源文件生成的。

第二种目标使用规则声明。每个规则实例都用于指定一组输入文件与一组输出文件之间的关系。规则的输入可以是源文件,但也可以是其他规则的输出。

target是某个 rule 的一个实例。那么 Rule 又是什么?示例中cc_library 就是一个 rule,它规定了 一类构建规则。从 cc_library 这个规则名称上我们很容易猜测出来这 一类规则 描述了如何构建一个采用 C/C++ 编程语言编写的库(library,可以是静态库也可能是动态库)。一个 Rule 由很多 attribute 构成,这点采用面向对象的概念来看,Rule 就好比是 class,而 attribute 就好比是 class 的 member。定义 target 就是实例化了这个 rule,这样大家就理解了上面这段代码实际上就是定义了一个 target,每个实例必须要有一个名字在同一个 package 中和其他 target 实例进行区分。所以 name 这个 attribute 是必须有的,其他 attribute 是可选的,不写则按默认值定义。

标签 --label

所谓 label 可以认为是在一个 Bazel 的 workspace 范围中唯一标识一个 target 的 ID。我们可以用这个 label 来引用一个 target。label 的语法如下:

//path/to/package:target-name

以 // 开始,接下来的 path/to/package 也就是这个 target 所在 package 在 workspace 中的相对路径。然后是一个 : 后面跟着一个 target-name 即上面说的一个 target 中的 name 那个属性的字符串值。

譬如我们要构建 examples/cpp-tutorial/stage3 这个 workspace 下的 main 这个 package 中的 "hello-greet" 这个 target。那么我们要做的就是先 cd 到 stage3 这个 workspace 下然后用 label 引用这个 target 执行构建。具体命令如下:

$ cd examples/cpp-tutorial/stage3
$ bazel build //main:hello-greet

就会生成 libhello-greet.a 和 libhello-greet.so

依赖--dependency

各个 target 之间存在依赖关系,这是在所有构建系统中都存在的概念,同样在 Bazel 中也缺少不了。譬如在 stage3 这个例子中,target //main:hello-world 就依赖于 target //main:hello-greet,背后的含义就是我们要构建最终的可执行程序 hello-world,则首先要构建成功 hello-greet 这个规则的 obj 文件,这种依赖关系在 BUILD 文件中体现为 deps 这个 attribute 的描述。

注意以下两点:

  • ":hello-greet" 这里也是一个 label 描述,由于 hello-greet 和 hello-world 这两个 target 在一个 package 中,所以前面的 path/to/package 可以省略。
  • 这里如果直接执行 bazel build //main:hello-world 并不会生成 libhello-greet.a 和 libhello-greet.so,原因是目前例子中上面的描述并没有给出构建 hello-world 需要依赖 so 或者 .a。所以默认只是依赖于 hello-greet 的 obj 文件。

.bzl文件

如果你的项目有一些复杂构造逻辑、或者一些需要复用的构造逻辑,那么可以将这些逻辑以函数形式保存在.bzl文件,供WORKSPACE或者BUILD文件调用。其语法跟Python类似。

.bazelrc文件

对于Bazel来说,如果某些构建动作都需要某个参数,就可以将其写在此配置中,从而省去每次敲命令都重复输入该参数。Bazel 会按以下顺序读取可选的 bazelrc 文件:

  1. 系统级文件,位于 etc/bazel.bazelrc。

  2. 位于 $workspace/tools/bazel.rc 的 Workspace rc 文件。

  3. 主目录文件位于 $HOME/.bazelrc 中

此处列出的每个 bazelrc 文件都有一个对应的标志,可用于停用这些标志(例如 --nosystem_rc、--noworkspace_rc 和 --nohome_rc)。您还可以通过传递 --ignore_all_rc_files 启动选项让 Bazel 忽略所有 Bazelrcs。

如何工作

当运行构建或者测试时,Bazel会:

  1. 加载和目标相关的BUILD文件

  2. 分析输入及其依赖,应用指定的构建规则,产生一个Action图。这个图表示需要构建的目标、目标之间的关系,以及为了构建目标需要执行的动作。Bazel依据此图来跟踪文件变动,并确定哪些目标需要重新构建

  3. 针对输入执行构建动作,直到最终的构建输出产生出来

构建

运行以下命令以切换到 stage3 目录:

cd stage3

运行以下命令:

bazel build //main:hello-world

在目标标签中,//main:部分是BUILD文件相对于工作区根目录的位置,hello-world是BUILD文件中的目标名称。

Bazel 会生成如下所示:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s

运行以下命令可删除输出文件,并可选择停止服务器。:

bazel clean

运行

执行二进制文件以获得最终的 Hello world 消息:

bazel-bin/main/hello-world

依赖图

  • 生成依赖图:

# 查找target为 //main:hello-world 的所有依赖
# --nohost_deps 		表示不包括host依赖
# --noimplicit_deps 	表示不包括隐式依赖 e.g: @bazel_tools//tools/cpp:stl
bazel query --nohost_deps --noimplicit_deps 'deps(//main:hello-world)' --output graph
  • 将生成的输出图文字描述, 粘贴到 GraphViz, 生成的依赖图如下

本文属于如下文章中的子章节

bazel学习系列章节汇总_m0_74043383的博客-CSDN博客

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

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

相关文章

【洛谷】P3853 路标设置

原题链接:https://www.luogu.com.cn/problem/P3853 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 整体思路:二分答案 由题意知,公路上相邻路标的最大距离定义为该公路的“空旷指数”。在公路上增设一些路标&…

6. series对象及DataFrame对象知识总结

【目录】 文章目录 6. series对象及DataFrame对象知识总结1. 导入pandas库2. pd.Series创建Series对象2.1 data 列表2.2 data 字典 3. s1.index获取索引4. s1.value获取值5. pd.DataFrame()-创建DataFrame 对象5.1 data 列表5.2 data 嵌套列表5.3 data 字典 6. df[列索引]…

Linux安装MySQL5.7.26教程图解

0、准备工作 下载MySQL软件包 ①、官网下载:https://www.cnblogs.com/linu-x/p/15701479.html#_label6 ②、百度网盘下载:百度网盘 请输入提取码 提取码:chao ③、文件说明 主机名 CentOS版本 MySQL版本 IP地址 test CentOS Linux …

AtCoder Beginner Contest 318

目录 A - Full Moon B - Overlapping sheets C - Blue Spring D - General Weighted Max Matching E - Sandwiches F - Octopus A - Full Moon #include<bits/stdc.h> using namespace std; const int N1e65; typedef long long ll ; const int maxv4e65; typedef …

nsq中diskqueue详解 - 第二篇

上一篇博客 nsq中diskqueue详解 - 第一篇_YZF_Kevin的博客-CSDN博客 中我们讲了diskqueue是什么&#xff0c;为什么需要它&#xff0c;它的整体架构流程&#xff0c;以及对外接口等等&#xff0c;如果你还没了解过&#xff0c;强烈建议先看一下&#xff0c;不然直接看这篇博客的…

AVR128单片机 USART通信控制发光二极管显示

一、系统方案 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 void port_init(void) { PORTA 0xFF; DDRA 0x00;//输入 PORTB 0xFF;//低电平 DDRB 0x00;//输入 PORTC 0xFF;//低电平 DDRC 0xFF;//输出 PORTE 0xFF; DDRE 0xfE;//输出 PO…

Leetcode Top 100 Liked Questions(序号236~347)

236. Lowest Common Ancestor of a Binary Tree 题意&#xff1a;二叉树&#xff0c;求最近公共祖先&#xff0c;All Node.val are unique. 我的思路 首先把每个节点的深度得到&#xff0c;之后不停向上&#xff0c;直到val相同&#xff0c;存深度就用map存吧 但是它没有向…

Lesson4-2:OpenCV图像特征提取与描述---Harris和Shi-Tomas算法

学习目标 理解Harris和Shi-Tomasi算法的原理能够利用Harris和Shi-Tomasi进行角点检测 1 Harris角点检测 1.1 原理 H a r r i s Harris Harris角点检测的思想是通过图像的局部的小窗口观察图像&#xff0c;角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化&#xff…

【多线程】线程间通信及状态

文章目录 1. 线程间的通信1.1 wait和notify1.2 notify随机唤醒1.3 notifyAll()1.4 join() 2. 线程间的状态3. 验证线程的状态3.1 验证NEW、RUNNABLE、TERMINATED3.2 验证WAITING3.3 验证TIMED-WAITING3.4 验证BLOCKED 4. 面试题&#xff1a;wait和sleep对比 1. 线程间的通信 1…

人工智能轨道交通行业周刊-第58期(2023.8.28-9.3)

本期关键词&#xff1a;成都智慧工厂、机务段、站台地标、备案大模型、AIGC报告 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道世界铁路…

Redis 缓存穿透击穿和雪崩

一、说明 Redis 缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要害的问题&#xff0c;就是数据的一致性问题&#xff0c;从严格意义上讲&#xff0c;这个问题无解。如果对…

C# Color颜色RGB对照表

序号Color色系颜色RGB图例1Color.AliceBlue蓝色艾丽丝蓝240,248,2552Color.AntiqueWhite白色古典白色250,235,2153Color.Aqua&#xff0c;Color.Cyan青色浅蓝色&#xff0c;蓝绿色&#xff0c;青色0,255,255 C# Color颜色RGB对照表_旭东怪的博客-CSDN博客 C#颜色和名称样式对照…

Nginx全家桶配置详解

源码包安装NGINX A&#xff0c;搭建Web Server&#xff0c;任意HTML页面&#xff0c;其8080端口提供Web访问服务&#xff0c;截图成功访问http(s)&#xff1a;//[Server1]:8080并且回显Web页面。保留Server1&#xff0c;但是不允许直接访问Server 1&#xff0c;再部署1套NGINX …

8.(Python数模)马尔科夫链预测

Python实现马尔科夫链预测 马尔科夫链原理 马尔科夫链是一种进行预测的方法&#xff0c;常用于系统未来时刻情况只和现在有关&#xff0c;而与过去无关。 用下面这个例子来讲述马尔科夫链。 如何预测下一时刻计算机发生故障的概率&#xff1f; 当前状态只存在0&#xff08;故…

1分钟实现 CLIP + Annoy + Gradio 文搜图+图搜图 系统

多模态图文搜索系统 CLIP 进行 Text 和 Image 的语义EmbeddingAnnoy 向量数据库实现树状结构索引来加速最近邻搜索Gradio 轻量级的机器学习 Web 前端搭建 文搜图 图搜图 CLIP图像语义提取功能&#xff01;

生信分析Python实战练习 3 | 视频21

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

已解决下载安装Python官网安装包下载速度慢问题

本文摘要&#xff1a;本文已解决下载安装Python官网安装包下载速度慢的问题。 &#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究…

47、springboot 的 国际化消息支持--就是根据浏览器选择的语言,项目上的一些提示信息根据语言的选择进行对应的显示

springboot的国际化也是基于spring mvc 的。 springboot 的 国际化消息支持–就是根据浏览器选择的语言&#xff0c;项目上的一些提示信息根据语言的选择进行对应的显示。 总结下国家化自动配置&#xff1a; 功能实现就是&#xff1a; 比如一个登录页面&#xff0c;我们在浏览…

ORB-SLAM3复现的详细过程——配置安装及ROS和脚本运行---Ubuntu20.04

ORB-SLAM3配置安装及ROS和脚本运行---Ubuntu20.04 1. 安装所需要的依赖和包2. 修改代码及文件内容2.1 CMakeLists.txt文件的修改2.2 单目可视化代码修改2.3 环境配置文件的修改2.4 源码的修改 3.ORB-SLAM3的编译3.1 构建 ORB-SLAM3 库3.2 生成ROS节点 4.ORB-SLAM3的运行4.1 非R…

ModaHub魔搭社区专访百度智能云李莅:您认为向量数据库是一个刚需产品吗?

ModaHub魔搭社区&#xff1a;可以看到&#xff0c;大模型火了以后&#xff0c;向量数据库受到了特别高的关注&#xff0c;您是如何看待这种现象呢&#xff1f;您认为向量数据库是一个刚需产品吗&#xff1f; 李莅&#xff1a;是的。大模型是在今年才崭露头角&#xff0c;或者说…