Вопрос или проблема
В идеале это не вопрос, специфичный для Rust, но для справки: я работаю над проектом на Rust, который использует tonic
для доступа к gRPC, но немного расширяет его функциональность, поэтому он использует пользовательский build.rs
скрипт для вызова компилятора определения proto protoc
. У меня есть проект Bazel (использующий MODULE.bazel
вместо WORKSPACE
), который определяет раздел cargo_build_script
в моем BUILD.bazel
файле для выполнения build.rs
, и пока я выполняю его на системе, где уже установлен protoc
, все собирается идеально. Если я удаляю protoc
, он начинает выдавать ошибку:
Ошибка: Custom { kind: NotFound, error: "Не удалось найти `protoc`. Если `protoc` установлен, попробуйте установить переменную окружения `PROTOC` на путь к бинарнику `protoc`. Чтобы установить его на Debian, выполните `apt-get install protobuf-compiler`. Он также доступен по адресу https://github.com/protocolbuffers/protobuf/releases Дополнительная информация: https://docs.rs/prost-build/#sourcing-protoc" }
Мне нужно, чтобы Bazel также выполнял скрипт сборки внутри нашего CI пайплайна, который по умолчанию не поставляется с protoc
, поэтому я пытаюсь найти самый простой способ сделать protoc
доступным для Bazel. Я нашел toolchains_proto, но пока не смог заставить это работать. Я все еще довольно нов в Bazel. Извините, если это тривиальный вопрос.
Похоже, что большинство цепочек инструментов (включая ту, что указана выше?) предназначены для выполнения компиляции protobuf на отдельном шаге сборки, а не как часть build.rs
Rust. Если возможно, я хотел бы избежать этого и вместо этого просто найти способ заставить Bazel получить бинарный файл protoc
и сделать его доступным таким образом, чтобы я мог добавить его в deps
в правиле cargo_build_script
(если “правило” – правильное слово), что позволит мне по-прежнему вызывать его самостоятельно, как мне угодно, с пользовательскими аргументами и так далее.
Чтобы сделать protoc
доступным в вашей сборке на основе Bazel без необходимости ручной установки, вы можете использовать http_archive
Bazel для загрузки и распаковки бинарного файла protoc
прямо в вашем рабочем пространстве, а затем сделать его доступным в вашем правиле cargo_build_script
.
Вот общий подход, который вы можете попробовать:
-
Загрузите бинарный файл
protoc
с помощьюhttp_archive
:
В вашем файлеWORKSPACE
вы можете определить правилоhttp_archive
для загрузки предварительно скомпилированного бинарного файлаprotoc
для вашей платформы.http_archive( name = "protoc", urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v24.1/protoc-24.1-linux-x86_64.zip"], # Не забудьте настроить для вашей платформы strip_prefix = "protoc-24.1", )
Настройте поле
urls
в зависимости от версииprotoc
, которую вы хотите, и вашей платформы (например, Linux, macOS, Windows). -
Экспонируйте
protoc
как цепочку инструментов или исполняемый файл:
После его загрузки вы можете сделать его исполняемой целью, чтобы вашbuild.rs
мог его вызывать. В вашемBUILD
файле создайте правило для экспонирования бинарного файлаprotoc
.filegroup( name = "protoc_bin", srcs = ["@protoc//:bin/protoc"], )
-
Сделайте
protoc
доступным в вашем правилеcargo_build_script
:
Теперь измените ваше правилоcargo_build_script
, чтобы ссылаться на этот бинарный файлprotoc
и установить переменную окруженияPROTOC
.cargo_build_script( name = "my_build_script", srcs = ["build.rs"], data = [":protoc_bin"], # Сделать бинарный файл protoc доступным env = { "PROTOC": "$(location :protoc_bin)", }, )
Это обеспечит возможность использования скриптом
build.rs
бинарного файлаprotoc
, загруженного Bazel в процессе сборки. -
Обеспечьте правильное управление платформами:
Если ваш CI пайплайн работает на нескольких платформах, вам нужно будет настроитьhttp_archive
для загрузки правильного бинарного файла для каждой платформы. Вы можете сделать это, используя специфичную для платформы логику в вашем файлеWORKSPACE
, чтобы загрузить соответствующий бинарный файлprotoc
.
Используя этот подход, Bazel будет обрабатывать загрузку бинарного файла protoc
, а ваш CI пайплайн не будет зависеть от его предустановки.
Ответ или решение
Чтобы сделать protoc
доступным для сборки в проекте Bazel, не зависимо от предварительной установки, вы можете воспользоваться возможностями Bazel для загрузки необходимых бинарных файлов, а затем интегрировать их в ваш процесс сборки. Вот подробное руководство по этому процессу с использованием http_archive
для загрузки бинарного файла protoc
.
Шаг 1: Загрузка бинарного файла protoc
В вашем файле MODULE.bazel
(или в WORKSPACE
для стандартной конфигурации Bazel) добавьте правило http_archive
, чтобы загрузить предварительно собранный бинарный файл protoc
с GitHub. Например:
http_archive(
name = "protoc",
urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v24.1/protoc-24.1-linux-x86_64.zip"], # Обязательно адаптируйте под вашу платформу
strip_prefix = "protoc-24.1",
)
Убедитесь, что URL соответствует версии protoc
, которую вы хотите использовать, и что указан правильный путь для вашей операционной системы (например, Linux, macOS, Windows).
Шаг 2: Экспонирование protoc
как исполняемого файла
После загрузки бинарника вам нужно создать правило в BUILD.bazel
, чтобы сделать бинарный файл доступным:
filegroup(
name = "protoc_bin",
srcs = ["@protoc//:bin/protoc"],
)
Это правило создаст группу файлов, включающую только исполняемый файл protoc
, чтобы он был доступен для использования в вашем проекте.
Шаг 3: Интеграция protoc
в cargo_build_script
Теперь, когда protoc
доступен как целевой объект в Bazel, вы можете настроить правило cargo_build_script
, чтобы использовать его в вашем скрипте build.rs
. Обновите ваше определение cargo_build_script
, следуя этому примеру:
cargo_build_script(
name = "my_build_script",
srcs = ["build.rs"],
data = [":protoc_bin"], # Делаем бинарный файл protoc доступным
env = {
"PROTOC": "$(location :protoc_bin)",
},
)
Это гарантирует, что ваш скрипт build.rs
сможет использовать бинарный файл protoc
, загруженный Bazel в процессе сборки.
Шаг 4: Обработка различных платформ
Если ваша CI система работает на нескольких платформах, вам следует настроить http_archive
для загрузки соответствующего бинарного файла для каждой платформы. Это можно сделать с помощью платформо-зависимой логики в вашем WORKSPACE
файле, используя условия для определения текущей платформы и выбора соответствующего URL для загрузки.
Заключение
С помощью данного подхода вы сможете сделать protoc
доступным для вашей сборки в Bazel, не зависимо от наличия его на целевой машине. Ваш CI/CD процесс не будет зависеть от предварительной установки protoc
, что значительно упростит процесс автоматической сборки. Вы можете использовать это решение как для собственного проекта, так и для интеграции в другие проекты с использованиеме gRPC и библиотек, таких как tonic
.
Таким образом, использование Bazel для управления зависимостями и инструментами сборки позволит обеспечить гибкость и согласованность в вашей среде разработки.