2017-10-07 7 views
1

Je tente d'utiliser Bazel's Protocol Buffer Rules pour compiler (générer) des liaisons de langage Python et des dépendances. La mise en page de mon projet est simple, avec un seul répertoire, proto, contenant le fichier .proto et le fichier BUILD.Pourquoi une cible Bazel ProtoBuf publique n'est-elle pas déclarée?

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

Mon fichier 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", 
) 

Dans mon fichier WORKSPACE, le rendement attendu hachage SHA-256 du fichier téléchargé a été omis pour une meilleure lisibilité. La règle WORKSPACE http_archive est utilisée car le ProtoBuf GitHub repo contient les fichiers Bazel WORKSPACE et BUILD.

Le new_http_archive doit être utilisé pour la bibliothèque six puisqu'il ne s'agit pas d'un espace de travail Bazel. Il convient également de noter que Bazel transitive dependencies doit être fourni dans mon dossier WORKSPACE (de la documentation Bazel):

Bazel ne lit que les dépendances répertoriées dans votre fichier Workspace. Si votre projet (A) dépend d'un autre projet (B) qui liste une dépendance sur un troisième projet (C) dans son fichier WORKSPACE, vous devrez ajouter à la fois B et C au fichier WORKSPACE de votre projet.

six.BUILD est pris directement à partir de la prise en pension et enregistré localement:

Mon fichier 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"], 
) 

Les arrises problème lors de la construction:

bazel build //proto:py 

sortie (formaté pour la lisibilité):

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. 

Cependant, la construction de la dépendance externe de ma marche ligne de commande:

bazel build @com_google_protobuf//:protobuf_python 

sortie (tronqué pour la lisibilité):

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

La cible protobuf_python est clairement de condamné à une amende et publique:

Répondre

2

Le problème est que votre cible (// proto: py) dépend //: protobuf_python, pas @com_gooogle_protobuf //: protobuf_python. Vous pouvez le confirmer avec la requête 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 = [], 
) 

Vous pouvez le voir dans la liste des comptes. Alors maintenant, la question est: pourquoi cela dépend-il de cela?Vous n'avez certainement pas défini cela ailleurs. La réponse est que, puisque py_proto_library est une macro, elle peut faire ce qu'elle veut.

En particulier, ces lignes de la macro vous causent des problèmes:

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

py_proto_library a un attribut appelé default_runtime qu'il ajoute à la liste des DEPS. La valeur par défaut est ": protobuf_python". Mais cela ne fonctionne que si vous utilisez la macro dans le même référentiel qui déclare protobuf_python. Par conséquent, vous pouvez résoudre ce problème en définissant default_runtime = "@com_google_protobuf//:protobuf_python" dans vos attributs py_proto_librarys.