protobuf C++编译器的bazel规则

mor*_*rxa 7 c++ protocol-buffers bazel

我正在使用Bazel和Google的协议缓冲区.我想添加一个Bazel规则,以便我可以从.proto文件中生成C++ API .在GNU make中,我会这样做(简化示例):

%.h: %.cc
%.cc: %.proto
    protoc --cpp_out=. $<
Run Code Online (Sandbox Code Playgroud)

如何mymessage.proto使用Bazel 完成相同的操作(即每次更改时生成API )?

Sam*_*Sam 6

我尝试了上面的方法,但似乎没有用,protoc尝试创建两个目录时出现错误,然后该my-proto.h目录不存在。相反,我做了

genrule(
    name = "my-proto-gen",
    outs = ["my-proto.pb.h my-proto.pb.cc"],
    cmd = "$(location //third_party/protobuf:protoc) --cpp_out=$(GENDIR) $<",
    srcs = ["my-proto.proto"],
    tools = ["//third_party/protobuf:protoc"],
)

cc_library(
    name = "my-proto",
    srcs = ["my-proto.pb.cc"],
    hdrs = ["my-proto.pb.h"]
)
Run Code Online (Sandbox Code Playgroud)

实际上,它只是检查以查看头文件是否已创建并创建bazel-genfiles目录。

然后,您可以在cc_libraryas中包含原型构建:my-proto

更新:要使整个工作正常进行,请执行以下操作:

  1. 将以下内容添加到您的WORKSPACE文件。这将下载protobuf库:

    http_archive(
        name = "protobuf",
        url = "https://github.com/google/protobuf/releases/download/v3.0.0/protobuf-cpp-3.0.0.zip",
        strip_prefix = "protobuf-3.0.0",
    )
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建一个.bzl文件(假设为protobuf.bzl)并放入以下内容:

    def cpp_proto(name, src):
      native.genrule(
          name = "%s-gen" % name,
          outs = ["%s.pb.cc" % name, "%s.pb.h" % name],
          cmd = "$(location @protobuf//:protoc) --cpp_out=$(GENDIR) $<",
          srcs = [src],
          tools = ["@protobuf//:protoc"],
      )
    
      native.cc_library(
          name = name,
          srcs = ["%s.pb.cc" % name],
          hdrs = ["%s.pb.h" % name],
      )
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在构建文件中,添加 load(':protobuf.bzl', 'cpp_proto')

  4. 您现在可以像这样使用宏:

    cpp_proto(
        name = "my-proto",
        src = "my-proto.proto"
    )
    
    cc_library(
        name = "my-program",
        srcs = ["my-program.cc"],
        deps = [
            ":my-proto",
        ],
    )
    
    Run Code Online (Sandbox Code Playgroud)


use*_*136 5

cc_proto_libraryBazel 最近已提供本机支持: http://bazel.build/blog/2017/02/27/protocol-buffers.html

tl;dr,设置WORKSPACE文件一次后,

cc_proto_library(
    name = "person_cc_proto",
    deps = [":person_proto"],
)

proto_library(
    name = "person_proto",
    srcs = ["person.proto"],
    deps = [":address_proto"],
)

...
Run Code Online (Sandbox Code Playgroud)

然后,

$ bazel build :person_cc_proto
Run Code Online (Sandbox Code Playgroud)

https://github.com/cgrushko/proto_library有一个示例。

要点是您定义一个proto_library将 .proto 文件“导入”到 Bazel 中,并将cc_proto_library其编译为 C++。默认情况下,协议缓冲区编译器和运行时分别从@com_google_protobuf//:protoc和获取@com_google_protobuf_cc//:cc_toolchain

这种分离的原因是为了支持需要编译为多种语言的大型原型图。