2017-10-07 131 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"來解決這個問題。