Привет! Я очень давно планировал упаковать uutils-coreutils, но долго боролся за возможность использовать его вместо gnu coreutils. Но похоже меня определи. Поэтому поделюсь некоторыми замечаниями по сборке пакета: 1: BuildRequires: rust BuildRequires: rust-cargo Для сборки Rust пакетов есть rpm-build-rust, который устанавливает базовые зависимости и вспомогательные макросы. Конечно никто не запрещает вручную собирать, но тогда при глобальных изменениях в сборке Rust пакетов, а они я надеюсь произойдут, их придётся адаптировать самостоятельно. 2: Зависимость rust-cargo лишняя. Если нужно установить rustc и cargo стоит ставить либо rpm-build-rust либо просто rust либо если есть потребность установить только их, то зависимость стоит выставлять как rustc и rust-cargo. Исторически так сложилось, что rust-cargo это пакет который ставит rustc (aka rust) и некоторые недобросовестные мейнтейнеры указывают её для установки как cargo так и rustc, но такая зависимость является ошибочной, так как она прибивает пакетный менеджер cargo к конкретной версии компилятора rustc, что аналогично тому, если бы cmake устанавливал конкретную версию gcc или clang. К чему это? Это к тому, что вручную указывать зависимость на cargo не стоит. Я подниму обсуждение по этой теме когда у меня будет достаточно времени, но это произойдёт нескоро. 3: Patch0: debian-fix-locale-path.patch Зачем понадобился патч для изменения путей локалей? 4: rustflags = ["-Copt-level=3", "-Cdebuginfo=1"] Так делать не стоит. Я знаю, что это пример из вики, но его нужно исправить. Аргументация следующая: rustflags - низкоуровневая переменная передаваемая напрямую компилятору в обход каких-либо проверок со стороны cargo и у неё есть очень неприятные побочные эффекты. Она не умеет объединятся с rustflags из других уровней конфигурации. Если разработчики указали важные флаги, которые необходимы при сборке, они будут полностью перезаписаны. Не всегда это справедливо, но лучше этого избегать. У cargo есть более тонкий механизм настройки для указания уровня оптимизаций и отладочной информации, при помощи debug и opt-level, пример: [profile.release] strip = false opt-level = 3 debug = 2 lto = true codegen-units = 1 Указание rustflags обходит этот механизм, что может привести к неожиданному поведению. 5: -Cdebuginfo=1 Зачем указывать неполную отладочную информацию? 6: %ifarch aarch64 sed -i 's/linker = "aarch64-linux-gnu-gcc"/linker = "aarch64-alt-linux-gcc"/' .cargo/config.toml %endif Для aarch64 лучше вырезать переопределение компановщика, оно здесь только для кросскомпиляции из x86_64. Привязывать к конкретному компановщику не стоит. 7: %make_build \ PROFILE=release \ %{?_enable_multicall:MULTICALL=y} \ %{?!_enable_selinux:SKIP_UTILS="runcon chcon"} Данные условия оформлены неправильно. При сборке _enable_<x> не определёны, из-за чего результат сборки получается прямо противоположный. Вместо единого бинаря получается набор отдельных утилит, вместо сборки Selinux утилит они отсуствуют. 8: Не хватает зависимости на clang-libs, о зависимости на libclang прямо написано в Readme проекта. 9: Об этом нигде не написано (GNUmakefile в помощь), но для сборки Selinux утилит, через make нужно указывать переменную SELINUX_ENABLED=1. 9: При генерации документации вылезает следующее предупреждение: [00:01:40] warning: coreutils@0.10.0: No tldr archive found, so the documentation will not include examples. [00:01:40] warning: coreutils@0.10.0: To include examples, download the tldr archive: [00:01:40] warning: coreutils@0.10.0: curl -L https://github.com/tldr-pages/tldr/releases/latest/download/tldr.zip -o docs/tldr.zip uutils-coreutils позволяет при сборке расширить документацию примерами команд, поэтому рекомендую завендорить этот архив. 10. При локальной отладке сборки проекта я заметил одну особенность: чем больше ядер выдаёшь на сборку, тем медленее и прожорливее идёт сборка. Казалось бы скорость должна расти, но вместо этого идёт деградация. У меня в системе 28 ядер, на сборочнице от 72 и больше. Поэтому рекомендую поставить ограничение на количество используемых потоков на сборку например так перед make_build: # High NPROCS results in insane slowdown. export NPROCS="$(($(nproc) < 16 ? $(nproc) : 16))" 11. Для такого пакета, слишком маленькое описание, брать summary некрасиво, ещё и точку не поставить. Касаемо организации сборочного репозитория: 1. Сборка только из тега это надёжный способ оставлять исходники чистыми, но она очень плохо сочетается с потребностью просмотреть эти исходники. При сборке, проверке и исправлении исходников, часто возникает потребность просмотреть исходники, проблема в том, что при сборке из тега приходится делать очень неприятную последовательность действий: git add . && git stash && git checkout && git stash pop && git restore или всё мерджить или выполнять команды с которыми человек работающий с гитом выполняет пару раз за свою карьеру, а ещё очень неудобно просматривать исходники из браузера. Я рекомендую подгружать исходники тега в отдельную папку при помощи git subtree, либо вручную гитовыми командами либо при помощи отдельного пакета. Пример "git subtree add --prefix=uutils-coreutils upstream 0.10.0". Принуждать к такой схеме упаковки я не могу, но мне было очень неприятно изучать исходники. 2. Не понял что означает почему релизный тег имеет приставку uutils-coreutils-, в апстриме никаких приставок нет. 3. .gear/update-vendor - классическое замечание рецензентов: .gear предназначен для служебных файлов gear, помещать туда собственные файлы не стоит. Я к этому отношусь нейтрально, но на будущее совет. 4. .gear/update-vendor: "pushd "$REPO_ROOT" > /dev/null" - "когда произойдёт восстание машин, оно произойдёт бессшумно, ты поймёшь что всё это время ты заблуждался, но только когда будет слишком поздно". 4.1. Вендорить на хостовой системе не стоит: из соображений безопасности, в связи с тем, что завендоренные зависимости могут отличаться в зависимости от версии cargo и rustc и в связи с тем что если не занимаешься разработкой на Rust, то тебе не нужны лишние 200 мб в системе. Есть 3 схемы вендоринга которые позволяют избежать этих проблем: Через OCI контейнер, через виртуалку и через hasher. 4.2 Для создания временных директорий есть отдельная команда, поручать нейронке ручное удаление директорий в системе я бы не стал. Знакомые люди на этом очень неприятно прогорели потеряв важные личные данные с последующим неприятным восстановлением системы. Пример моих наработок можно посмотреть по: http://git.altlinux.org/people/rx1513/packages/?p=uutils-coreutils.git&a=tree Там далеко не всё прекрасно как хотелось бы, но для контекста замечаний думаю хватит.
Добрый день. Спасибо за разбор. Углублюсь чуть позже и дам вам ответ. То, что нужно/можно исправить на вики - обсудим с вами и исправим, т.к. устаревшие инструкции на вики меня постоянно преследуют) О возможности использовать вместо утилит GNU - попробую реализовать, но не хотел это делать сразу в первом релизе. Меня это тоже интересует, хотя и понимаю, что что-то может сломаться и использовать повседневно, наверное, не получится.
(Ответ для Корытов Иван на комментарий #1) > О возможности использовать вместо утилит GNU - попробую реализовать, но не > хотел это делать сразу в первом релизе. Меня это тоже интересует, хотя и > понимаю, что что-то может сломаться и использовать повседневно, наверное, не > получится. Проблема в кривом графе зависимостей, который позволяет сделать полную замену coreutils пакета на хостовой системе, но не позволяет сделать это в hasher. Надо будет обсуждать это с мейнтейнерами gnu coreutils, я думаю...
1. Изначально (год назад), я не стал использовать макросы для сброки, т.к. %rust_build или %rust_test, ЕМНИП, делали что-то не так для конкретно этого проекта. Соответствено, был использован ручной способ сборки. За год могло произойти много изменений, поэтому я попробую использовать их заново. 2. rust-cargo был указан в примере. О таких последствиях с зависимостями не знал, исправить недолго. https://www.altlinux.org/RPM/Rust 3. Стандартная директория /usr/share/locales, используемая в проекте, больше никем в Сизифе не используется. т.е. этот путь не общий, а содержит файлы только одной программы. Также, ее название на одну букву отличается от /usr/share/locale, которая содержит другой формат файлов с переводами. И так как нашлись люди которых это тоже смутило, то и был использован готовый патч (с небольшими изменениям). 4. Учту на будущее, если что-то буду собирать на Rust. Опять же, пример из вики - ровно то, что я и использовал, т.к. для меня это первый проект/программа на Rust. 5. Вы угадали - вики. Для меня это выглядит как рекомендация чтобы на выходе можно было получить пакет с debuginfo. Если перейти на макросы для сборки, то этот вопрос автоматически закроется. 6. Да, согласен. Наверное, решил по старой памяти прибить гвоздями как при бутстрапе системы. 7. Проверил в hasher работу условий - все резловится корректно. Multicall собирается, но вместе с ним собираются и устанавливаются отдельные бинарники. Этого не должно происходить, надо разобраться. SELinux, скорее всего, не работает из-за пункта 9, а не из-за неверного условия. 8. Упустил, согласен. Привык к ругани CMake и autotools при отсутствии необходимых зависимостей при сборке. 9. Сделаю, без проблем. 10. Возможно, что из-за этого на сборочнице и падают время от времени тесты, да еще и разные тесты. Надо попробовать. У меня локально 16 ядер, поэтому все происходит достаточно стабильно и в меру быстро. 11. Этот комментарий должен был появиться чуть раньше и от человека с другой ролью) Дополню description, можно выцепить еще несколько предложений из README.md --- 1. > Принуждать к такой схеме упаковки я не могу, но мне было очень неприятно изучать исходники. Я постоянно занимаюсь выполнением этой гимнастики с другим проектом и для меня это привычно. Скорее вопрос в другом - для чего и кто это придумал в Альте и почему никто не запрещает это, если это многим не нравится. Даже если раньше не было других способов упаковки с сохранением истории, то сейчас время перейти на них. 2. Думал, что имена для хэшей апстримных тэгов в .gear/list могут быть произвольного формата. Если где-то указаны правила о сторогом соответствии - дайте знать. 3. Окей, перемещу в корень. 4. Срисовано с другого скрипта. Наверное, скрывать вывод не стоит. Но даже если рассмотреть вариант, что pushd выполнится с пустыми кавычками, то отреагировать и остановить скрипт через Ctrl+C вряд ли кто-то сможет и произойдут "unforeseen consequences". Тогда уж лучше проверить путь на то, что он не пуст или является директорией. 4.1 Тогда изменю скрипт на сборку через hasher. Он есть у всех, кто собирает пакеты. 4.2 > Для создания временных директорий есть отдельная команда, поручать нейронке ручное удаление директорий в системе я бы не стал. Причем здесь нейронка?) Может быть оригинальный скрипт и написан при помощи ее, но клонирование апстримного тэга во временную директорию - мое творчество, ибо при "merge -s ours" надо вытаскивать исходники наружу. Даже если я создам, например, директорию через mktemp, то удалять ее нужно тем же самым rm -rf. И если $TMP пустой, то без нее путь превращается в "/uu-coreutils". > Пример моих наработок можно посмотреть по: Вопрос: мне внести часть вашего spec в свой и отметить ваш вклад в changelog или же вы сами, как участник Team, придете и внесете их от своего имени? Я не хотел бы ситуации, чтобы эти наработки считались "стыреными".
(Ответ для Корытов Иван на комментарий #3) > 1. Изначально (год назад), я не стал использовать макросы для сброки, т.к. > %rust_build или %rust_test, Я имел ввиду %rust_prep, в данном проекте можно собирать всё и через Make макросы. > ЕМНИП, делали что-то не так для конкретно этого > проекта. Соответствено, был использован ручной способ сборки. Они не умеют работать с альтернативными профилями. Код назад апстрим использовал вместо release release-fast и release-small. Я сейчас работаю над исправлением этой > 2. rust-cargo был указан в примере. О таких последствиях с зависимостями не > знал, исправить недолго. > https://www.altlinux.org/RPM/Rust Поправил. > 3. Стандартная директория /usr/share/locales, используемая в проекте, больше > никем в Сизифе не используется. т.е. этот путь не общий, а содержит файлы > только одной программы. Также, ее название на одну букву отличается от > /usr/share/locale, которая содержит другой формат файлов с переводами. И так > как нашлись люди которых это тоже смутило, то и был использован готовый патч > (с небольшими изменениям). Действительно... Не заметил. > 4. Учту на будущее, если что-то буду собирать на Rust. Опять же, пример из > вики - ровно то, что я и использовал, т.к. для меня это первый > проект/программа на Rust. > > 5. Вы угадали - вики. Для меня это выглядит как рекомендация чтобы на выходе > можно было получить пакет с debuginfo. Если перейти на макросы для сборки, > то этот вопрос автоматически закроется. > Поправлю когда будет время. > 7. Проверил в hasher работу условий - все резловится корректно. > Multicall собирается, но вместе с ним собираются и устанавливаются отдельные > бинарники. Этого не должно происходить, надо разобраться. SELinux, скорее > всего, не работает из-за пункта 9, а не из-за неверного условия. > Вырезка из лога uutils 0.10.0: [00:00:03] + cd uutils-coreutils-0.10.0 [00:00:03] + make -j32 PROFILE=release [00:00:04] make: Entering directory '/usr/src/RPM/BUILD/uutils-coreutils-0.10.0' [00:00:04] Detected OS = x86_64-unknown-linux-gnu [00:00:04] make: Leaving directory '/usr/src/RPM/BUILD/uutils-coreutils-0.10.0' > 8. Упустил, согласен. Привык к ругани CMake и autotools при отсутствии > необходимых зависимостей при сборке. > Если я правильно помню, то тут используется pkgconfig. Он должен начать ругаться при добавлении сборки SELinux > 1. > > Принуждать к такой схеме упаковки я не могу, но мне было очень неприятно изучать исходники. > Я постоянно занимаюсь выполнением этой гимнастики с другим проектом и для > меня это привычно. > Скорее вопрос в другом - для чего и кто это придумал в Альте и почему никто > не запрещает это, если это многим не нравится. > Даже если раньше не было других способов упаковки с сохранением истории, то > сейчас время перейти на них. > https://bugzilla.altlinux.org/59716 https://lists.altlinux.org/pipermail/devel/2026-July/220052.html Обсуждения постоянно поднимаются, но реального фактора который скажет: так нельзя - нет. У каждого подхода есть свои плюсы и минусы и идеального решения пока не нашли. > 2. Думал, что имена для хэшей апстримных тэгов в .gear/list могут быть > произвольного формата. Если где-то указаны правила о сторогом соответствии - > дайте знать. > Вообще нет, просто я при обновлении использую gear-update-tag -ac, который автоматически именует тег так, как его именует апстрим. > 4. Срисовано с другого скрипта. Что за скрипт? > Наверное, скрывать вывод не стоит. Стоит только в том случае, если результат всегда гарантирован. Я заметил многие нейронки обожают скрывать любые ошибки и это одновременно и пугает и раздражает, потому что когда что-то идёт не так, решать в первую очередь тебе, а нейронка предварительно позаботилась о том что сам ты найдёшь причину только через трату времени на пустую работу. > 4.1 Тогда изменю скрипт на сборку через hasher. Он есть у всех, кто собирает > пакеты. > У меня нет. Что за скрипт? > 4.2 > > Для создания временных директорий есть отдельная команда, поручать нейронке ручное удаление директорий в системе я бы не стал. > Причем здесь нейронка?) Очевидные комментарии, игнорирование логов, это выдаёт стиль нейросети. > Может быть оригинальный скрипт и написан при помощи > ее, но клонирование апстримного тэга во временную директорию - мое > творчество, ибо при "merge -s ours" надо вытаскивать исходники наружу. Тогда извиняюсь. Очень много приходится ревьюить плохого сгенеренного кода. > Даже если я создам, например, директорию через mktemp, то удалять ее нужно > тем же самым rm -rf. > И если $TMP пустой, то без нее путь превращается в "/uu-coreutils". Можно создавать TMPDIR, если настроен tmpfs (а он обычно настроен при установке любых альтовых образов), то удалять самому ничего не придётся. https://www.altlinux.org/TmpDir > > Пример моих наработок можно посмотреть по: > Вопрос: мне внести часть вашего spec в свой и отметить ваш вклад в changelog > или же вы сами, как участник Team, придете и внесете их от своего имени? Я > не хотел бы ситуации, чтобы эти наработки считались "стыреными". Как хотите, мне главное что бы пакет был собран качественно.
(Ответ для Сергей Жидких на комментарий #4) > Я имел ввиду %rust_prep, в данном проекте можно собирать всё и через Make макросы. Да, %rust_prep добавлю, т.к. heredoc с конфигурацией выглядит так себе и, получается, еще и неверный. > Вырезка из лога uutils 0.10.0: Все верно. Multicall отключен по умолчанию, а утилиты SELinux не пропускаются (за минусом косяка с указанием их сборки через переменную окружения). > gear-update-tag -ac Точно, я опять забыл, что почти на все случаи есть какой-то инструмент. > Что за скрипт? Скрипт из пакета narcolepsyd, он использован за основу: https://git.altlinux.org/gears/n/narcolepsyd.git?p=narcolepsyd.git;a=blob;f=.gear/merge-up.d/01-cargo-vendor;h=68d0a6fb2d91cfe348afc9d9312b8a4888bea1bd;hb=0e59e54649714b92dded0373c8e25deba63a1d93 > У меня нет. Что за скрипт? Я про то, что скрипт update-vendor будет переделан на hasher, т.к. hasher (а не скрипт) должен быть у человека, который занимается сборкой пакетов. > Можно создавать TMPDIR, если настроен tmpfs (а он обычно настроен при установке любых альтовых образов), то удалять самому ничего не придётся. Он очищается при перезагрузке и хранится в ОЗУ. У меня аптайм до месяца бывает, поэтому не почистить за собой - как-то неправильно. Но, наверное, да, можно пропустить, т.к. это скорее исключение из правил. > Как хотите, мне главное что бы пакет был собран качественно. Понял, тогда упомяну в changelog и постараюсь на этой неделе закинуть новую таску с исправлением указанных замечаний.
(Ответ для Корытов Иван на комментарий #5) > (Ответ для Сергей Жидких на комментарий #4) > > У меня нет. Что за скрипт? > Я про то, что скрипт update-vendor будет переделан на hasher, т.к. hasher (а > не скрипт) должен быть у человека, который занимается сборкой пакетов. Возможно стоит немного повременить: https://packages.altlinux.org/ru/tasks/431040/ Если кратко, то я добавил механизм вендоринга в %%rust_prep: Source1: vendor.tar => %{!?_enable_rust_vendoring: Source1: vendor.tar } В зависимости добавить: BuildRequires: cargo-vendor-filterer Распаковку vendor.tar оформить в виде: %setup %{!?_enable_rust_vendoring:-a1} При сборке пакета: gear --hasher --commit -v -- hsh --apt-config=<Путь до конфига apt> --rpmbuild-args="--enable rust_vendoring" -v --mountpoint=/proc 2>&1 Когда дойдёт cargo-vendor-alt оборвать сборку. Перезапустить с сетью: hsh-copy --rooter /etc/resolv.conf /etc/resolv.conf share_network=1 gear --hasher --commit -v -- hsh-rebuild -v --mountpoint=/proc --rpmbuild-args="--enable rust_vendoring" 2>&1 На %build прервать сборку и скопировать архив с вендором: cp ~/hasher/chroot/usr/src/RPM/SOURCES/vendor.tar . Либо через через смену владельца и mv. Архив можно распаковать и паковать как обычный vendor/ либо поменять в .gear/rules tar на copy: vendor.tar. Постараюсь до конца недели исправить все проблемы с новыми макросами и поднять обсуждение об обновлении.
(Ответ для Сергей Жидких на комментарий #6) > Возможно стоит немного повременить: > https://packages.altlinux.org/ru/tasks/431040/ > ... > Постараюсь до конца недели исправить все проблемы с новыми макросами и > поднять обсуждение об обновлении. Окей, скрипт я еще не исправлял, попробую сразу этот вариант. Немного застрял с новой таской из-за того, что opt-level=3 съедал ОЗУ и весь раздел подкачки. Не сразу понял, что из-за него такое.
Вроде бы сделал и исправил все указанные моменты, кроме вендоринга (жду новый rpm-build-rust). Также, пришлось оставить debuginfo=1 для i586, иначе происходит OOM на сборочнице. Но зато для всех архитектур проходят тесты, даже подряд две сборки не упали. Для nprocs и optlevel/debuginfo добавил возможность переопределить их, т.к. локально не получается собрать без ограничения в одно ядро или уменьшения optlevel/debuginfo, начинается OOM, либо на грани его срабатывания (суммарно почти 20-30 Гб потребления). Тестовая таска на "посмотреть": https://packages.altlinux.org/ru/tasks/432404/
(Ответ для Корытов Иван на комментарий #8) > Вроде бы сделал и исправил все указанные моменты, кроме вендоринга (жду > новый rpm-build-rust). Если не будет никаких возмущений думаю приедет через недельку-две. Я думаю ради этого не стоит задерживать релиз. > Также, пришлось оставить debuginfo=1 для i586, иначе происходит OOM на > сборочнице. Это очень странно. Обычно больше всего ресурсов жрёт codegen-units и lto. > Для nprocs и optlevel/debuginfo добавил возможность переопределить их, т.к. > локально не получается собрать без ограничения в одно ядро или уменьшения > optlevel/debuginfo, начинается OOM, либо на грани его срабатывания (суммарно > почти 20-30 Гб потребления). В https://packages.altlinux.org/ru/tasks/431040/ добавил возможность при сборке сразу указать желаемый уровень отладочной информации и оптимизаций. Единственное нужно будет переименовать название макросов, под настройки Cargo и убрать ручное добавление опций. > * Thu Aug 13 2026 Ivan Korytov <toreonify@altlinux.org> 0.10.0-alt1 В changelog пишутся только релизы которые хоть раз попали в репозиторий. Содержание changelog должно отражать информацию интересную конечному пользователю. Для изменений направленных на изменение сборки пакета есть git. > BuildRequires: rust Не нужен если есть rpm-build-rust. В остальном замечаний нет.
(Ответ для Sergey Zhidkih на комментарий #9) > Если не будет никаких возмущений думаю приедет через недельку-две. Я думаю > ради этого не стоит задерживать релиз. Окей, тогда перепакую vendor через hasher вручную. А уже 0.11.0 тогда с новым способом выпущу. (Ответ для Sergey Zhidkih на комментарий #9) > > Также, пришлось оставить debuginfo=1 для i586, иначе происходит OOM на > > сборочнице. > Это очень странно. Обычно больше всего ресурсов жрёт codegen-units и lto. В локальном hasher на i586, кстати, такой проблемы не было. Уменьшение codegen-units на x86_64 у меня не дало должного эффекта. (Ответ для Sergey Zhidkih на комментарий #9) > В https://packages.altlinux.org/ru/tasks/431040/ добавил возможность при > сборке сразу указать желаемый уровень отладочной информации и оптимизаций. > Единственное нужно будет переименовать название макросов, под настройки > Cargo и убрать ручное добавление опций. Да, прочитал об этом в вашем анонсе в рассылке. (Ответ для Sergey Zhidkih на комментарий #9) > В changelog пишутся только релизы которые хоть раз попали в репозиторий. > Содержание changelog должно отражать информацию интересную конечному > пользователю. Для изменений направленных на изменение сборки пакета есть git. alt2 был лишь для теста, поэтому перезалью эти изменения под alt1 и удалю старое задание на EPERM. Кстати, а в автоматических проверках присутствует проверка на пропущенные релизы? Есть, например, проверка на то, что версия в бранчах не должна быть выше, чем в сизифе и тэг наследуется от той же ветки. Понятно, что такого не должно быть и это достаточно заметно. (Ответ для Sergey Zhidkih на комментарий #9) > > BuildRequires: rust > Не нужен если есть rpm-build-rust. > > В остальном замечаний нет. Окей, спасибо. Надеюсь, что больше ничего из проблем не просочится и таска вновь соберется, а не упадет на случайном тесте...
(Ответ для Корытов Иван на комментарий #10) > Кстати, а в автоматических проверках присутствует проверка на пропущенные > релизы? Вроде как нет. Есть проверка на соответствие changelog у SRPM в стабильных ветках, но это не то.