Если коротко: после обновления крупных библиотек вроде glibc, openssl, Qt или Python AUR-пакеты надо пересобирать вручную, потому что за тебя их никто не пересобирает. Официальные пакеты репозитория Arch пересобирает команда мейнтейнеров, а пакеты из AUR живут своей жизнью: собранный месяц назад бинарник продолжает ссылаться на старые версии библиотек и после апгрейда системы может просто не запуститься. Найти таких кандидатов помогает rebuild-detector, а пересобрать их можно одной командой yay или paru.
Программы из AUR ты собираешь из исходников, и в момент сборки они линкуются с теми версиями библиотек, которые стоят в системе. Крупные библиотеки вроде glibc, openssl, Qt, GTK, ffmpeg или Python меняют между версиями внутренний интерфейс, ABI. Бинарник, собранный против старой версии, после обновления библиотеки может не найти нужные символы и упасть при запуске.
Механизм простой. Каждая динамическая библиотека несёт в имени soname, версию интерфейса: libfoo.so.2, libfoo.so.3. Пока soname не меняется, бинарники, собранные против старой версии, спокойно работают с новой. Но крупные обновления вроде перехода glibc на новую версию или Qt 5 на Qt 6 меняют soname и внутренние символы. Старый бинарник ищет символы, которых в новой библиотеке уже нет, и падает с ошибкой вроде undefined symbol или version GLIBC_2.38 not found.
Официальные пакеты от этого защищены. Когда glibc обновляется в репозитории, все зависящие пакеты пересобираются и выходят в обновлении следом. У AUR такого конвейера нет: пакет в AUR это просто PKGBUILD, а не готовый бинарник. Обновил библиотеку, и все локально собранные пакеты, которые от неё зависят, остаются со старыми ссылками. Система при этом считает их установленными и ничего пересобирать не предлагает.
Чаще всего страдают пакеты, собранные давно. Чем дольше пакет живёт в системе без пересборки, тем выше шанс, что очередной апгрейд библиотеки его сломает. О том, почему зависимости AUR разваливаются после обновлений, подробно написано в статье «AUR-зависимости ломаются после обновления».
Симптомы разные. Программа может не запуститься вовсе, упасть через пару минут работы или молча терять функции. Типичные сообщения: error while loading shared libraries, undefined symbol, version GLIBC_2.38 not found. Иногда всё работает, но странно: например, после обновления Python AUR-модуль, собранный под старую версию, отказывается импортироваться.
Хуже всего то, что pacman об этом не знает. Он видит, что пакет установлен и его файлы на месте, и не предлагает ничего пересобрать. Ошибка вылезает только в момент запуска программы, часто в самый неподходящий момент. Поэтому пересборку лучше делать заранее, по расписанию после крупных обновлений, а не когда что-то уже упало.
Классический пример: обновил python, а AUR-пакет с C-расширением собран под старую версию. При импорте он падает с ошибкой про несовместимый ABI. Или обновил Qt, и приложение из AUR закрывается при запуске с сообщением про отсутствующий символ. В обоих случаях лечится одинаково: пересборка пакета против новых библиотек.
Самый простой способ: утилита rebuild-detector. Она сканирует установленные пакеты и сравнивает версии библиотек, с которыми они собраны, с текущими версиями в системе. Устанавливается из AUR:
yay -S rebuild-detector
rebuild-detector
Вывод покажет список пакетов, собранных против устаревших библиотек. Это и есть кандидаты на пересборку. Утилита не идеальна: она не ловит все случаи, особенно динамическую линковку через dlopen, но как первичный фильтр работает отлично. Запускать её стоит после каждого крупного обновления, а не только когда что-то сломалось.
Второй способ: посмотреть, от каких библиотек зависит пакет, и сравнить с тем, что стоит в системе.
pacman -Qi имя-пакета
В выводе есть секция «Зависимости» (Depends On). Если среди них есть glibc, qt6-base, python или другая крупная библиотека, которую ты недавно обновил, пакет стоит пересобрать. Особенно если он собран давно: дату установки показывает поле «Установлен» (Install Date).
Если хочешь найти все пакеты, зависящие от конкретной библиотеки, используй pactree с флагом -r (reverse):
pactree -r libfoo
Команда выведет дерево пакетов, которые тянут libfoo. Среди них будут и официальные, и AUR-пакеты. Официальные уже пересобраны репозиторием, а вот AUR-пакеты из списка твоя забота. Подробнее про работу с деревом зависимостей читай в статье «pactree: граф зависимостей».
Если пакет установлен через AUR-хелпер, пересборка делается одной командой. Для yay:
yay -S --rebuild имя-пакета
Для paru:
paru --rebuild имя-пакета
Флаг –rebuild заставляет хелпер пересобрать пакет, даже если версия в AUR не менялась. Если хочешь заодно обновить все пакеты, собранные из git-репозиториев, добавь –devel:
yay -S --rebuild --devel
Если хелпера нет или пакет собран вручную, зайди в каталог с PKGBUILD и пересобери:
cd ~/builds/имя-пакета
touch PKGBUILD
makepkg -f
Команда touch меняет время изменения PKGBUILD, поэтому makepkg считает, что исходники изменились, и пересобирает пакет заново. Флаг -f (force) перезаписывает уже собранный пакет. После сборки установи его через pacman -U. Основы работы с makepkg разобраны в статье «makepkg: всё, что нужно знать».
Перед ручной пересборкой убедись, что в системе есть все зависимости для сборки, makedepends из PKGBUILD. Если чего-то не хватает, makepkg сам подскажет, но лучше проверить заранее. И помни: makepkg собирает пакет от обычного пользователя, а не от root.
Пересобирай в правильном порядке: сначала пакеты, от которых зависят другие. Если пакет A зависит от пакета B, а B собран против старой библиотеки, сначала пересобирай B, потом A. Иначе A соберётся против старой версии B, и проблему это не решит. rebuild-detector обычно выводит список в правильном порядке, но если сомневаешься, проверь зависимости через pactree. Правильная последовательность экономит время: не придётся пересобирать одно и то же дважды.
Пересборка нескольких пакетов занимает время. Ускорить её можно через ccache и tmpfs, об этом статья «Ускорить сборку: ccache и tmpfs». А если сборка падает с непонятной ошибкой, поможет методика из статьи «Divide and conquer: отладка сборки».
После пересборки проверь, что бинарник теперь ссылается на актуальную версию библиотеки. Проще всего через ldd:
ldd $(command -v имя-приложения)
В выводе будут строки вида libfoo.so.2 => /usr/lib/libfoo.so.2. Если какая-то библиотека не найдена, ldd покажет «not found». Значит, пакет всё ещё собран против старой версии, и пересборка не помогла или прошла не для того пакета. Сверь soname в выводе ldd с текущей версией библиотеки в системе: они должны совпадать. Если «not found» несколько, не паникуй: часть из них может быть опциональными библиотеками, которые подгружаются по требованию. Смотри в первую очередь на те, что относятся к обновлённой библиотеке.
Второй способ: проверить целостность файлов пакета.
pacman -Qkk имя-пакета
Команда сверяет контрольные суммы файлов с теми, что записаны в базе pacman. Если после пересборки пакет не был переустановлен, pacman -Qkk покажет изменённые файлы. Подробнее читай в статье «Проверка целостности: pacman -Qkk».
Не все пакеты требуют пересборки. Статические бинарники, в которые библиотеки вшиты на этапе сборки, от обновления библиотек не зависят вообще. Это касается многих Go-программ, Rust-утилит и пакетов, собранных с -static. Если ldd на такой бинарник отвечает «not a dynamic executable», пересборка бессмысленна.
Также не стоит пересобирать пакеты, которые не зависят от обновлённой библиотеки. rebuild-detector их и не покажет, а ручная пересборка всего подряд только потратит время и может принести новые проблемы. Пересобирай точечно, по списку, а не всё подряд.
Отдельная категория: пакеты, которые тащат библиотеки с собой, в комплекте. Некоторые приложения собираются с вендоренными зависимостями и не используют системные вообще. Их пересборка после обновления системных библиотек тоже ничего не даст.
Проверь ldd ещё раз. Возможно, пакет тянет библиотеку, которую ты не обновил, или пересобрал не ту зависимость. Соблюдай порядок: сначала зависимости, потом сам пакет. Если ничего не помогает, откати обновление, переустановив старую версию библиотеки из кеша pacman.
Утилита сравнивает версии по записям в базе pacman и не всегда видит динамическую линковку через dlopen. Если пакет падает, но rebuild-detector молчит, проверь его зависимости через pacman -Qi и пересобери вручную.
Нет. Пересборка нужна только после обновления крупных библиотек, от которых пакет зависит: glibc, openssl, Qt, GTK, ffmpeg, Python и подобных. После обычных обновлений мелких пакетов ничего пересобирать не надо.
Их пересобирает команда Arch. Когда в репозиторий попадает новая версия glibc или Qt, мейнтейнеры пересобирают все зависящие пакеты и выкладывают обновления. Тебе остаётся только выполнить pacman -Syu. У AUR такого процесса нет, поэтому пересборка ложится на тебя.
Можно, но не нужно. yay -S –rebuild –devel пересоберёт всё, что установлено из AUR, но это займёт много времени. Разумнее пересобирать только те пакеты, которые rebuild-detector пометил как устаревшие.
После обновления крупных библиотек AUR-пакеты не пересобираются сами, это твоя задача. Найди кандидатов через rebuild-detector или pactree -r, пересобери сначала зависимости, потом сами пакеты через yay -S –rebuild или makepkg -f, и проверь результат через ldd. Статические бинарники можно не трогать. Пятнадцать минут на пересборку избавят тебя от внезапных падений программ после очередного pacman -Syu.
Задай вопрос в чате — отвечаем быстро, по делу и без воды.
Комментарии