写在前面
一些网站
-
bazel 官网:https://bazel.google.cn/
-
buildbuddy 官网:https://bazel.google.cn/
Bazel 和 Bazelisk 的区别
-
bazel 是 Google 开源的构建工具,用于构建和测试各种软件项目。
-
bazelisk 是一个工具,用于管理和安装 Bazel 版本。主要优势在于它能够简化 Bazel 版本的切换和管理。
Bazel 的版本更新频繁,不同版本之间可能存在不兼容性。
Bazelisk 可以自动下载和切换到适合你的项目的 Bazel 版本,从而避免了版本兼容性问题。
安装 Bazelisk
安装
bazelisk 虽然是 google 推荐的 bazel 使用工具,但是它不能离线使用;
通过 Releases 发布页面下载相应平台的安装包进行安装。
以 Linux x86-64 平台为例:
1
2
3
4
5
6
7
8
# 下载 bazelisk
wget https://github.com/bazelbuild/bazelisk/releases/download/v1.18.0/bazelisk-linux-amd64
# 增加执行权限
chmod +x bazelisk-linux-amd64
# 移动到系统目录并重命名为 bazel
sudo mv bazelisk-linux-amd64 /usr/local/bin/bazel
第一次执行 bazel(实际是 bazelisk) 命令时:
1
bazel version
会经历如下步骤:
-
执行 bazelisk 的 version 指令,比如得到:
1
Bazelisk version: v1.18.0
-
检查当前目录和上层(上上层…)目录是否存在
WORKSPACE
文件确定该级目录为工作区根目录;-
[建议] 如果工作区根目录存在
.bazelversion
文件,从中读出指定的 bazel 版本;1
6.3.2
-
如果工作区根目录存在
.bazeliskrc
文件,从中读出指定的 bazel 版本;1
USE_BAZEL_VERSION=6.3.2
-
如果从文件无法得到 bazel 版本,那就会去检查
USE_BAZEL_VERSION
环境变量; -
如果从文件和环境变量都无法得到 bazel 版本,那就会从云端读到最新的 bazel 版本(需要联网);
-
-
检查本地是否有对应的 bazel 版本:
- 如果存在就使用这个版本;
- 如果不存在就从云端下载这个版本(需要联网);
-
使用对应版本的 bazel(真实的)时,bazel(实际是 bazelisk)会把传参原样转发;
bash 补全
生成 bazel-complete.bash
文件:
1
2
3
4
5
6
7
8
9
# 下载 bazel-complete-header.bash
wget https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-complete-header.bash
# 下载 bazel-complete-template.bash
wget https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-complete-template.bash
# 生成 bazel-help-completion
bazel help completion > bazel-help-completion
# 合并 3 个文件
cat bazel-complete-header.bash bazel-complete-template.bash bazel-help-completion > bazel-complete.bash
将 bazel-complete.bash
放到 /etc/bash_completion.d
目录中:
1
sudo cp bazel-complete.bash /etc/bash_completion.d/
安装 Bazel
安装
如果你有离线使用需求,应该直接安装 bazel 二进制预编译文件;
下载地址:点这
1
2
3
4
5
6
7
wget https://github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-installer-linux-x86_64.sh
# 给执行权限
chmod +x bazel-6.4.0-installer-linux-x86_64.sh
# 进行安装
sudo ./bazel-6.4.0-installer-linux-x86_64.sh
bash 补全
添加下面的指令到 ~/.bashrc
中:
1
source /usr/local/lib/bazel/bin/bazel-complete.bash
bazel 进行构建 c++
本地构建
克隆代码仓:
本教程的示例项目位于
examples/cpp-tutorial
目录中。
1
git clone https://github.com/bazelbuild/examples
第一阶段:BUILD 中一个 target
代码结构如下:
1
2
3
4
5
6
7
8
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
├── .bazelversion // 创建一个,写你的 bazel 版本号,比如 6.3.2
└── WORKSPACE
BUILD 文件中只有一个 target:
1
2
3
4
5
6
load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
编译方法:
在
BUILD
文件和命令行中,bazel 使用标签来引用目标,例如//main:hello-world
。其语法为:
//path/to/package:target-name
1
bazel build //main:hello-world
第二阶段:BUILD 中多个 target
代码结构如下:
1
2
3
4
5
6
7
8
9
10
examples
└── cpp-tutorial
└──stage2
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── .bazelversion // 创建一个,写你的 bazel 版本号,比如 6.3.2
└── WORKSPACE
BUILD 文件中有多个 target:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
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",
],
)
编译方法:
在
BUILD
文件和命令行中,bazel 使用标签来引用目标,例如//main:hello-world
。其语法为:
//path/to/package:target-name
1
bazel build //main:hello-world
第三阶段:多个 BUILD
代码结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
examples
└── cpp-tutorial
└──stage2
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
├── .bazelversion // 创建一个,写你的 bazel 版本号,比如 6.3.2
└── WORKSPACE
lib 目录中的 BUILD 文件:
1
2
3
4
5
6
7
8
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
main 目录中的 BUILD 文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
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",
],
)
编译方法:
在
BUILD
文件和命令行中,bazel 使用标签来引用目标,例如//main:hello-world
。其语法为:
//path/to/package:target-name
1
bazel build //main:hello-world
buildbuddy 远程构建
-
打开 https://www.buildbuddy.io/ 并登录;
-
按个人中心的 QuickStart 进行设置
.bazelversion
:- api key 验证;
- 完全缓存;
- 使能远程执行;
1 2 3 4 5 6
build --bes_results_url=https://app.buildbuddy.io/invocation/ build --bes_backend=grpcs://remote.buildbuddy.io build --remote_cache=grpcs://remote.buildbuddy.io build --remote_timeout=3600 build --remote_executor=grpcs://remote.buildbuddy.io build --remote_header=x-buildbuddy-api-key=V1A5A5q9URMhvBQO7MyO
-
在我们的工作区根目录创建
.bazelversion
,并写入上一步得到的信息,然后执行:1
bazel build //main:hello-world --jobs=80
其他
bazel 推荐规则:rules
最佳实践:best-practices
c++ 用例:cpp-use-cases
配置 c++ 工具链:ccp-toolchain-config
查看依赖关系图:cpp-dependency