Как ссылаться на выходные заголовки 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"],
)

зависимое репо (рабочее пространство правильно вытягивается как внешнее, и я вижу вывод сборки прототипа): СТРОИТЬ

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>
      |          ^~~~~~~~~~~~~~~~~~

В том же рабочем пространстве я могу сделать следующее: ```cc_library(name = "my-lib", hdrs = [ ":my-proto-lib" ], deps = [":my-proto-lib"] ) ` «тогда в файле C++, который требует этого, я могу просто: #include "proto/point.pb.h" но в зависимой рабочей области, которая извлекает этот репозиторий как внешний, он, похоже, не работает. Я думаю, что это может быть мое неправильное понимание того, как ссылаться на другие рабочие пространства.

weagle08 09.05.2022 19:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

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

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

Я обнаружил, что мне вообще не нужно включать, и причина того, что копты находятся в самом файле сборки, заключается в том, что я надеюсь, что он работает как минимальная версия в CMake, которая выдает ошибку, если вы пытаетесь построить проект с помощью меньшая версия gcc/g++. Спасибо за ответ.

weagle08 10.05.2022 14:37
Ответ принят как подходящий

В общем, вы должны иметь возможность напрямую зависеть от cc_proto_library, поэтому промежуточное звено cc_librarymy-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

OMG, это был <> vs "", большое спасибо! Я бы никогда не попробовал это, потому что я всегда использую <> при включении из удаленных библиотек. У меня есть промежуточная библиотека на случай, если я когда-нибудь добавлю несколько вспомогательных классов преобразования в библиотеку protobuf.

weagle08 10.05.2022 02:04

поскольку вы, кажется, хорошо разбираетесь в базеле, ответьте на этот вопрос: файлы рабочей области. Кроме того, вы бы сказали, что Bazel можно использовать для довольно большой производственной среды, или мне следует придерживаться CMake?

weagle08 10.05.2022 02:26

Я дал там ответ, и краткий ответ: «Да, в основном так это работает, и есть новая система, предназначенная для устранения неудобств, bazel.build/docs/bzlmod». Что касается 2-го вопроса, Google использует Bazel (или его версию) для создания почти всего, поэтому, поскольку у Google есть большая производственная среда, я бы сказал да. См. bazel.build/community/users#google и другие там.

ahumesky 10.05.2022 02:54

Следует иметь в виду, что Google и другие компании и проекты широко используют удаленное кэширование и удаленное выполнение с помощью Bazel для достижения масштабируемости и повышения производительности для крупных проектов (сотни тысяч целей и более), что требует времени и усилий для настройки и поддерживать.

ahumesky 10.05.2022 03:04

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