Bazel之旅
新建一个C++工程,物理组织如下图所示。该工程的WORKSPACE为空文件,该项目不存在外部依赖。并且,包括lib和main两个包。
lib包
头文件
lib/hello-time.h
实现如下。
#ifndef FEDF_8765_DHEG_9465_GHEK_87HE_
#define FEDF_8765_DHEG_9465_GHEK_87HE_
void print_localtime();
#endif
实现文件
lib/hello-time.cc
实现如下。
#include "lib/hello-time.h"
#include
#include
void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}
需要注意的是,-I
的包含路径始于WORKSPACE
所在目录。因此,包含hello-time.h
时,需要加前缀路径#include "lib/hello-time.h"
。
构建目标
lib/BUILD
构建脚本如下。Bazel的构建脚本常常命名为BUILD
或BUILD.bazel
。
cc_library(
name = "hello-time",
hdrs = ["hello-time.h"],
srcs = ["hello-time.cc"],
visibility = ["//main:__pkg__"],
)
在规则//lib:hello-time
定义中,声明了visibility
属性为//main:__pkg__
,表示该规则对 main
包可见。Bazel的所有规则,其可见性默认为private
(后文将详细阐述)。
main包
头文件
在main包中,定义了一个定义和实现了一个get_greet
函数。
#ifndef DHEO_9573_BDTW_6438_NKDE_7619_
#define DHEO_9573_BDTW_6438_NKDE_7619_
#include
std::string get_greet(const std::string &thing);
#endif
实现文件
同样注意的是,-I
目录始于WORKSPACE
。
#include "main/hello-greet.h"
#include
std::string get_greet(const std::string& who) {
return std::string("Hello ") + who;
}
main函数
main
函数将构建可执行程序,它分别依赖于上述的两个目标。
#include "lib/hello-time.h"
#include "main/hello-greet.h"
#include
int main(int argc, char** argv) {
std::cout << get_greet("world") << std::endl;
print_localtime();
return 0;
}
构建脚本
重点关注一下规则//main:hello-world
的deps
属性。一方面,因为//main:hello-world
和//main:hello-greet
在同一个包中,可简写为:hello-greet
。但是,//main:hello-world
和//main:hello-time
不在同一个包中,因此需要完整的路径。
另一方面,因为lib
和main
包隶属不同的包(Package)。为了能够让main
包访问lib
包,需要显式地声明lib
包对main
包可见//main:__pkg__
。
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",
],
)
构建
执行如下命令,构建目标//main:hello-world
。
$ bazel build //main:hello-world
构建成功后,生成可执行程序bazel-bin/main/hello-world
。
$ bazel-bin/main/hello-world Hello world
依赖图
执行如下命令,可以得到以//main:hello-world
为根节点的DAG
图。
$ xdot <(bazel query --nohost_deps --noimplicit_deps 'deps(//main:hello-world)' --output graph)