如何在含其他BUILD文件的目录中,用sh_test的data=glob匹配Java文件?
Bazel中跨包glob匹配文件的解决办法
你遇到的问题核心是Bazel的包隔离机制:每个BUILD文件对应一个独立的包,父包的glob默认无法直接读取子包(带BUILD文件的子目录)里的文件,因为这些子目录被视为独立的包空间。
以下是几种常用的解决方式:
1. 在子包中定义filegroup并引用
这是最规范的做法,符合Bazel的包设计原则:
- 先在
java/dev/enola/io/BUILD里定义一个暴露Java文件的filegroup:
filegroup( name = "java_sources", srcs = glob(["*.java"]), # 允许父包访问这个目标 visibility = ["//java:__pkg__"], )
- 然后在
java/BUILD的sh_test中直接依赖这个子包的目标:
sh_test( name = "test", srcs = ["test.bash"], data = [ # 当前包的Java文件(如果有的话) glob(["*.java"]), # 子包暴露的文件组 "//java/dev/enola/io:java_sources", ], )
如果有多个子包,每个子包都这么定义后,可以用//java/...:java_sources一次性引用所有子包的同名目标。
2. 使用绝对路径glob匹配全量文件
如果不想逐个定义子包的filegroup,可以直接用绝对路径的glob来匹配所有Java文件(注意要处理好可见性):
sh_test( name = "test", srcs = ["test.bash"], data = glob(["//java/**/*.java"]), )
这种方式会递归匹配java目录下所有包的.java文件,但需要确保这些文件所在的包允许被当前包访问(如果子包的目标有严格的visibility限制,可能需要调整)。
3. 显式指定子目录路径(适合少量子包)
如果子包数量不多,也可以直接在glob里显式列出子目录的路径,绕过包隔离的限制:
sh_test( name = "test", srcs = ["test.bash"], data = glob([ "*.java", "dev/enola/io/*.java", ]), )
这种方式简单直接,但子包多了之后维护起来比较麻烦。
内容的提问来源于stack exchange,提问作者vorburger
相关产品推荐
相关产品推荐

