[devel] Расширение функциональности rpm-build-rust
Rx
rx1513 на altlinux.org
Ср Окт 28 10:27:54 MSK 2026
По результатам пересборки пакетов картина следующая:
Из 432 пакетов упало 29:
phrog aris - Пакет использует устаревший макрос %__cargo. Исправление:
phrog-0.53.0-alt2.src.rpm
<https://git.altlinux.org/tasks/431040/gears/70400/phrog-0.53.0-alt2.src.rpm>
prek dmaks @everybody - Сборка проходила без отладочной информации.
Её включение вызвало чрезмерное использование памяти на ix86.
Исправление: отключение отладочной информации на ix86
<https://git.altlinux.org/gitoskop/#/tasks/431040/gears/75370/git/-/commit/d2ac6cb56462865525aae491e792b4e904b65fff>.
cosmic-applibrary aris - Сборка тестов проходила без отладочной
информации. Её включение вызвало ошибку компиляции в одной из
завендоренных библиотек. Отключение отладочной информации чинит сборку,
но как таковых тестов у пакета нет:
> [00:01:07] + cargo test --release -j32 --no-fail-fast
> [00:01:08] Compiling cosmic-app-library v1.11.0 (/usr/src/RPM/BUILD/cosmic-app-library-epoch-1.11.0)
> [00:01:12] Finished `release` profile [optimized] target(s) in 4.79s
> [00:01:12] Running unittests src/main.rs (target/release/deps/cosmic_app_library-cc2bbb419a3f8485)
> [00:01:12]
> [00:01:12] running 0 tests
influxdb3 amakeenk @everybody - Из-за отказа от RUSTFLAGS сборка
перестала игнорировать флаги, задававшие lld в качестве компоновщика и
параметры для его корректной работы. Кроме того, из-за включения
механизма синхронизации флагов между стадиями сборка %check падала
из-за нехватки памяти. Исправление: установка отсутствующего lld и смена
глобального уровня отладочной информации
<https://git.altlinux.org/gitoskop/#/tasks/431040/gears/75300/git/-/commit/67d521cf910cf892387ca8030dd2198485dffcf3>.
ouch amakeenk @everybody - Прямая конфигурация отладочной информации
через `--config` заставила Cargo выставить переменную среды DEBUG,
благодаря которой отладочная информация стала генерироваться и для кода
на C++. Падение сборки вызвано внутренней ошибкой gcc-15 на i586.
Исправление: сборка через clang
<https://git.altlinux.org/gitoskop/#/tasks/431040/gears/75360/git/-/commit/f3c0b54eb1a371d6585fa5f8a909f1b62e1ba832>;
в качестве альтернативы можно отключить генерацию отладочной информации
на ix86.
Просьба к мейнтейнерам пакетов, для которых подготовлены исправления
выразить явное согласие: 431040
<https://packages.altlinux.org/ru/tasks/431040/>
Следующие пакеты упали из-за включения --frozen:
casr kuznetsovam @everybody
clevis-pin-tpm2 lvol @everybody
countryfetch srebrov @everybody
droid-juicer neko savoptik
dualsense-tools minergenon @everybody
handy ulysses @everybody
kryoptic slev @everybody
jsonschema-rs enimalojd @everybody
rot8 minergenon @everybody
seaweedfs enimalojd @everybody
swaptop zerospirit @everybody
television amakeenk @everybody
tgt-client sirius @everybody
volt-gui minergenon @everybody
thoth minergenon @everybody
vopono nicourced @everybody
websocat serjigva @everybody
xr-picker minergenon @everybody
cosmic-minimon-applet aris
cosmic-applets aris
cosmic-viewer aris
scope-tui joycap savoptik
thoth minergenon @everybody
treefetch fiersik @everybody
vault-tasks fiersik @everybody
Падение сборки для этих пакетов означает, что:
1. Cargo не смог создать идентичный Cargo.lock из существующего Cargo.toml.
2. Завендоренные зависимости не удовлетворяют сгенерированному Cargo.lock.
Например, в репозитории есть Cargo.lock, но апстрим его не обновляет. В
одном из пакетов видел ситуацию, когда мейнтейнер устанавливает
Cargo.lock, но Cargo его отбрасывает.
Обычно исправление сборки таких пакетов простое: делать вендоринг после
%prep, сгенерированный Cargo.lock устанавливать в сборочную директорию в
секции %prep либо, если используется %rust_prep, - внутрь архива с vendor/.
Однако для некоторых пакетов такое исправление не является достаточным.
Например если апстрим вендорит некоторые зависимости внутрь vendor/,
cargo-vendor-alt отказывается работать с такой директорией, перенос
зависимостей требует изменений Cargo.toml, что, в свою очередь, влечёт
за собой несоответствие Cargo.toml и Cargo.lock.
Отсутствие фиксированного Cargo.lock говорит о том, что нельзя из
заданного Cargo.toml и списка завендоренных зависимостей создать
однозначное соответствие зависимостей, по которому можно воспроизвести
идентичную сборку в любой среде.
В дополнение к этому теряется гарантия отсутствия пересборки пакета на
последующих стадиях после %build.
Тем не менее, ввиду того, что добавление --frozen влечёт заметное
усложнение сборки на фоне малозаметных преимуществ, было решено отложить
внедрение до востребования.
По поводу отказа от безусловной установки RUSTFLAGS.
Сканирование применения апстримами rustflags показало следующую статистику:
Из 632 пакетов только в 183 апстрим упоминает rustflags напрямую либо
косвенно.
Среди всех пакетов, зависящих от rust и rpm-build-rust, апстрим чаще
всего выставляет флаги для статического связывания с musl libc
(rustflags = ["-C", "target-feature=+crt-static"], 34%).
Вторым по распространённости являются флаги изменения агрессивности
линтера (11%).
Третьим по распространённости флагом является изменение cfg (11%).
Очень часто апстрим выставляет rustflags таким образом, что случайно их
перезаписать не получится. Нужно либо патчить сборочные скрипты, либо
выставлять CARGO_ENCODED_RUSTFLAGS.
Ручная фильтрация показала, что из 183 пакетов только в 44 выставленные
RUSTFLAGS могут повляить на апстримные флаги.
Из этих 44 пакетов только 18 используют макросы из rpm-build-rust. Из 18
пакетов 2 пакета выставляют собственные RUSTFLAGS.
Из оставшихся 16 пакетов выставление RUSTFLAGS влечёт либо негативные,
либо неопределимые эффекты, в частности:
8 пакетов потеряли cfg
6 пакетов потеряли флаги оптимизации размера/производительности/скорости
сборки/отладочной информации
2 пакета потеряло LLVM-only сборку.
1 пакет потерял разрешение сборки с определённым предупреждениями.
Кроме того, в ~30-40 пакетах оптимизации, выставляемые мейнтейнером
через rustflags в config.toml, полностью игнорировались.
Поэтому считаю, что полный отказ от выставления RUSTFLAGS более чем
целесообразен.
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?
>
----------- следующая часть -----------
Вложение в формате HTML было удалено...
URL: <http://lists.altlinux.org/pipermail/devel/attachments/20261028/7fe1be39/attachment-0001.html>
Подробная информация о списке рассылки Devel