[devel] Расширение функциональности rpm-build-rust
Danil Shein
dshein на basealt.ru
Чт Сен 17 14:01:52 MSK 2026
Добрый день!
Комментарий ниже не относится к модификации макросов для сборки проектов
на Раст: данные изменения выглядят вполне обоснованными на мой взгляд.
Вот тут обсуждаются всякие подходы к тому, чтобы втащить в сизиф кучу
крэйтов раста как системные зависимости для "контроля и учёта" и вообще
всеобщего блага.
Идея как будто бы понятная и даже имеющая под собой какое-то обоснование.
У меня несколько чисто практических вопросов больше с точки зрения
разработчика на Раст:
1. Как быть с тем что в рамках одного проекта у вас может завендорится
сразу несколько несовместимых версий одного и того же крэйта и это
вообще абсолютно нормально для экосистемы Раст? Насколько я помню
репозиторий такие сценарии поддерживает чуть более чем никак.
2. Что буде собой представлять упакеченный крэйт который нужен другим
проектам исключительно в виде исходного кода без возможности
предварительной компиляции в какие либо артефакты? Просто тарбол с сорцами?
3. Как вы себе представляете использование таких упакеченных крэйтов в
апстримных проектах? Вот прям как именно в вашем понимании будет это
выглядеть на практике? Километровые патчи в Cargo.toml и борьба с тем
что локальные крэйты приезжают только с абсолютными путями не говоря уже
о других сложностях?
Ну и если всё вышеуказанное легко решаемо, то кто будет сопровождать все
эти зависимости и как?
Вот мой пакет например хочет версию крэйта 1.5 и я его обновляю ломая
при этом чужие пакеты которые требуют не совместимую версию 0.9. И я
полагаю тут может быть ситуация когда починить чужой пакет вообще не
получится т.к. зависимость транзиентная и просто поползёт пол
репозитория на каждое изменение.
Мне кажется мы уже достаточно ходили по этим граблям с другими языками,
и если для интерпретируемых языков подход с втаскиванием всех
зависимостей в репозиторий ещё как-то работает, то для Раст и например
Го альтернативы вендорингу я лично не вижу вообще.
Надеюсь мои комментарии дадут некоторую пищу для ума участникам
сообщества и позволят выработать правильный подход к упакечиванию
проктов на Расте.
15.09.2026 15:55, Rx пишет:
>
> Привет!
>
> Недавно нашёл время решить проблемы с которыми сталкивался лично
> и слышал от других мейнтейнеров при использовании макросов из
> rpm-build-rust.
>
> Поскольку часть изменений может вызвать споры и непредвиденные
> побочные эффекты, считаю что стоит поднять обсуждение по возможным
> доработкам.
>
> https://packages.altlinux.org/ru/tasks/431040/
>
>
> Использованные термины
>
> Пакет (ориг. package
> <https://doc.rust-lang.org/cargo/appendix/glossary.html#package>)
> - набор исходных файлов с манифестом Cargo.toml
> <https://doc.rust-lang.org/cargo/reference/manifest.html>, описывающим
> метаданные для сборки пакета.
>
> Cargo
> <https://doc.rust-lang.org/cargo/guide/why-cargo-exists.html#enter-cargo>
> - пакетный менеджер / система сборки нацеленная на пакеты на языке
> программирования Rust.
>
> Рабочее пространство (ориг. workspace
> <https://doc.rust-lang.org/cargo/reference/workspaces.html#workspaces>)
> - набор пакетов, связанных единым манифестом и зависимостями.
>
>
> Были добавлены аргументы путей для %rust_prep
>
> В некоторых случаях апстримный гит репозиторий может содержать
> несколько пакетов несвязанных между собой через рабочее пространство,
> для таких пакетов необходимо создавать собственную конфигурацию и
> вендорить отдельные зависимости. Выполнение данного действия
> подразумевает оборачивание rust_prep в cd или push/pop, что внешне
> может ухудшать читаемость и внешний вид spec-файла. Примерами таких
> пакетов могут выступать тестовые пакеты, представляющие
> собой отдельные CLI утилиты использующие собранные бинарные артефакты.
> Поэтому для решения этой проблемы был добавлен аргумент:
>
> -p <path> - путь до корня пакета, данная опция задаёт корень,
> относительно которого заполняется конфигурация .cargo/config.toml и
> выполняется вендоринг.
>
> Иногда апстрим может класть config.toml в нестандартные папки,
> например cargo/, из которых потом другая системой сборки, например
> Make или Meson, устанавливают cargo.config по нужному пути. Чтобы
> изменить путь в котором находится config.toml с .cargo/ на
> альтернативный можно использовать аргумент:
>
> -c <path> - путь относительно текущего корня пакета в котором стоит
> искать config.toml.
>
> Для общей конфигурции корня или пути до .cargo/ были добавлены
> глобальные переменные задающие значения по умолчанию:
>
> %rust_package_root ${PWD}
>
> %rust_cargo_config_home ".cargo"
>
>
> Был добавлен механизм вендоринга на уровне макросов
>
> Вдохновишись подходом, описанным @aris для вендоринга зависимостей в
> https://bugzilla.altlinux.org/48459 (например spec-файла
> <https://packages.altlinux.org/ru/sisyphus/srpms/glycin-2/specfiles/>),
> я решил реализовать данный механизм при помощи макросов и
> интегрировать его в %rust_prep.
>
> Такой подход позволяет:
>
> 1. Не прибивать вендоринг к наличию дополнительных инструментов,
> таких как etersoft-build-utils, zoryn или самописных решений: для
> вендоринга достаточно иметь hasher или rpmbuild с программой,
> выполняющей вендоринг.
> 2. Связать процесс вендоринга со spec-файлом.
> 3. Перевести ручной вендоринг на сторону сборочницы. Если в будущем
> появится подходящая инфраструктура, можно будет заменить вендоринг
> обращением к внутреннему зеркалу.
>
>
> Для добавления возможности вендоринга spec-файл должен
> содержать:
>
> # При отключенном вендоринге брать vendor/ из заранее подготовленного
> архива.
> %{!?_enable_rust_vendoring: Source1: vendor.tar }
>
> BuildRequires(pre): rpm-build-rust
> # При активном вендоринге, установить программу для вендоринга.
> # По умолчанию %rust_vendor использует cargo-vendor-alt из
> cargo-vendor-filterer.
> %{?_enable_rust_vendoring:
> BuildRequires: cargo-vendor-filterer
> }
>
> %prep
> # Аналогично Source1.
> %setup %{!?_enable_rust_vendoring:-a1}
> %rust_prep
>
>
> Сборка пакета с вендорингом.
>
> Для сборки пакета с вендорингом достаточно передать в rpmbuild
> '--enable "rust_vendoring" '.
>
>
> Для Hasher + gear весь процесс вендоринга выглядит следующим
> образом:
>
> hsh --apt-config=<путь до используемого apt-conf> --initroot
> hsh-update-resolver-conf
> share_network=1 gear --hasher --commit -v -- hsh-rebuild -v
> --rpmbuild-args="--enable rust_vendoring"
>
> По завершении %rust_prep архив c завендоренными зависимостями
> помещается в RPM/SOURCES/ или же %_sourcedir. Его можно скопировать
> сразу же после %prep или по окончании сборки, например так:
>
> "cp ~/hasher/chroot/usr/src/RPM/SOURCES/vendor.tar ."
>
> Полученный архив сохраняет путь до директории в которой был произведён
> вендоринг относительно пути в котором был вызван %rust_prep. Например
> если был вызов %rust_prep -p rust/ в полученном архиве корень будет
> начинаться с rust/.
>
>
> Конфигурация вендоринга.
>
> Название получаемого архива можно изменить опцией -o передаваемой
> в %rust_prep, например %rust_prep -o cargo_vendor.tar
>
> Для конфигурации вендоринга можно переопределить следующие глобальные
> макросы:
>
> %rust_vendor_prog - программа/скрипт выполняющая только вендоринг,
> обязательным требованием к ней является передача в stdout списка
> источников которые заменены вендорингом, подобно тому как это делает
> cargo vendor или cargo-vendor-filterer. По умолчанию вендоринг
> выполняется при помощи cargo-vendor-alt.
>
> %rust_vendor_options <аргументы для %rust_vendor_prog>
>
> %rust_pre_vendor <shell code or binary> - программа или скрипт
> вызываемые до вендоринга.
>
> %rust_post_vendor <shell code or binary> - программа или скрипт
> вызываемые после вендоринга, но до упаковки vendor/ в архив.
>
> %rust_vendor <shell code or binary> - программа выполняющая вендоринг,
> фильтрацию списка зависимостей и сохранение его в vendor/.
>
>
> Была добавлена поддержка профилей.
>
> Некоторые апстримы могут определять альтернативные конфигурации
> сборки, например вместо обычного release апстрим может определить
> release-lto/release-fast/release-small.
>
> Для изменения собираемого профиля было добавлены следующие макросы:
> %rust_upstream_profile - Какой апстримный профиль использовать для сборки.
>
> %rust_downstream_profile - Как назвать сборочный профиль
> унаследованный от апстримного.
>
> Некоторые апстримы могут определять профили в .cargo/config.toml. В
> таком случае при попытке переопределить его опции через конфигурацию
> Cargo будет жаловаться на дублирование профилей. Во избежания этой
> ситуации можно создать собственный профиль унаследованный от апстримного.
>
> %rust_build_profile - Какой профиль использовать в командах сборки,
> установки и тестирования. В очень редких случаях апстрим может
> использовать специализированный профиль для тестов.
>
>
> Появился макрос для обозначения целевой директории.
>
> С появлением поддержки профилей был добавлен макрос который задаёт
> директорию в которую cargo кладёт бинарные артефакты и из которой
> производится установка. В первую очередь данный макрос нужен для
> ручной установки артефактов из целевой директории, когда cargo install
> и %rust_install не могут сделать это самостоятельно, например при
> устнавке заголовочных файлов, ассетов и тд.
>
> Вместе с тем был добавлен макрос %rust_resolve_target_dir, который
> при вызове при помощи механизмов Cargo возвращает путь до target/.
>
>
> RUSTFLAGS больше не задаётся по умолчанию через окружение.
>
> Переменная RUSTFLAGS это низкоуровневая переменная которая задаёт
> флаги напрямую передаваемые компилятору на всех стадиях сборки в обход
> механизмов Cargo. Её главное назначение передать флаги, которые Cargo
> не умеет выставлять самостоятельно. В общем случае это может быть
> бесполезно, а иногда вредно, потому что Cargo не умеет объединять
> флаги с нескольких уровней. Это значит что если апстрим определяет
> свои специфические флаги для лучшей поддержки целевой архитектуры, они
> будут перезаписаны и, как следствие, можно ожидать нестабильную работу
> приложения.
>
> Если всё же нужно выставить RUSTFLAGS, то никаких барьеров к тому
> чтобы самостоятельно экспортировать флаги через export RUSTFLAGS нет.
>
> Если выставляемые RUSTFLAGS являются общими для всех пакетов и всех
> стадий, то можно задать макрос %rustflags, который синхронизирует
> rustflags между %rust_build, %rust_test,
> %rust_cbuild, %rust_ctest, %rust_cinstall.
>
>
> Отладочная информация теперь задаётся штатными механизмами Cargo.
>
> Теперь при вызове %rust_build отладочная информация задаётся напрямую
> через конфигурацию профиля и аргументы командной строки.
>
> Таким образом в случае необходимости переопределить отладочную
> информацию, это можно сделать через аргумент командной строки, например:
> %rust_build --config 'profile.%rust_build_profile.debug = false'
>
> Либо же можно переопределить новый макрос %rust_debug_level, который
> синхронизирует отладочную информацию между всеми стадиями сборки.
>
>
> Появилась возможность задавать некоторые опции компиляции
> через макросы.
>
> Иногда при сборке пакета очень хочется выставить больше (или меньше)
> оптимизаций, чем выставил апстрим. Раньше для этого требовалось
> дописывать/писать собственный config.toml/привлекать дополнительные
> инструменты, что не очень хорошо сочетается с автоматизацией. Поэтому
> для глобального указания некоторых опций компиляции были добавлены:
> # https://doc.rust-lang.org/cargo/reference/profiles.html#codegen-units
> # https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units
> %rust_codegen_units - Задаёт насколько сильно будет раздроблен пакет
> на бинарные единицы при сборке. Чем меньше - тем лучше будет
> оптимизировано приложение, но тем прожорливее будет сборка и LTO
> оптимизации.
>
> # https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level
> %rust_opt_level - Уровень оптимизаций.
>
> # https://doc.rust-lang.org/cargo/reference/profiles.html#lto
> %rust_lto - уровень LTO оптимизаций. Для Rust пакетов одна из самых
> мощных и капризных оптимизаций, поскольку она снимает ограничение на
> inline оптимизации между различными модулями и внешними зависимостями.
>
> В отличие от RUSTFLAGS данные макросы используют штатные механизмы Cargo.
>
>
> Были добавлены макросы для сборки пакетов с rust-cargo-c
>
> Команды из rust-cargo-c используют тот же интерфейс для вызова, что и
> обычные cargo build/cargo install/cargo test с добавлением аргументов
> путей ассоциированных с C-библиотеками.
>
> Если апстрим позаботился о добавлении возможности "-F capi", они
> позволяют легко и просто собирать разделяемые библиотеки с
> C-интерфейсом, вместе всеми необходимыми флагами компиляции,
> заголовками, библиотеками и тд.
>
> Аналогично %rust_build, %rust_install и %rust_test новые макросы имеют
> названия: %rust_cbuild, %rust_cinstall, %rust_ctest.
>
>
> Все команды сборки теперь имеют флаг --frozen вместо --offline.
>
> Раньше при сборке пакетов Cargo мог решить обновить зависимости на
> основании содержимого vendor/, обычно это происходит при изменении
> путей в Cargo.toml, при вызове cargo install или при отсутсвии
> некоторых зависимостей.
>
> Именно поэтому, даже при одинаковых флагах компиляции, Сargo
> перезапускал сборку при вызове cargo install.
>
> Если исходить из смысла секций RPM пакета, то все зависимости должны
> быть зафиксированны до %prep или в случае вендоринга в %prep, но точно
> не на стадии сборки или установки артефактов. Поэтому логичным
> решением будет запретить Cargo менять Cargo.lock.
>
> Для это Cargo можо передать опцию --locked или --frozen (--locked +
> --offline).
>
> Полагаю, что некоторые пакеты могут перестать собираться. Это может
> означать, что вендоринг был выполнен с ошибкой и по какой-то причине
> не все зависимости попали в vendor/. Самым простым решением данной
> проблемы является регенерация Cargo.lock через cargo generate-lockfile.
>
>
> %rust_prep добавляет пустую строку перед записью в config.toml.
>
> Некоторые апстримы не имеют пустой строки в конце config.toml, что
> приводило к накладыванию названия таблицы на существующие строки.
>
>
> Зависимость на rust-cargo была заменена зависимостью на rust.
>
> Cargo может работать с любой версией компилятора, поэтому для
> установки всех пакетов необходимых для сборки Rust пакета она является
> неудачной, поскольку не задаёт однозначного соотвествия. В будущем
> планируется убрать зависимость cargo на идентичную версию rustc.
>
>
> Нерешённые вопросы.
>
> 1. Должен ли %rust_prep поддерживать переопределение директории
> vendor/? Теоритически она может быть переопределена, но я не видел
> практического использования данной возможности.
> 2. Должен ли %rust_prep высчитывать корень сборочной директории при
> вендоринге зависимости в поддереве для формирования префикса
> архива. Как это правильно сделать? В текущей реализации %rust_prep
> считает корнем сборочной директории путь, в котором он был вызван,
> что в общем случае неверно. Я хотел использовать какой-нибудь
> специальный макрос, но не нашёл такого.
> 3. Должен ли %rust_prep выставлять хоть какие-то флаги компиляции?
> Должны ли быть значения по умолчанию для макросов задающих опции
> компиляции?
> 4. Должен ли %rust_install с появлением полной синхронизации между
> %build и %install перейти на cargo install? %rust_install и cargo
> install имеют несовместимые интерфейсы вызова. Стоит ли в таком
> случае добавить макросы %cargo_build, %cargo_install и т.д.?
> 5. Должен ли %rust_build_dir безусловно вычислятся для текущего пути?
> 6. В текущей реализации макросов нет механизма который бы позволял
> легко и просто изменять уже существующую конфигурацию. Стоит ли
> добавить зависимость на внешние toml конфигураторы или стоит
> написать собственный конфигуратор? Сейчас стоит очень большая
> проблема, что всё содержимое config.toml дописывается в конец, что
> не позволяет перезаписать уже существующие значения, например если
> апстрим переопределит компилятор по умолчанию кросскомпилятором
> для aarch64.
> 7. Стоит ли добавлять в rpm-build-rust зависимость на rust-cargo-c
> или оставить выбор за пользователем?
> 8. Должен ли вендоринг сохранять Cargo.lock?
> 9. Должен ли %rust_prep регенерировать Cargo.lock?
>
>
> _______________________________________________
> Devel mailing list
> Devel на lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/devel
--
*Данил Шеин / Danil Shein*
dshein на altlinux.org
dshein на basealt.ru
----------- следующая часть -----------
Вложение в формате HTML было удалено...
URL: <http://lists.altlinux.org/pipermail/devel/attachments/20260917/57a8a58b/attachment-0001.html>
Подробная информация о списке рассылки Devel