2017-10-07 41 views
1

我试图使用Bazel's Protocol Buffer Rules来编译(生成)Python语言绑定和任何依赖项。我的项目布局很简单,只有一个目录proto,其中包含.proto文件和BUILD文件。为什么公开可见的Bazel ProtoBuf目标'未声明'

WORKSPACE 
BUILD.six 
|-- proto 
| |-- example.proto 
| |-- BUILD 

WORKSPACE文件:

workspace(name = "com_example") 

http_archive(
    name = "com_google_protobuf", 
    strip_prefix = "protobuf-3.4.1", 
    urls = ["https://github.com/google/protobuf/archive/v3.4.1.zip"], 
) 

new_http_archive(
    name = "six_archive", 
    build_file = "six.BUILD", 
    url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz", 
) 

bind(
    name = "six", 
    actual = "@six_archive//:six", 
) 

在我WORKSPACE文件,下载的文件的预期SHA-256散列已经为可读性省略。由于ProtoBuf GitHub repo包含Bazel WORKSPACEBUILD文件,因此使用http_archive WORKSPACE规则。

new_http_archive必须用于六个库,因为它不是Bazel工作区。另外值得一提的是,Bazel transitive dependencies必须在我WORKSPACE文件中提供的(从巴泽尔文档):

巴泽勒只读取工作区中的文件中列出的依赖关系。如果您的 项目(A)依赖于另一个项目(B),该项目(B)在其WORKSPACE文件中列出了依赖于 的第三个项目(C),则必须将B 和C都添加到项目的WORKSPACE文件中。

six.BUILD直接从回购取出并保存在本地:

BUILD文件

load("@com_google_protobuf//:protobuf.bzl", "py_proto_library") 

py_proto_library(
    name = "py", 
    use_grpc_plugin = True, 
    deps = [ 
     "@com_google_protobuf//:protobuf_python", 
     ":example_proto", 
    ], 
    visibility = ["//visibility:public"], 
    # protoc = "@com_google_protobuf//:protoc", 
) 

proto_library(
    name = "example_proto", 
    srcs = ["example.proto"], 
) 

问题棱当建筑:

bazel build //proto:py 

输出(格式化的可读性):

proto/BUILD:3:1: 
no such target '//:protobuf_python': 
target 'protobuf_python' not declared in package '' defined by BUILD and referenced by '//proto:py'. 
ERROR: Analysis of target '//proto:py' failed; build aborted. 

但是,从我的命令行建立外部依赖的工作:

bazel build @com_google_protobuf//:protobuf_python 

输出(截断可读性):

INFO: Found 1 target... 
... 
INFO: Elapsed time: 51.577s, Critical Path: 8.63s 

protobuf_python目标显然是de罚款和公众:

回答

2

的问题是,你的目标(原//:PY)取决于//:protobuf_python,不@com_gooogle_protobuf //:protobuf_python。你可以用bazel查询来确认。

$ bazel query --output build //proto:py 
# proto/BUILD:3:1 
py_library(
    name = "py", 
    visibility = ["//visibility:public"], 
    generator_name = "py", 
    generator_function = "py_proto_library", 
    generator_location = "proto/BUILD:3", 
    deps = ["//:protobuf_python", "@com_google_protobuf//:protobuf_python", "//proto:example_proto"], 
    imports = [], 
    srcs = [], 
) 

你可以在deps列表中看到它。所以现在的问题是,为什么它取决于那个?你当然没有在任何地方设置。答案是,由于py_proto_library是一个宏,它可以做任何想做的事情。

尤其是宏观的,这些线是造成你的麻烦:

https://github.com/google/protobuf/blob/6032746882ea48ff6d983df8cb77e2ebf399bf0c/protobuf.bzl#L320 https://github.com/google/protobuf/blob/6032746882ea48ff6d983df8cb77e2ebf399bf0c/protobuf.bzl#L373-L374

py_proto_library有一个名为default_runtime它追加到DEPS列表中的属性。默认值是“:protobuf_python”。但是,只有在声明protobuf_python的同一个存储库中使用宏时才有效。

所以,你可以通过在你的py_proto_librarys属性中设置default_runtime = "@com_google_protobuf//:protobuf_python"来解决这个问题。

相关问题