为了更好地控制包(Package)对外发布的接口,及其细粒度地控制包之间的依赖关系,Bazel通过配置规则的visibility
完成该功能,这是Bazel相对于其他构建工具的一大特色。
可见性级别
Bazel的可见性存在5中类型的精细化控制方法:
-
["//visibility:private"]
: 表示包内私有; -
["//some/package:__pkg__", "//other/package:__pkg__"]
:对//some/package
和//other/package
包可见; -
["//some/package:__subpackages__", "//other/package:__subpackages__"]
:对//some/package
和//other/package
包或子包可见; -
["//some/package:package_group_name"]
:对//some/package:package_group_name
包集合可见; -
["//visibility:public"]
:对所有包可见。
默认的可见性
除非由package
的default_visibility
指定默认的可见性,否则默认为//visibility:private
。
例如,在//polyflow:BUILD
顶级文件中,定义了一个包集合,它表示当前工程下所有的包。
package_group(
name = "internal",
packages = [
"//polyflow/...",
],
)
而在任意的一个包中,可引用该包集合,并赋予包的默认可见性。例如,//polyflow/core:BUILD
中,规则model_id
的可见性对//polyflow
下的所有包可见,包括它自己所在的包。
package(
default_visibility = [
"//polyflow:internal"
],
)
cc_library(
name = "model_id",
hdrs = ["model_id.h"],
srcs = ["model_id.cc"],
)
规约
一般地,如果将测试与实现放在同一个包中,则测试目标能够引用到被测试目标。例如,目标//cub/string:string_view
与目标//cub/string:string_view_test
定义在同一个包中,测试目标可直接引用被测试目标。
package(
default_visibility = [
"//visibility:public",
],
)
cc_library(
name = "string_view",
hdrs = ["string_view.h"],
srcs = ["string_view.cc"],
)
cc_test(
name = "string_view_test",
srcs = ["string_view_test.cc"],
deps = [
":string_view",
"@xunit_cut//:cut",
"@xunit_cut//:cut_main",
],
)
如果违背了这个约定,将头文件、实现文件和测试文件分别放在include
、src
和test
目录,这种风格将导致复杂的Bazel
配置。