Я только начал использовать 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.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++. Спасибо за ответ.
В общем, вы должны иметь возможность напрямую зависеть от 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
OMG, это был <> vs "", большое спасибо! Я бы никогда не попробовал это, потому что я всегда использую <> при включении из удаленных библиотек. У меня есть промежуточная библиотека на случай, если я когда-нибудь добавлю несколько вспомогательных классов преобразования в библиотеку protobuf.
поскольку вы, кажется, хорошо разбираетесь в базеле, ответьте на этот вопрос: файлы рабочей области. Кроме того, вы бы сказали, что Bazel можно использовать для довольно большой производственной среды, или мне следует придерживаться CMake?
Я дал там ответ, и краткий ответ: «Да, в основном так это работает, и есть новая система, предназначенная для устранения неудобств, bazel.build/docs/bzlmod». Что касается 2-го вопроса, Google использует Bazel (или его версию) для создания почти всего, поэтому, поскольку у Google есть большая производственная среда, я бы сказал да. См. bazel.build/community/users#google и другие там.
Следует иметь в виду, что Google и другие компании и проекты широко используют удаленное кэширование и удаленное выполнение с помощью Bazel для достижения масштабируемости и повышения производительности для крупных проектов (сотни тысяч целей и более), что требует времени и усилий для настройки и поддерживать.
В том же рабочем пространстве я могу сделать следующее: ```cc_library(name = "my-lib", hdrs = [ ":my-proto-lib" ], deps = [":my-proto-lib"] ) ` «тогда в файле C++, который требует этого, я могу просто:
#include "proto/point.pb.h"
но в зависимой рабочей области, которая извлекает этот репозиторий как внешний, он, похоже, не работает. Я думаю, что это может быть мое неправильное понимание того, как ссылаться на другие рабочие пространства.