我正在使用Bazel和Google的協議緩衝區。我想添加一個Bazel規則,以便我可以從.proto
文件生成C++ API。在GNU做,我會做(例如簡化):protobuf C++編譯器的bazel規則
%.h: %.cc
%.cc: %.proto
protoc --cpp_out=. $<
如何可以完成相同(即生成API每當mymessage.proto
變化)使用巴澤爾?
我正在使用Bazel和Google的協議緩衝區。我想添加一個Bazel規則,以便我可以從.proto
文件生成C++ API。在GNU做,我會做(例如簡化):protobuf C++編譯器的bazel規則
%.h: %.cc
%.cc: %.proto
protoc --cpp_out=. $<
如何可以完成相同(即生成API每當mymessage.proto
變化)使用巴澤爾?
原生支持cc_proto_library
最近登陸Bazel:http://bazel.build/blog/2017/02/27/protocol-buffers.html。
TL;博士,設置你的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
。
這種分離的原因是啓用需要編譯爲多種語言的大型原型圖。
有幾種方法。作爲一次性的,你可以創建一個genrule在某些輸入要執行的命令:
genrule(
name = "my-proto-gen",
outs = ["my-proto.cc", "my-proto.h"],
cmd = "$(location //path/to:protoc) [email protected] $<",
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) [email protected] $<",
srcs = [src],
tools = ["//path/to:protoc"],
)
native.cc_library(
name = name,
srcs = ["%s.cc" % name],
hdrs = ["%s.h" % name],
)
然後,比方說,富/ BUILD,你可以導入&使用宏來簡潔地調用規則:
load('//foo:bar.bzl', 'cpp_proto')
cpp_proto('my-proto', 'my_proto.proto')
然後你可以依靠//foo:my-proto
,從cc_library
s,cc_binary
s和cc_test
s。
最後,您可能想要關注https://github.com/bazelbuild/bazel/issues/52(並只使用mzhaom的宏)。
感謝指向mzhaom宏的指針,我不知何故錯過了它。但是,我並不真正瞭解如何使用它。線程末尾還有兩個其他的替代方案,但我無法讓其中任何一個運行。原生protobuf支持似乎缺少cpp部分,並且pubref規則始終引發異常。 – morxa
我試過上面的,它似乎沒有工作,我從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
。
UPDATE: 爲了得到這個整個事情的工作,做到以下幾點:
以下內容添加到您的工作區文件。這個下載的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",
)
創建.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],
)
在你的build文件,添加在load(':protobuf.bzl', 'cpp_proto')
現在,您可以使用宏這樣:
cpp_proto(
name = "my-proto",
src = "my-proto.proto"
)
cc_library(
name = "my-program",
srcs = ["my-program.cc"],
deps = [
":my-proto",
],
)
這隻適用於原始文件在工作區中。如果它位於子文件夾中,則生成的文件不在bazel希望它們出現並失敗的文件夾中。我需要將'--proto_path'添加到'protoc'調用中。 – morxa
我在https://github.com/pubref/rules_protobuf上制定了一套protobuf生成規則。除了支持多種其他語言外,它還支持C++。希望你覺得它有用。
cc_proto_library的本機支持最近登陸Bazel:https://bazel.build/blog/2017/02/27/protocol-buffers.html。如果這對你有幫助,我會把這個評論變成一個答案。 – user1071136
@ user1071136那會很好! – morxa