[devel] Расширение функциональности rpm-build-rust
Rx
rx1513 на altlinux.org
Ср Сен 16 21:06:57 MSK 2026
16.09.2026 17:02, Artyom Singyuin пишет:
> Привет,
>
> Попробую высказать свои мысли на этот счёт.
>
> 1. Очень важно, чтобы обновление rpm-build-rust сопровождалось
> обновлением https://www.altlinux.org/RPM/Rust
Безусловно!
> 2. Наиважнейшая задача обновления rpm-build-rust состоит в обратной
> совместимости для пакетов, которые собираются с помощью rpm-build-rust.
> Например, в предлагаемых изменениях из %rust_build убран RUSTFLAGS.
> Считаю, что это делать ни в коем случае нельзя, и вот почему:
> - RUSTFLAGS имеет приоритет над .cargo/config.toml и в 100% случаев
> отменяет для всех существующих пакетов .cargo/config.toml.Если просто
> взять и убрать, то внезапно огромное количество пакетов наша
> сборочница будет пересобирать с незапланированными мейтейнерами
> флагами. Мы с @obirvalger это уже обсуждали и вывод был примерно
> таким: "90 % того, что разработчики прописывают в RUSTFLAGS похоже на
> чрезмерные заморочки, которые можно отменить".
Например?
Мне кажется неправильным безусловно выкидывать RUSTFLAGS, прописанные
апстримом. Если апстрим заморочился над написанием данных флагов, значит
у него была какая-то проблема, которую он таким образом решил. Но что за
проблема?
Если апстрим ввиду неопытности хотел таким образом хотел
сконфигурировать Cargo, то да, такие флаги скорее всего не нужны. В
таком случае если апстрим ещё жив, то ему стоит указать на это, если нет
то исправить это самостоятельно.
Если же апстрим таким образом решал конретную задачу, которую другим
способом не решить, то это откровенно вредит сборке. Конкретно в lore
<packages.altlinux.org/ru/sisyphus/srpms/lore/specfiles/> макросы не
были использованы как раз по этой причине.
Я попробую пересобрать все зависимые пакеты с новыми макросами, но
оценка в 90% кажется мне завышенной.
> Но я даже не спорю, что, возможно, RUSTFLAGS надо из макросов
> убирать, но только не из текущих, а обязательно надо делать это в
> новых, намример, каком-нибудь %rust_build_no_flags
Я бы на самом деле заменил бы приставку rust- на cargo-. При должном
желании Rust пакеты могут быть собраны другими системами сборки.
Понятно, что де-факто Cargo - главная система сборки, но она не является
единственной. Если я правильно помню апстрим Cargo регулярно сслылается
на альтернативные системы сборки при разработке нового функционала.
> 3. Не очень понимаю, где оправдан вендоринг
> https://packages.altlinux.org/ru/sisyphus/srpms/glycin-2/specfiles/ -
> буду благодарен за пояснения, зачем нужно так усложнять.
Не понимаю в чём заключается усложнение. Алгоритм максимально прост:
Если активирован rust_vendoring - игнорируем старый вендор и вендорим
по-новой, сохраняя архив и источники.
Если rust_vendoring отключен - используем архив и восстанавливаем источники.
Главное приемущество такого подхода в том, что в будущем для таких
пакетовможно будет незаметно отключить механизм вендоринга и заменить на
обращение к внутреннему зеркалу или схожему механизму предоставления
зависимостей.
> 4. Хочется прокомментировать https://bugzilla.altlinux.org/48459,
> <https://bugzilla.altlinux.org/48459> где обсуждалось, как сделать
> проще вендоризацию. Вообще сейчас достаточно изучить инструмент zoryn
> + хуки, с помощью которых можно сделать вендоризацию максимально
> простой для мейнтейнера. И здесь большей проблемой кажется желание
> мейнтейнеров знакомиться с новыми инструментами, нежели с недостатком
> инструментов.
Инструментов как раз очень много и очень простых. Я лично для вендоринга
пользовался схемой podman + собственной автоматикой. Но я знаю много
кто, особенно из начинающих мейнтейнеров, вендорит на хостовой системе,
что немного неправильно хотя бы из соображений безопасности.
> инструмент zoryn + хуки
Из личных убеждений я не доверяю коду неизвестного происхождения.
> 5. Пока не забыл - вендоринг вроде как должен добавлять Cargo.lock. Я
> уже не помню, но когда-то у меня были какие-то связанные с этим проблемы.
Понял, учту. Было бы славно посмотреть пример.
> В целом общее впечатление: текущие нововведения кажутся перегруженными,
Возможно для одного релиза многовато. Но основная суть была в том,
чтобы сделать макросы более дружелюбными для большего числа пакетов.
> когда читал, сложно было придумать, когда может понадобиться тот или
> иной инструмент.
Я не добавлял ничего что не могло быть применено в уже существующих
пакетах и в чём не возникало нужды.
Пути в %rust_prep - cargo-auditable
<https://packages.altlinux.org/ru/sisyphus/srpms/cargo-auditable/specfiles/> и
некоторые пакеты @aris.
Профили - uutils-coreutils
<https://packages.altlinux.org/ru/sisyphus/srpms/uutils-coreutils/specfiles/>
до 0.8 имел два профиля вместо release, lore
<https://packages.altlinux.org/ru/sisyphus/srpms/lore/specfiles/>.
Конфигурация компиляции через макросы убирает костыли вокруг config.toml
и %rust_build. И наверное это главная причина почему я не использовал
%rust_prep.
rust-cargo-c - должен быть во всех пакетах, которые его поддерживают,
ибо это единственно верный инструмент для сборки разделяемых библиотек c
С-интрефейсом для таких пакетов.
--locked - "защита от дурака" и неожиданных эффектов.
> В 90 % случаев текущих инструментов, на мой взгляд, достаточно, а
> создавать макросы для единичных случаев не кажется правильным.
А должно быть 99.5%.
Чем больше пакетов будет использовать макросы, - тем проще будет вносить
в них какие-то важные изменения и тем меньше пакетов имеют риск быть
собраны абы как.
> Также, на мой взгляд, сейчас rust-сборка максимально дружелюбная для
> всех, кто ознакомился с инструкциями https://www.altlinux.org/RPM/Rust -
И тем не менее периодически я нахожу очевидные проблемы в некоторых
чужих пакетах.
> я боюсь, нововведения усложняют понимание для новых мейнтейнеров,
> осложняя жизнь. ИМХО.
По-хорошему существующую статью стоит отрефакторить и разделить две части:
То что нужно знать новичку.
То что нужно знать новичку если что-то из первой главы не сработало.
Либо банально две статьи написать.
На счёт осложнения я честно не знаю, ибо основной принцип работы остался
неизменными, разве что появилось больше гибкости.
В любом случае с политикой
<https://docs.fedoraproject.org/en-US/packaging-guidelines/Rust/> сборки
Rust проектов в Fedorа это не сравнится. Если люди это как-то осилили,
то пару новых макросов точно осилят.
> Резюмируя, сейчас кажется большей проблемой не недостаток в
> инструментах, а в следующих моментах:
> 1. Нет чётких политик, что-как-куда вендорить на Wiki.
Согласен. Но вот вопрос, а как правильно?
Я считаю, что правильный вендоринг:
1. Должен выполнятся в изолировнной среде. hasher/podman/qemu и т.д.
Бог знает какие уязвимости при вендоринге могут привести к утечке
ключей и конфенденциальной информации.
2. Если возможно, то должен выполнятся для Sisyphus, иначе для целевой
ветки.
Чем свежее используемый Cargo и cargo-vendor-filterer тем меньше
риска подхватить потенциальные уязвимости.
3. Должен генерировать настолько компактные артефакты насколько это
возможно. В идеале, если возможно использовать cargo-vendor-alt.
Далеко нередкое явление когда даже самый маленький пакет тянет
зависимостей на +200мб больше размера самого пакета.
4. Должен быть автоматизирован.
Если мы хотим избавится от вендоринга, должен механизм полностью
убрать его из сборки и заменить альтернативным механизмом.
5. Должен быть явно связан с пакетом.
Другие мейнтейнеры должны иметь возможность воспроизвести результаты
вендоринга вне зависимости от использованного способа.
Бонусом можно было бы добавить: "не вендорить, то что есть в
репозитории", но тут пока нет какой-то явной стратегии. Ну и пару
технических деталей.
> Может быть, нужно сначала разобраться с документацией и политиками, а
> потом менять rpm-build-rust
Чтобы разобраться с политиками и документацией нужно для начала выделить
явные проблемы. Для rpm-build-rust у меня есть такой список, для
вменяемой политики, - пока нет.
> В Вт, 15/09/2026 в 15:55 +0300, 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
>
>
> _______________________________________________
> Devel mailing list
> Devel на lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/devel
----------- следующая часть -----------
Вложение в формате HTML было удалено...
URL: <http://lists.altlinux.org/pipermail/devel/attachments/20260916/c9a0556c/attachment-0001.html>
Подробная информация о списке рассылки Devel