[devel] Расширение функциональности rpm-build-rust

Artyom Singyuin writers на altlinux.org
Ср Сен 16 17:02:44 MSK 2026


Привет,  

Попробую высказать свои мысли на этот счёт. 

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 надо из макросов убирать, но только не из текущих, а
обязательно надо делать это в новых, намример, каком-нибудь
%rust_build_no_flags
3. Не очень понимаю, где оправдан
вендоринг https://packages.altlinux.org/ru/sisyphus/srpms/glycin-2/specfiles/
 - буду благодарен за пояснения, зачем нужно так усложнять. 
4. Хочется прокомментировать https://bugzilla.altlinux.org/48459,
[1] где обсуждалось, как сделать проще вендоризацию. Вообще сейчас
достаточно изучить инструмент zoryn + хуки, с помощью которых можно
сделать вендоризацию максимально простой для мейнтейнера. И здесь
большей проблемой кажется желание мейнтейнеров знакомиться с новыми
инструментами, нежели с недостатком инструментов. 
5. Пока не забыл - вендоринг вроде как должен добавлять Cargo.lock. Я
уже не помню, но когда-то у меня были какие-то связанные с этим
проблемы. 

В целом общее впечатление: текущие нововведения кажутся перегруженными,
когда читал, сложно было придумать, когда может понадобиться тот или
иной инструмент. В 90 % случаев текущих инструментов, на мой взгляд,
достаточно, а  создавать макросы для единичных случаев не кажется
правильным. 

Также, на мой взгляд, сейчас rust-сборка максимально дружелюбная для
всех, кто ознакомился с
инструкциями https://www.altlinux.org/RPM/Rust - я боюсь, нововведения
усложняют понимание для новых мейнтейнеров, осложняя жизнь. ИМХО. 

Резюмируя, сейчас кажется большей проблемой не недостаток в
инструментах, а в следующих моментах:
1. Нет чётких политик, что-как-куда вендорить на Wiki. 
2. Не хватает инструкций по некоторым передовым практикам на Wiki,
например, по использованию zoryn для пакетов c Rust, по "правильному"
вендорингу, для которого хорошо бы ещё написать и согласовать
политику. 

Может быть, нужно сначала разобраться с документацией и политиками, а
потом менять rpm-build-rust

В Вт, 15/09/2026 в 15:55 +0300, Rx пишет:
>  
> Привет! 
>  
> Недавно нашёл время решить проблемы с которыми сталкивался лично
> и слышал от других мейнтейнеров при использовании макросов из rpm-
> build-rust.
>  
> Поскольку часть изменений может вызвать споры и непредвиденные
> побочные эффекты, считаю что стоит поднять обсуждение по возможным
> доработкам.
>  
> https://packages.altlinux.org/ru/tasks/431040/
>  
> Использованные термины 
> Пакет (ориг. package [2]) - набор исходных файлов с
> манифестом Cargo.toml [3], описывающим метаданные для сборки пакета.
>  
> Cargo [4] - пакетный менеджер / система сборки нацеленная на пакеты
> на языке программирования Rust.
>  
>  
> Рабочее пространство (ориг. workspace [5]) - набор пакетов, связанных
> единым манифестом и зависимостями.
>  
> Были добавлены аргументы путей для %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-файла [6]), я
> решил реализовать данный механизм при помощи макросов и интегрировать
> его в %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


[1] https://bugzilla.altlinux.org/48459,
    https://bugzilla.altlinux.org/48459
[2] package
    https://doc.rust-lang.org/cargo/appendix/glossary.html#package
[3] Cargo.toml https://doc.rust-lang.org/cargo/reference/manifest.html
[4] Cargo
    https://doc.rust-lang.org/cargo/guide/why-cargo-exists.html#enter-cargo
[5] workspace
    https://doc.rust-lang.org/cargo/reference/workspaces.html#workspaces
[6] spec-файла
    https://packages.altlinux.org/ru/sisyphus/srpms/glycin-2/specfiles/
----------- следующая часть -----------
Вложение в формате HTML было удалено...
URL: <http://lists.altlinux.org/pipermail/devel/attachments/20260916/d38ed765/attachment-0001.html>


Подробная информация о списке рассылки Devel