Как ссылаться на выходные заголовки bazel С++ protobuf в другом рабочем пространстве/пакете

Я только начал использовать Bazel пару дней назад в надежде на что-то лучшее, чем CMake. У меня есть небольшая библиотека, которая содержит только определения protobuf в собственном репозитории. Я получил bazel для создания прототипов и вижу их в каталоге bazel-bin/proto, но не знаю, как поступить, чтобы включить этот каталог в зависимые рабочие пространства/пакеты, чтобы я мог использовать выходные файлы заголовков?

прото-репозиторий: ПОСТРОИТЬ

      load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

cc_library(
    name = "my-protobuf-common",
    hdrs = [
        ":my-proto-lib",
    ],
    copts = ["--std=c++17"],
    includes = [
        ":my-proto-lib",
    ],
    linkstatic = True,
    visibility = ["//visibility:public"],
    deps = [":my-proto-lib"],
)

cc_proto_library(
    name = "my-proto-lib",
    visibility = ["//visibility:public"],
    deps = [":my-proto"],
)

proto_library(
    name = "my-proto",
    srcs = [
        "proto/point.proto",
        "proto/point-geodetic.proto",
        "proto/point-ned.proto",
    ],
    visibility = ["//visibility:public"],
)

зависимое репо (рабочее пространство правильно извлекается как внешнее, и я вижу вывод сборки прототипа):BUILD

      load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "my-service",
    srcs = [
        "app/bazel-test.cpp",
    ],
    hdrs = [
        "@mpc//:my-protobuf-common",
    ],
    copts = ["--std=c++17"],
    deps = [        
        "@mpc//:my-protobuf-common",
    ],
)

базель-test.cpp

      #include <iostream>
#include <proto/point.pb.h>

int main() {
    MyProtobufCommon::Point p;
}

ошибка сборки:

      app/bazel-test.cpp:2:10: fatal error: proto/point.pb.h: No such file or directory
    2 | #include <proto/point.pb.h>
      |          ^~~~~~~~~~~~~~~~~~

2 ответа

В общем, вы должны быть в состоянии полагаться на cc_proto_libraryнепосредственно, поэтому промежуточный cc_library my-protobuf-commonне нужен вообще. Цепочка инструментов cc использует -iquoteдобавить прототипы, так что я верю #include "proto/point.pb.h"должен быть использован.

proto-repo/WORKSPACE:

      load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "rules_proto",
    sha256 = "66bfdf8782796239d3875d37e7de19b1d94301e8972b3cbd2446b332429b4df1",
    strip_prefix = "rules_proto-4.0.0",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz",
        "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz",
    ],
)
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()

proto-repo/BUILD:

      cc_proto_library(
  name = "point_cc_proto",
  deps = [":point"],
  visibility = ["//visibility:public"],
)

proto_library(
  name = "point",
  srcs = ["proto/point.proto"],
)

proto-repo/proto/point.proto:

      syntax = "proto3";

package my_protos.point;

message Point {
  optional int32 x = 1;
  optional int32 y = 2;
}

main-repo/WORKSPACE:

      load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

local_repository(
  name = "my_protos",
  path = "../proto-repo",
)

http_archive(
    name = "rules_proto",
    sha256 = "66bfdf8782796239d3875d37e7de19b1d94301e8972b3cbd2446b332429b4df1",
    strip_prefix = "rules_proto-4.0.0",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz",
        "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz",
    ],
)
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()

main-repo/BUILD:

      cc_binary(
  name = "main",
  srcs = ["main.cc"],
  deps = ["@my_protos//:point_cc_proto"],
)

main-repo/main.cc:

      #include <iostream>
#include "proto/point.pb.h"

int main() {

  my_protos::point::Point p;
  p.set_x(123);
  p.set_y(456);
  std::cout << p.DebugString();

  return 0;
}

Применение:

      main-repo$ bazel run main
INFO: Analyzed target //:main (43 packages loaded, 570 targets configured).
INFO: Found 1 target...
Target //:main up-to-date:
  bazel-bin/main
INFO: Elapsed time: 6.166s, Critical Path: 5.33s
INFO: 106 processes: 4 internal, 102 linux-sandbox.
INFO: Build completed successfully, 106 total actions
INFO: Build completed successfully, 106 total actions
x: 123
y: 456

cc_library.includesпринимает строки, представляющие пути, а не метки. Вы хотите установить includes = ["."]в my-protobuf-common.

Сходным образом, cc_library.hdrsпредназначен для исходных файлов заголовков, цели которых зависят от этого. #include. Перечисление чего-либо в обоих depsи не имеет смысла, для этого варианта использования вам не нужно hdrsвообще.

Кроме того, используйте cc_binaryсоздать файл с main. не делает полную ссылку.

Кроме того, copts = ["--std=c++17"]редко бывает хорошей идеей. Это только устанавливает флаг для файлов в этом , который может изменить его ABI, чтобы ссылка на другие части сборки не работала. В этом случае cc_library- эквивалентные части cc_proto_libraryне передаст флаг. Используйте флаг командной строки bazel --copt=--std=c++17 insteadчтобы применить его ко всей сборке.

Другие вопросы по тегам