Наша сегодняшняя тема плавно вытекает из предыдущей, и не просто вытекает, а её слегка воспроизводит.
когда ты хочешь, чтобы софт попал в систему, ты можешь попытаться поставить пакет с помощью специальных инструментов. Мы правда не оговорили что делать с чужими рпмами, которые собраны не для вашего бистрибутива, а вы хотите их поставить. Варианта два -- не ставтиь эти рпмы, второй вариант -- разархивировать и развернуть в специальном каталоге и потом разложить бинарники ручками, и третий вариант -- перепаковать рпм. Есть такой скрипт rpm-rebuild. Он берет пакет, дает вам поредактировать спек и его пересобирает, по возможности следя за зависмостями. Если это не помогает, вероятно программу надо будет собрать из исходников. И здесь есть путь, при котором не понимая, что такое сборка, человек совершает акт сборки из пакета с исходниками. Почему не обязательно понимат, что такое сборка?
Пакет исходников
Достаточно обеспечить наличие сборочных зависимочтей, проделать кой какие алгоритмизированные упражнения и собрать пакет с помощью rpm-build. Tckb ye;ysq dfv gfrtn tcnm d ytcnf,bkmyjv [hfybkbot? а вам нужно его пересобрать в окружении стабильного хранилища, то вероятность что новый пакет соберется в старом окружении достаточно высокая. Проблемы будут только если хранилище настолько странное, что нужная библиотека исчезла, гцц сменился, или апи поменялось сильно.
- сборочные зависимости.
- rpm -i .src.rpm (развернуть пакет с исходниками). Эта операция кардинально отличается от её же для бинарного пакета -- она просто раскладывает файлы с исходниками. Раскладываются они в TOPDIR, которая по умолчанию ~/RPM с подкаталогами src, spec, rpm (туда соберется бинарный пакет), srpm (туда соберется новый пакет с исходниками)
- rpm-build -d спек-файл.
Если вы все сборочный зависимости установили (их можно прочесть в файле спецификаций, они помечены дибо тегом BuildReq, либо тегом BuildPreReq. Разницы никакой, кроме того, что можно определить какие пакеты ставить позже, а какие раньше. Можно писать несколько строк с этими тегами, ставятся они будут в любом случае в строго два этапа -- сначала пререк, потом рек.
Итак, если оно не сработало, что делать?
- Посмотреть на ошибку. Возможно, просто не хватает сборочных зависимочтей. В альте идет напряженная борьюа, чтобы обеспеичить более четкую сборку бинарников. Недавно была битва с дсолинк. Если библиотека А, с который вы линкуетесь, линкуется с библиотекой Б. И совершенно не факт, что эти отношения библиотек будут сохраняться. Например, библиотека libr, в ней есть функции libm. Потом приходит разработчик, и говорит "я соптимизировал, теперь мне libm не нужна", а вы её использовали. Как бороться? Запретить экспорт по цепочке. Либм был чемпионом по недолинковке. Так вот, вполне возможно, что сборочных зависимостей стало больше. Вы лезете руками в спекфайл, и начинаете там мудрить.
- Другая особенность альтлинукса. Недавно удалили пакет xorg-devel. Это был хороший пакет для установки всех иксовых библиотек, и очень плохой для включения в buildreq.
- Что ещё может случиться, что понадобиться редактивроать спек вручную? Могут ужесточиться полиси. Раньше в сизифе можно было класть в /usr/share бинарник, а теперь нельзя.
- Может быть хуже, могла измениться не только процедура сборки, а апи билиотеки, с которой оно собиралось. Например, буст. От его новой версии в сизифе ломается тестовая пересборка кучи пакетов.
- libpng, апстрим любит меня api без изменения сонейма. Далее есть два пути. Если вы позаботились сохранить старый пакеты, добавив в их имена версию, то в спеке достаточно поставить номер версии. Так делается в очень многих дистрибутивах, потому что мало кому хочется пересобирать программы под новые илиотеки, если они работают со старым.
- Для того же буста есть мнение, что надо соответствовать новейшей версии, и патчить исходники для этого.
Патч
diff -u f1 f2
Выдает какие строки в файлах изменились и несколько строк контекста.
Этот самый резудьтат дифф кладется в файл .patch, кладется в sources, и в спеке пишется, что надо наложить такие-то патчи. Команда патч довольно умная и она способна накладывать патчи, даже если исходные файлы слегка поменялись, благодаря содержащемуся в диффах контексту.
Если вы попали в ситуацю, когда исходник не собирается, то возможно его просто надо попатчить под новую версию библиотеки.
Как патчить?
Вам нужно добиться собираемости того, что вы собираете. Вам нужно поправтить исходники и запусить команду сборки прямо оттуда.
В случае рпма исходники лежат в каталоге build, в подкаталоге соотв названию пакета.
Вы заходить в ~/BUILD/.../ смотрите в мейкфайл, смотрите где он свалился, правите, перезапускаете мейк... И так, пока мейк не дойдет до конца. Вопрос, как теперь всё туда впихнуть? Всё впихивать не надо, вам не надо править апстримные исходники, надо сгенерировать диффы. Нужно положить рядом нетронутый развернутый пакет и сгенерировать диффы.
Итого, черновой способ состоит в том, чтобы захакать руками исходники, переименовать, развернуть исходники ещё раз rpm -bp (это означает развернуть и наложить патчи).
Есть несколько более хитрых и надежных способов. Например, ... Да нет, нету.
Лектор пользуется способом с гитом. Можно сказать рпм -бп, инициализировать гит. Договариваетесь с мейком.Хорошо то, что в гите не хранятся генераты, их можно удалить легко удалить. (а make clean сработает не во всех системах сборки)
git init git add . git comit hack hack git clean -fd git diff
Причем эти 4 команды можно вхакать в спек, никому не станет хуже.
Ситуация -- патч не прикладывается. Его надо перегенить. Вы руками все приделываете, а потом оказывается, что этот 3 патч из 10, <...>
Вы превращаетесь в полноценного разработчика, который работает с исходниками. Единственное что не стоит делать -- вхакивать патчи прямо сразу в оригинальный тарболл, надо хранить свои изменения в виде патчей.
Помимо бп есть многих всяких опцций у rpm-build.
ba -- сборка всего bi -- всё включая инстолл, но не включая последующуб проверку но не собирая рпм
Чего есть в спек файле
Спек-файл это рецептурник, в котором описано как собрать пакет из исходников. Исходники 3 типов
- апстрим тарболс -- то что скачали с апстрима
- патчи
- файлы, которые вы считаете, что должны быть в пакете -- десктоп файлы, конфиги, итп.
Спек это управляющий файл для системы рпм, в нем могут встречаться макросы для рпма, опредление которых лежит в /usr/lib/rpm/moresoft . Маколс в рпме начинается на проценты, в его имя может входить точка. Если вам нужно подставноку макроса %{version}_1. В редхате принято писать с фигурными скобками, в альте их принято, по возможности, убирать.
Механизм рпм макросов замороченный, но алгоритмически неполный, поэтому пользоваться надо с осторожностью.
Три назначения рпм макросов:
- Использовать короткую строку вместо длинной. %configure, который раскрывается в вызов соответствующего скрипта, но ему передается много параметров, специфичных для дистрибутива, или указывающих конфигуру, какие файлы в какие каталоги раскладывать. Очень часто при сборке по умолчанию программа будет раскадывать себя в /usr/local, что связано с древними предписаниями FHS, а вам это не нужно, потому что большинство полиси дистрибутив велит ставить в просто /usr.
- Не использовать магические числа. Есть программа, которая хранит данные в пути, зависимом от версии. Внутри спекфайла эту версию упомянать не хочется по десять раз. %datadir, %libdir, %bindir, %version
- Совершать насилсьтвенные действия над умолчаниями рпма, дабы профилировать процесс сборки. Какой-нибудь %optflags содержить стандартные ключи сборки с программы. Это стандартный макрос, чтобы изменить опции вы можете написать %add_opflags -DUNIX. Вы используете макрос для модифицирования состояния сборочной среды.
Из чего состоит спекфайл ?
Из секций, описывающих разные стадии сборки, паспорт пакета, ченджлог.
На сайте есть менюшка. В паспорт входят
- имя
- лицензия
- саммари
- груп
Заголовок
Версионирование.
Есть три поля. Версия, которая совпадает с апстримной версии, только если у апстрима совсем не отъехала крыша в этом плане. Релиз -- номер сборки этого пакета из этого исходника в рамках репозитория. Релиз используется, чтобы обозначить детали сборки. Если кто-то собрал ваш пакет вместо вас, то номер релиза не увеличивается, а приписывается через точку номер чрезвычайной сборки. Сюда же относится ситуация, когда пакет является бэкпортом. Тогда, чтобы, с одной стороны, обеспечить увеличение номера версий, а с другой стороны обеспечить, чтобы пакет собранный для этой самой версии имел больший номер релиза, в префикс ставится alt.0, а не бэкпорты -- alt.1 alt.2 etc Это надо, что бы обеспечить дист-апгрейд в правильные пакеты. Если хотите поименовать бету, то её тоже пихают в релиз, чтобы обеспечить правильную лексикографическую упорядоченность. version 1.2, release alt3beta
В заголовке есть информация об исходниках -- какие сорс и какие патчи. Когда их много, они перенумерованы. Все файлы, которые указаны вразделе исходники лежат в топдире в каталоге сорсес.
Информация о зависимостях сборочных и установочных тоже находится в спеке. Что касается информации о зависимостях. Можно указать зависимость от пакета, метапакета, файла. Если стоит зависимость пакет от пакета, то можно дополнительно указать версию. Это частенько используется. Игрушку собираешь, новая версия с новым артворком, артворк и бинарник в разных пакетах, одно без другого не имеет смысла. У бинарника ставится зависимость на конкретную версию артфорка. Requires^ %name-data = %version -%release.
Ещё в заголовке может быть информация о том, что он провайдит, обсолетит, с чем конфликтит (те дополнения к этому, что вписываются руками). Обсолет это когда нужно пакет удалить и вместо него поставить данный. (От конфликта отличается тем, что обсолет означает обновление).
Дескрипшн -- в нём описано более толсто, что такое наш пакет. Когда берете аптитуд или синаптик, он показывает дескрипшны, елси тыкать в имя пакета.
%prep
Раздел по развертыванию исхходников в топдире, конретно в подкаталоге билд. Дальше идут шелльные команды обычно. По окончанию исходники разложены, патчи применены и вообще можно делать мейк после этого.
%setup берет пакет, разворачивает пакет и поумолчанию ожидает, что им каталога будет -name-%version переходит туда и дальше совершает дальнейшие команды. Если имя каталога называется по другому надо передать ключик -n. Ключики -a -b позволяют развернуть несколько исходников рядом.
%patch10 -- применение файла под название патч10 из заголовка. Если патчу надо передать ключики, прямо так и передаете %patch10 -p1. p1 откусывает один уровень вложенности у каталога.
%build
Результатом должен быть законченный мейк. Если он был один. Возможно еще что-нибудь (конверт иконочек в разные размеры, например).
%configure %make_build
Почему мейк завернут в макрос? помимо флагов, этот макрос опирается ещё и на количество процессоров в системе (nproc в рпм) и может запустить сборку с -j. Сейчас ситуация многопоточной сборки встречается все чаще и чаще.
Можно это все делать и без макросов, но тогда надо самим озаботиться передать нужные ключи.
Глядя спеки редхачьи и сусешные, вы увидите. что они пошли дальше и гораздо больше всего завернули в макросы. %cp и тп.
Помимо стандартных макросов, в сборочном окружении могут приехать макросы, специфичные для конкретной среды -- питона, смаке, итп. В этой секции может использоваться очень много макровос. Не забывайте rpm --eval, который покажет, во что макрос раскрывается в действительности.
У нас есть апстримные исходники, патчи к ним годно приклдаываются, пусть с фаззом, но они делают то, что надо. Пока они это делают, их функциональность с высокой вероятностью сохраняется. Если их менять при каждом фаззе, то становится сложно в истории разработки увидеть серьезные именения в апстриме.
Результатом билда должна быть ситуация, когда можно приступать к установке.
%install
%install %makeinstall
Главное то, что ваша сборка должна быть ориентирована под установку не в корень, а в %buildroot. Всё, в том числе возможные патчи, было подготовлено к тому, чтобы ваш бинарник устанавливался в специальное место,а не в корень, да ещё и без прав рута. Чем плохо запуск произвольного кода от рута, объяснять не надо. Бывает так, что апстрим немножко кривовастенький, и что-то кладется не в билдрут. Дестдир -- ещё один префикс. результат суперплозиции префиксов может быть странным.
%bindir, %man1dir, всё, что может именоваться явно, лучше именовать с помощью макросов, потому что они очень много где используются.
%check
Запускаете тесты, если таковые имеются. Обратите внимание, что чек запускается после установки.
%files
Списки файлов в пакете. Что есть особенного? %_bindir/* %attr(...) файл. Всем файлам в бине накладывается 755, сетуиднымм и сетгидным запрещается чтение, короче если сами не прибьёте экзотические права, то будет так.
Там есть полиси -- если вы умудрились запаковать ридабл сетуидный файл, то полиси чек не пройдёт.
Вторая причина, что аттр нужны (первая -- сетудниый файлы) вторая -- можно сказать инсталл. Инсталлу выполниться не удастся, но он это запомнит.
Ну и конфиг. Чтобы не морочиться, можно сказать %doc. %config. Мы помним, что рпму можно сказать, что некоторые файлы конфигурационные, вот так это делается.
%changelog
Что вы сделали, когда собиралаи очередную версию, в соответствии с достаточно жесткими правилами. Кто собирал, какие изменения прикладывал. Это то, что читает разработчик, когда хочет понять, что случилось с пакетом.
Альтовый ченджлог обладает специальным свойством -- особые сообщения в ченджлоге приводят к закрытию бага в багзилле.
Из одного и того же срц-рпма можно собрать кучу бинарных пакетов. Это оформляется отдельным разделом
%package
Суффикс имени пакета. -devel, -data. Можно принципиально изменить имя пакета -n. после неё следуют куски паспорта к этому новому пакету. Например, там должна быть группа. Дескрипшн и саммари.
преп и билд у них общая, а секция файлс разная, по тому же самому принципу.
Полезное при сборке
Какие секции не встречаются в альтовом спеке. %clean. потому что билдрут зачищается автоматом. Редко встречаются секции, где хранятся послеустановочные сценарии.
rpm-build может продолжить работать с любого места. Ключ -- short-circuit.
build-req -- скрипт, генерящий сборочные зависимости. Хорошая штука, особенно если собираете пакет с нуля, хотя совсем всё сделать не может.
Три вещи
- Помимо генерации сборочных зависимостей вручную, рек и провайдс генерируются автоматически. Причем, зависимостей пакет-пакет там мало. На бибилотеки и питоно модули ставятся зависимостина сущности. Для этого существует большая пчка скриптов, которая занимается поиском этих зависимостей. Тоже самое относится к поискам провайдс.
- Проверка пакетов после сборки. Несколько стадий.
- правильно ли слинкованы бинарники, не попало ли что странное в rpath, все ли символы есть итп.
- buildroot policy. Проверяется куча ошибок, альтоспецифично. Поначалу это кажется издевательством и придирками, но, как всякая разумная дисциплина облегчает жизнь.
- Что делать с пакетами, которые рпм собрал и набросал в /usr блабла. Как их установить? rpm -i, но тогда зависимости на вас. Как поставить свежесобранный пакет из свалки? Как поставить пакет из кталога, который не репозиторий, а просто свалка рпм, причем поставить с зависимостями. Ответ -- в сорсес лист специальный вид репозитория rpm-dir. Это специальный вид репозитория, в котором индексы генерятся на лету.