Bazel是Google开源的一个构建系统,主要支持分布式缓存和增量编译,使得大项目的构建更快速, 主要用于C++,Java,Go等服务端项目构建.
有一个与之类似的快速构建系统Buck(Facebook开源)则更关注于Android和iOS客户端的构建. 两者都倾向于mono repo(而非基于项目的仓库)的构建.
之前看了眼官方教程,觉得过于复杂没有引起兴趣. 最近看到在B站代码和envoy都作为标配,所以再做些深入了解.
使用基础
在项目的根目录下创建WORKSPACE和BUILD文件.
工作区/WORKSPACE配置
bazel有工作区的概念, 该文件配置加载bazel环境需要的规则和依赖,可以为空.
### BUILD配置 构建项目信息配置文件,语法类似于python.
java_binary(
name = "ProjectRunner",
srcs = ["src/main/java/com/example/ProjectRunner.java"],
main_class = "com.example.ProjectRunner",
deps = [":greeter"],
)
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
visibility = level属性改变目标的可见范围, 在上面的例子中需要改变默认当前BUILD的限制,因为用到了其他BUILD配置.
构建命令
bazel build //:ProjectRunner
构建后将生成一些输出目录的符号链接,如bazel-bin和bazel-out.
可部署
# 默认不会包含依赖,而采用加入CLASSPATH的方式确保本地可以运行
bazel build //src/main/java/com/example/cmdline:runner
# jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
# 如果要求可部署,需要加_deploy后缀
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Go项目构建
WORKSPACE文件
加载Go规则,使用gazelle自动生成/更新BUILD文件.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "io_bazel_rules_go",
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.18.5/rules_go-0.18.5.tar.gz"],
sha256 = "a82a352bffae6bee4e95f68a8d80a70e87f42c4741e6a448bec11998fcc82329",
)
http_archive(
name = "bazel_gazelle",
urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.17.0/bazel-gazelle-0.17.0.tar.gz"],
sha256 = "3c681998538231a2d24d0c07ed5a7658cb72bfb5fd4bf9911157c0e9ac6a2687",
)
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
gazelle_dependencies()
BUILD配置文件
添加
load("@bazel_gazelle//:def.bzl", "gazelle")
# 更新为对应项目名
gazelle(
name = "gazelle",
prefix = "bazeltest",
)
生成配置文件
bazel run //:gazelle
注: 在我本地测试时,没有自动生成go_binary相关配置, 则需要更新配置如下:
load("@io_bazel_rules_go//go:def.bzl", "go_binary","go_library", "go_test")
go_binary(
name = "bazeltest",
srcs = ["main.go"],
deps = [":go_default_library"],
# embed = [":go_default_library"],
# visibility = ["//visibility:public"],
# out = "cmd",
)
构建
# // 来表示当前项目的根目录, ... 表示当前路径下所有的包
bazel build //...
# 指定目标
bazel build //cmd/bazeltest