буферы протокола — базовые правила для компилятора protobuf C ++

Я использую Bazel и буфер протокола Google. Я хочу добавить правило Bazel, чтобы я мог генерировать C ++ API из .proto файлы. В GNU make я бы сделал (упрощенный пример):

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

Как я могу сделать то же самое (то есть генерировать API всякий раз, когда mymessage.proto изменения) с помощью Bazel?

6

Решение

Нативная поддержка cc_proto_library Недавно приземлился в Базеле: http://bazel.build/blog/2017/02/27/protocol-buffers.html.

тл; д-р, после настройки вашего 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соответственно.

Причина такого разделения состоит в том, чтобы включить большие протограммы, которые должны быть скомпилированы для нескольких языков.

3

Другие решения

Я попытался выше, и это не сработало, я получил ошибку от 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",
    ],
    )
    
4

Есть несколько способов. Вы можете просто создать 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"],
)

Исходя из вашего правила make, я предполагаю, что вы хотите сделать это несколько раз. В этом случае вы можете определить макрос в файле .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')

Тогда вы можете зависеть от //foo:my-proto от cc_librarys, cc_binaryс и cc_tests.

Наконец, вы можете следовать https://github.com/bazelbuild/bazel/issues/52 (и просто используйте макрос mzhaom).

2

Я собрал набор правил генерации протобуфа в https://github.com/pubref/rules_protobuf. Он поддерживает C ++ в дополнение к ряду других языков. Надеюсь, что вы найдете ее полезной.

2
По вопросам рекламы [email protected]