Bazel Starlark API对外部存储库中的文件执行奇怪的操作。我有以下Starlark片段:
print(ctx.genfiles_dir)
print(ctx.genfiles_dir.path)
print(output_filename)
ret = ctx.new_file(ctx.genfiles_dir, output_filename)
print(ret.path)
它正在创建以下输出:
DEBUG: build_defs.bzl:292:5: <derived root>
DEBUG: build_defs.bzl:293:5: bazel-out/k8-fastbuild/genfiles
DEBUG: build_defs.bzl:294:5: google/protobuf/descriptor.upb.c
DEBUG: build_defs.bzl:296:5: bazel-out/k8-fastbuild/genfiles/external/com_google_protobuf/google/protobuf/descriptor.upb.c
多余的external/com_google_protobuf
似乎无处不在,这使我的规则失败了:
ctx.genfiles_dir.path
(即bazel-out/k8-fastbuild/genfiles
)。bazel-out/k8-fastbuild/genfiles/google/protobuf/descriptor.upb.c
bazel-out/k8-fastbuild/genfiles/external/com_google_protobuf/google/protobuf/descriptor.upb.c
同样,当我尝试从外部存储库中对源文件调用file.short_path
时,会得到类似../com_google_protobuf/google/protobuf/descriptor.proto
的结果。这似乎无济于事,所以我只写了一些手动代码来剥离开头的../com_google_protobuf/
。
我想念什么吗?我该如何以一种好像我并没有一直在与Bazel战斗的方式编写此规则?
答案 0 :(得分:1)
我想念什么吗?
您已经意识到,基本问题是,您有两个路径“命名空间”,一个是protoc看到的路径(即,导入路径),另一个是bazel看到的路径(即,您传递到declare_file()
的路径)。
2件事要注意:
1)用declare_file()
声明的所有路径都获得路径<bin dir>/<package path incl. workspace>/<path you passed to declare_file()>
2)所有操作均从<bin dir>
执行(除非是output_to_genfils=True
,在这种情况下,如您的示例所示,该操作将切换为<gen dir>
。
尝试解决与您遇到的完全相同的问题,我采取了从output_file路径中剥离已知路径的方法,以确定将哪个目录作为p传递:
# This code is run from the context of the external protobuf dependency
proto_path = "google/a/b.proto"
output_file = ctx.actions.declare_file(proto_path)
# output_file.path would be `<gen_dir>/external/protobuf/google/a/b.proto`
# Strip the known proto_path from output_file.path
protoc_prefix = output_file.path[:-len(proto_path)]
print(protoc_prefix) # Prints: <gen_dir>/external/protobuf
command = "{protoc} {proto_paths} {cpp_out} {plugin} {plugin_options} {proto_file}".format(
...
cpp_out = "--cpp_out=" + protoc_prefix,
...
)
您也许还可以使用ctx.bin_dir
,ctx.label.workspace_name
,ctx.label.package
和ctx.label.name
构建相同的路径。
proto_library
最近获得了属性strip_import_prefix
。使用时,以上内容是不正确的,因为所有相关文件都被符号链接到一个新目录,在该目录中,它们具有用strip_import_prefix
声明的相对路径。
路径格式为:
<bin dir>/<repo>/<package>/_virtual_base/<label name>/<path `import`ed in .proto files>
i.e.
<bin dir>/external/protobuf/_virtual_base/b_proto/google/a/b.proto
假设您要构建一个名为protobuf
的外部存储库,该存储库的根目录包含一个BUILD
文件,目标文件名为b_proto
,而目标文件又依赖于一个{{1} }包装proto_library
并使用google/a/b.proto
属性。