簡體   English   中英

protobuf C ++編譯器的bazel規則

[英]bazel rules for the protobuf C++ compiler

我正在使用Bazel和Google的協議緩沖區。 我想添加一個Bazel規則,以便我可以從.proto文件生成C ++ API。 在GNU make中,我會這樣做(簡化示例):

%.h: %.cc
%.cc: %.proto
    protoc --cpp_out=. $<

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

我嘗試了上面的內容,它似乎沒有用,我從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"]
)

實際上只是檢查是否創建了頭文件並創建了bazel-genfiles目錄。

然后,您可以在cc_library包含原型構建: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", ) 
  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], ) 
  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", ], ) 

有幾種方法。 作為一次性,您可以創建一個genrule來執行某些輸入的命令:

genrule(
    name = "my-proto-gen",
    outs = ["my-proto.cc", "my-proto.h"],
    cmd = "$(location //path/to:protoc) --cpp_out=$@ $<",
    srcs = ["my-proto.proto"],
    tools = ["//path/to:protoc"],
)

cc_library(
    name = "my-proto",
    srcs = ["my-proto.cc"],
    hdrs = ["my-proto.h"],
)

根據你的制定規則,我假設你想多次這樣做。 在這種情況下,您可以在.bzl文件中定義 宏基本上是調用構建規則的函數:

# In, say, foo/bar.bzl.
def cpp_proto(name, src):
  native.genrule(
      name = "%s-gen" % name,
      outs = ["%s.cc" % name, "%s.h" % name],
      cmd = "$(location //path/to:protoc) --cpp_out=$@ $<",
      srcs = [src],
      tools = ["//path/to:protoc"],
  )

  native.cc_library(
      name = name,
      srcs = ["%s.cc" % name],
      hdrs = ["%s.h" % name],
  )

然后在foo / BUILD中,您可以導入並使用您的宏來簡明地調用規則:

load('//foo:bar.bzl', 'cpp_proto')
cpp_proto('my-proto', 'my_proto.proto')

然后你可以依賴於來自cc_library s, cc_binarycc_test//foo:my-proto

最后,您可能想要關注https://github.com/bazelbuild/bazel/issues/52 (並使用mzhaom的宏)。

cc_proto_library原生支持最近登陸了Bazel: httpcc_proto_library

tl; dr,在設置一次WORKSPACE文件之后,

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

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

...

然后,

$ bazel build :person_cc_proto

https://github.com/cgrushko/proto_library上有一個例子。

要點是,您定義了一個proto_library以將.proto文件“導入”Bazel,並將cc_proto_library為將其編譯為C ++。 默認情況下,協議緩沖區編譯器和運行時分別來自@com_google_protobuf//:protoc @com_google_protobuf_cc//:cc_toolchain@com_google_protobuf_cc//:cc_toolchain

這種分離的原因是為了啟用需要編譯為多種語言的大型原型圖。

我在https://github.com/pubref/rules_protobuf上整理了一組protobuf生成規則。 除了許多其他語言之外,它還支持C ++。 希望你覺得它有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM