Bazel
Bazel 是一款由 Google 开发的构建工具。原文链接:使用 Bazel 构建你的服务。
安装 Bazel
$ brew install bazel
适用于 MacOS 和 Linux 系统,需事先安装
Homebrew
。
Bazel 工程文件组成
使用 Bazel
管理的项目一般包含以下几种 Bazel
相关的文件:WORKSPACE(.bazel)
、BUILD(.bazel)
、.bzl
和 .bazelrc
等。
WORKSPACE(.bazel)
和 .bazelrc
必须要放置于项目的根目录下。BUILD(.bazel)
必须要放在项目的每一个文件夹中去(包括项目根目录)。.bzl
文件可以根据用户喜好自由放置,一般可放在项目根目录下的某个专用文件夹(比如 build)中。
其中,WORKSPACE(.bazel)
和 BUILD(.bazel)
可以加 .bazel
后缀,也可以不加。
WORKSPACE(.bazel)
此文件用于:
- 定义项目根目录和项目名。
- 加载
Bazel
工具和rule
集。 - 管理项目外部依赖库。
一个最小化的可用于构建 golang 语言项目的 WORKSPACE(.bazel)
文件大概是这样的:
# 定义工作环境名称
workspace(name = "com_github_tx7do_bazel_golang_minimal_example")
# 导入http_archive方法
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# 下载rules_go
http_archive(
name = "io_bazel_rules_go",
sha256 = "56d8c5a5c91e1af73eca71a6fab2ced959b67c86d12ba37feedb0a2dfea441a6",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.37.0/rules_go-v0.37.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.37.0/rules_go-v0.37.0.zip",
],
)
## 下载Gazelle
http_archive(
name = "bazel_gazelle",
sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
],
)
#########################################
## Go语言 规则集 初始化
#########################################
# 导入go_register_toolchains和go_rules_dependencies方法
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
# 初始化go规则集的依赖项
go_rules_dependencies()
# 注册go 1.19.5版本的工具链,包含下载安装go环境。
go_register_toolchains(version = "1.19.5")
#########################################
## Gazelle 规则集 初始化
#########################################
# 导入gazelle_dependencies和go_repository方法
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
# 初始化Gazelle规则集的依赖项
gazelle_dependencies()
BUILD.bazel
该文件主要针对其所在文件夹进行 依赖解析 和 构建目标 定义。拿 go 来说,构建目标可以是 go_binary
、go_test
、go_library
等。
为了引用一个依赖,Bazel 使用 label
语法对所有的包进行唯一标识,其格式如下:
@workerspace_name//path/of/package:target
比如,go 中常用的一个日志库 logrus
的 label
为:
@com_github_sirupsen_logrus//:go_default_library
如果是本项目中的包路径,可以将 // 之前的 workspace 名字省去:
//:library
一个最简单的 Go 项目的 BUILD.bazel
看起来是这样的:
# 导入go_binary、go_test、go_library方法
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
# 构建二进制程序
go_binary(
name = "hello",
srcs = ["hello.go"],
deps = [":greeter"],
)
# 构建库
go_library(
name = "greeter",
importpath = "github.com/tx7do/bazel-golang-minimal-example/greeter",
srcs = ["greeter.go"],
)
# 构建单元测试
go_test(
name = "greeter_test",
srcs = [ "greeter_test.go" ],
embed = [ ":greeter" ],
)
自定义 rule (*.bzl)
如果你的项目有一些复杂构造逻辑、或者一些需要复用的构造逻辑,那么可以将这些逻辑以函数形式保存在 .bzl
文件,供 WORKSPACE
或者 BUILD
文件调用。其语法跟 Python
类似:
def download_package():
# 下载 Bazel Go语言 规则集
if not native.existing_rule("io_bazel_rules_go"):
http_archive(
name = "io_bazel_rules_go",
sha256 = "56d8c5a5c91e1af73eca71a6fab2ced959b67c86d12ba37feedb0a2dfea441a6",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.37.0/rules_go-v0.37.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.37.0/rules_go-v0.37.0.zip",
],
)
# 下载 Bazel Gazelle 规则集
if not native.existing_rule("bazel_gazelle"):
http_archive(
name = "bazel_gazelle",
sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
],
)
.bazelrc
.bazelrc
是一个配置文件,熟悉 Linux 的同学一看就知道这是使用的 .*rc
的命名规则的配置文件。
因为网络不好,Golang 环境设置 GOPROXY
和 GOSUMDB
也是必须的,否则 go 依赖库的更新下载会让人崩溃死的。
# 设置JVM
startup --host_jvm_args=-XX:+UseParallelGC --host_jvm_args=-Xmx6g --host_jvm_args=-Xms1g
# 设置CoreDump
startup --unlimit_coredumps
# 设置GOPROXY
test --action_env=GOPROXY=https://goproxy.cn
build --action_env=GOPROXY=https://goproxy.cn
run --action_env=GOPROXY=https://goproxy.cn
# 设置GOSUMDB
test --action_env=GOSUMDB=goproxy.cn/sumdb/sum.golang.org
build --action_env=GOSUMDB=goproxy.cn/sumdb/sum.golang.org
run --action_env=GOSUMDB=goproxy.cn/sumdb/sum.golang.org
# 设置编译目标平台
build --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64
run --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64