Сделайте protoc доступным для сборки Bazel.

Вопрос или проблема

В идеале это не вопрос, специфичный для 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.

Вот общий подход, который вы можете попробовать:

  1. Загрузите бинарный файл 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).

  2. Экспонируйте protoc как цепочку инструментов или исполняемый файл:
    После его загрузки вы можете сделать его исполняемой целью, чтобы ваш build.rs мог его вызывать. В вашем BUILD файле создайте правило для экспонирования бинарного файла protoc.

    filegroup(
        name = "protoc_bin",
        srcs = ["@protoc//:bin/protoc"],
    )
    
  3. Сделайте 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 в процессе сборки.

  4. Обеспечьте правильное управление платформами:
    Если ваш 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 для управления зависимостями и инструментами сборки позволит обеспечить гибкость и согласованность в вашей среде разработки.

Оцените материал
Добавить комментарий

Капча загружается...