前言
因为平时主要是接触 c/golang/js 等语言居多, 相关的构建工具也只是: gcc/go/npm/make 等, bazel这个工具是去年接触, 并没有理会.
最近又遇到这家伙, 还是想快速入个门, 避免用的时候手忙脚乱.
What: bazel 是个啥?
其 github 主页说了:
a fast, scalable, multi-language and extensible build system
fast, scalable啥的就不管了, 还没用过也没个对比的, 不好说.
看最后两个字: build system
, 也就说所谓的构建系统. 那啥是构建呢? 我理解就是编译, 打包吧?
以go语言项目为例子: 先根据代码和配置等生成二进制, 再进一步可能变成docker镜像啥的.
安装
最快的方法, 从其 github release页面下载现成的, 这里我选择: bazelisk-linux-amd64
我的是centos8系统, 操作如下, 更多细节可参考这里:
wget -c https://github.com/bazelbuild/bazelisk/releases/download/v1.12.0/bazelisk-linux-amd64
chmod +x bazelisk-linux-amd64
mv bazelisk-linux-amd64 /usr/local/bin/bazel
使用 bazel 的要求
在上述安装完成后, 通过bazel help
看下
bazel help
WARNING: Invoking Bazel in batch mode since it is not invoked from within a workspace (below a directory having a WORKSPACE file).
[bazel release 5.2.0]
Usage: bazel <command> <options> ...
省略......
发现有个警告: WARNING: Invoking Bazel in batch mode since it is not invoked from within a workspace (below a directory having a WORKSPACE file).
有人说: 我干活从来不管WARNING, 只管ERROR, 这里还真得了解下.
上面的警告大意是说:
当前不在一个workspace下, 啥是worksapce? 目录里有个 WORKSPACE
文件就是workspace.
另外, 包含有名为WORKSPACE
文件的目录, 即为workspace的根.
WORKSPACE 文件介绍
上面说缺少WORKSPACE
文件, 那我创建一个再试试
$ cd /tmp/
$ mkdir bazeldemo && cd bazeldemo/
$ touch WORKSPACE
$ bazel help
Starting local Bazel server and connecting to it...
[bazel release 5.2.0]
Usage: bazel <command> <options> ...
... 省略
嗯, 没有警告了.
WORKSPACE 文件主要就是命名 workspace 以及声明外部的依赖
可以看下 envoy 项目的 WORKSPACE 文件, 直接看也能明白个一二:
workspace(name = "envoy")
load("//bazel:api_binding.bzl", "envoy_api_binding")
envoy_api_binding()
load("//bazel:api_repositories.bzl", "envoy_api_dependencies")
envoy_api_dependencies()
load("//bazel:repositories.bzl", "envoy_dependencies")
envoy_dependencies()
load("//bazel:repositories_extra.bzl", "envoy_dependencies_extra")
envoy_dependencies_extra()
load("//bazel:python_dependencies.bzl", "envoy_python_dependencies")
envoy_python_dependencies()
load("//bazel:dependency_imports.bzl", "envoy_dependency_imports")
envoy_dependency_imports()
BUILD 文件
每个包(模块)还需要一个名为BUILD
的文件, 里边会写一些代码来说明本包(模块)是如何构建的, 相当于"分而治之"了, 参考 这里.
Hello World
大概明白了, 搞个小 demo 看看:
tree .
.
├── main
│ ├── BUILD
│ ├── lib
│ │ ├── lib.cc
│ │ └── lib.h
│ └── main.cc
└── WORKSPACE
其中WORKSPACE文件内容为空, BUILD文件内容如下:
cc_library(
name = "lib",
srcs = ["lib/lib.cc"],
hdrs = ["lib/lib.h"],
)
cc_binary(
name = "main.out",
srcs = ["main.cc"],
deps = [
":lib",
],
)
cc_library 相当于是 bazel 的内置函数吧, 上面的意思一看也能明白:
最终是想生成 main.out 可执行文件, 其依赖 lib 库, lib 库的构建依赖于 lib.cc 和 lib.h;
OK, 迫不及待 build 看看:
$ bazel build //main:main.out
INFO: Analyzed target //main:main.out (37 packages loaded, 164 targets configured).
INFO: Found 1 target...
Target //main:main.out up-to-date:
bazel-bin/main/main.out
INFO: Elapsed time: 0.501s, Critical Path: 0.24s
INFO: 7 processes: 4 internal, 3 linux-sandbox.
INFO: Build completed successfully, 7 total actions
$ tree .
.
├── bazel-bazeldemo -> /root/.cache/bazel/_bazel_root/6ac66131e4a7caa816f83e2caf741288/execroot/__main__
├── bazel-bin -> /root/.cache/bazel/_bazel_root/6ac66131e4a7caa816f83e2caf741288/execroot/__main__/bazel-out/k8-fastbuild/bin
├── bazel-out -> /root/.cache/bazel/_bazel_root/6ac66131e4a7caa816f83e2caf741288/execroot/__main__/bazel-out
├── bazel-testlogs -> /root/.cache/bazel/_bazel_root/6ac66131e4a7caa816f83e2caf741288/execroot/__main__/bazel-out/k8-fastbuild/testlogs
├── main
│ ├── BUILD
│ ├── lib
│ │ ├── lib.cc
│ │ └── lib.h
│ └── main.cc
└── WORKSPACE
发现多了几个目录, 看下效果:
$ ls -al ./bazel-bin/main/main.out
-r-xr-xr-x 1 root root 17528 Jun 18 18:28 ./bazel-bin/main/main.out
$ ./bazel-bin/main/main.out
3 # 输出的结果符合预期
打扫战场:
$ bazel clean
INFO: Starting clean (this may take a while). Consider using --async if the clean takes more than several minutes.
$ ls
main WORKSPACE
(完)