[devel] Расширение функциональности rpm-build-rust
Rx
rx1513 на altlinux.org
Пт Сен 18 15:06:15 MSK 2026
7.09.2026 14:01, Danil Shein пишет:
>
> Добрый день!
>
> Комментарий ниже не относится к модификации макросов для сборки
> проектов на Раст: данные изменения выглядят вполне обоснованными на
> мой взгляд.
>
> Вот тут обсуждаются всякие подходы к тому, чтобы втащить в сизиф кучу
> крэйтов раста как системные зависимости для "контроля и учёта" и
> вообще всеобщего блага.
>
> Идея как будто бы понятная и даже имеющая под собой какое-то обоснование.
>
> У меня несколько чисто практических вопросов больше с точки зрения
> разработчика на Раст:
>
> 1. Как быть с тем что в рамках одного проекта у вас может завендорится
> сразу несколько несовместимых версий одного и того же крэйта и это
> вообще абсолютно нормально для экосистемы Раст? Насколько я помню
> репозиторий такие сценарии поддерживает чуть более чем никак.
>
> 2. Что буде собой представлять упакеченный крэйт который нужен другим
> проектам исключительно в виде исходного кода без возможности
> предварительной компиляции в какие либо артефакты? Просто тарбол с
> сорцами?
>
> 3. Как вы себе представляете использование таких упакеченных крэйтов в
> апстримных проектах? Вот прям как именно в вашем понимании будет это
> выглядеть на практике? Километровые патчи в Cargo.toml и борьба с тем
> что локальные крэйты приезжают только с абсолютными путями не говоря
> уже о других сложностях?
>
Fedora уже очень давно ответила на эти вопросы.
Они обернули функционал Cargo в кучу RPM макросов и обёрток.
В качестве содержимого пакетов у них выступают тарболы c расширением
.crate, производимые cargo package, и метаданные для разрешения
зависимостей.
> Километровые патчи в Cargo.toml и борьба с тем что локальные крэйты
> приезжают только с абсолютными путями не говоря уже о других сложностях?
>
Не совсем понимаю о чём речь. Можно поподробнее?
> Ну и если всё вышеуказанное легко решаемо, то кто будет сопровождать
> все эти зависимости и как?
>
Вот это наверное один из главных вопросов. Если действительно взяться за
упаковку растовских крейтов, то по скромным меркам придётся тянуть две
тысячи пакетов, не включая различные вариации версий. Мне тяжело
представить человека который будет настолько мотивирован сборкой Rust
пакетов, чтобы следить за актуальностью каждого.
Без автоматизированного решения это огромная растрата человеческого времени.
> Мне кажется мы уже достаточно ходили по этим граблям с другими
> языками, и если для интерпретируемых языков подход с втаскиванием всех
> зависимостей в репозиторий ещё как-то работает, то для Раст и например
> Го альтернативы вендорингу я лично не вижу вообще.
>
Я очень давно думаю над решением этой проблемы ибо мне не нравится, что
во многих Rust пакетах, тухнут зависимости потенциально содержащие
уязвимости; не нравится что в случае возникновения уязвимости ты никак
не сможешь исправить её для всех пакетов; не нравится что многие -sys
крейты тащат с собой бинари неизвестного происхождения; не нравится что
многие пакеты дублируют зависимости друг друга, занимая лишнее место.
Главное преимущество вендоринга - простота сборки и реализации, но не более.
Можно создать на базе сборочницы зеркало по запросу и далее монтировать
это зеркало внутрь hasher.
Например, мейнтейнер при отправке Rust-пакета может создать на
сборочнице запрос на синхронизацию зависимостей с crates.io. Эти
зависимости попадают в таск; если таск проходит успешно и существующие
патчи корректно применяются к новым версиям зависимостей, то они
вливаются в основное зеркало.
Как конкретно это должно работать ещё предстоит подумать, но в любом
случае это вопрос желания и времени. Fedora уже реализовала подход с
noarch пакетами ещё 7 лет назад, поэтому вопрос о том, можно ли
избавиться от вендоринга, должен быть закрыт.
Сейчас в первую очередь стоит чётко ответить на следующие вопросы:
Что мы хотим?
Как это реализовать?
Кто готов это реализовать и поддерживать?
После этого уже можно закрыть обсуждение вендоринга раз и навсегда.
> Надеюсь мои комментарии дадут некоторую пищу для ума участникам
> сообщества и позволят выработать правильный подход к упакечиванию
> проктов на Расте.
>
> 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
>
> _______________________________________________
> Devel mailing list
> Devel на lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/devel
----------- следующая часть -----------
Вложение в формате HTML было удалено...
URL: <http://lists.altlinux.org/pipermail/devel/attachments/20260918/574f128a/attachment-0001.html>
Подробная информация о списке рассылки Devel