应用Bazel构建系统,其总体目标包括:
- 采用细粒度控制依赖,最大化并行性和增量构建;
- 保持依赖关系的良好封装,严格控制规则的可见性;
- 保持代码组织拥有良好的结构和可测试性;
- 创建易于理解、易于维护的构建系统。
全量构建
一般地,一个良好的项目,如下两个构建命令应该总是成功的;否则,不应该将代码提交到Git上。
$ bazel build //repo_name/...
$ bazel test //repo_name/...
其中,repo_name
为顶级包名。
显示化平台依赖
在一些特殊的情况下,例如,需要特定的构建选项,平台选项,License等,应尽可能显式化地标记相应的规则,并且能够方便用户细粒度地筛选相应的规则,用户通过查看BUILD文件也能够快速了解规则的约束和条件。
尽最大化源码依赖
对于C/C++项目,尽量依赖于源码。如果依赖于二进制库,可能导致不兼容的编译选项和平台依赖。依赖于源码,保证二进制的兼容性和平台的一致性;而且保证诸如静态检查工具,测试覆盖率,及其性能分析更好地工作。
控制头文件的可见性
将公开的头文件放在在hdrs
列表中,而将不公开的头文件放置在srcs
列表中。例如,
cc_library(
name = "bar",
srcs = [
"bar.cc",
"bar-impl.h",
"bar-impl.cc",
],
hdrs = ["bar.h"],
)
此时,foo
依赖于bar
时,仅能包含bar.h
,而不能包含bar-impl.h
。
cc_binary(
name = "main",
srcs = [
"main.cc"
"foo.h",
"foo.cc",
],
deps = [":bar"],
)
只包含直接依赖
加入存在如下依赖关系,foo->bar->baz
。显然,foo
传递依赖于baz
。此时,foo.cc
能够包含foo.h, bar.h
;但是,绝对不应该包含baz.h
,除非foo
显式地将baz
添加到deps
列表中。
不幸的是,Bazel
目前实现由于技术实现的原因,并没有做到传递依赖的相关约束,仅推荐为最佳实践。如果在foo.cc
中包含了baz.h
,依然能够构建成功。但是,这个在未来版本中,可能被强制。
cc_binary(
name = "foo",
srcs = [
"main.cc"
"foo.cc",
"foo.h",
],
deps = [":bar"],
)
cc_library(
name = "bar",
srcs = [
"bar.cc",
"bar-impl.h",
"bar-impl.cc",
],
hdrs = ["bar.h"],
deps = [":baz"],
)
cc_library(
name = "baz",
srcs = [
"baz.cc",
"baz-impl.h",
"baz-impl.cc",
],
hdrs = ["baz.h"],
)