Spec-helper — различия между версиями
D uragan (обсуждение | вклад) м |
D uragan (обсуждение | вклад) (Translated into Russian) |
||
(не показана одна промежуточная версия этого же участника) | |||
Строка 1: | Строка 1: | ||
[[Category:Packaging Guidelines]] | [[Category:Packaging Guidelines]] | ||
− | {{Введение| | + | {{Введение|Следуем политикам сборки пакетов с помощью spec-helper}} |
__TOC__ | __TOC__ | ||
− | = | + | = Как это работает = |
− | Spec-helper | + | Spec-helper предоставляет набор скриптов, которые автоматически запускаются по время сборки пакетов и производят ряд действий, приводящих пакеты в соответствие с политиками сборки РОСЫ. Также в пакет {{pkg|spec-helper}} входят несколько скриптов, которые могут использовать мэйнтейнеры для автоматизации рутинных задач. |
− | + | Обратите также внимание на файлы {{file|/usr/lib/rpm/brp-*}}. Сокращение "brp" происходит от "build root policies", "политик сборочного контейнера". Эти файлы определяют инструкции, которые будут выполнены в директории сборки сразу после завершения ее. Запуск скриптов BRP регулируется макросом {{macro|%_os_install_post}}, который в РОСЕ определяется в файлах настройки внутри {{file|/usr/lib/rpm/}}. | |
− | + | Например, согласно политикам РОСЫ, справочные страницы {{prog|man}} должны архивироваться с помощью {{prog|xz}}. Чтобы избавить мэйнтейнера от необходимости самостоятельно вызывать команды сжатия и облегчит возможность изменения политики (например, смену программы архивации), мы используем специальный хук для {{prog|rpm}}, который архивирует man-страницы автоматически в процессе сборки пакета и тем самым автоматически приводит пакет в соответствие политикам. | |
− | + | Скрипты, используемые {{prog|spec-helper}}, размещаются в директории {{file|/usr/share/spec-helper}}. Запуск тех или иных скриптов регулируется в файле {{file|/etc/rpm/macros.d/spec-helper.macros}}. | |
− | + | Далее мы объясним, как можно добавить свой скрипт в {{prog|spec-helper}}. | |
− | = | + | = Создание скрипта = |
− | + | Для примера, напишем скрипт, запускающий [http://pmt.sourceforge.net/pngcrush/ pngcrush] на каждом {{file|png}}-файле пакета. | |
− | + | Для начала, необходимо выбрать имя скрипта. Использовать "pngcrus" не следует, поскольку так называется непосредственно программа, которую будет вызывать наш скрипт, и вы не сможете гарантированно сказать, что вы запускаете - ваш скрипт или программу. Поэтому давайте назовем скрипт {{prog|png_crush_rpm}}. | |
− | + | Что касается языка, на котором писать скрипт, то здесь у вас есть некоторая свобода выбора. У нас уже есть скрипты на {{prog|perl}}, {{prog|bash}} и {{prog|python}}. В нашем примере мы будем использовать shell. | |
− | + | Можно использовать и другие интерпретируемые языки, но помните, что добавление скрипта на новом языке добавит еще одну зависимость пакету {{pkg|spec-helper}}. Использование компилируемого языка и создание программы сделает spec-helper зависящим от аппаратной платформы и может затруднить его перенос на другие архитектуры, чего нам бы очень хотелось избежать.. | |
+ | |||
+ | Что касается тела скрипта, то в нашем случае оно очень простое - мы должны применить {{prog|pngcrush}} к каждому файлу, находящемуся внутри сборочно директории, имя которой содержится в переменной окружения {{var|$RPM_BUILD_ROOT}}. Обязательно убедитесь, что эта переменная выставлена и указывает на реально существующую директорию. | ||
<pre> | <pre> | ||
#!/bin/sh | #!/bin/sh | ||
− | # | + | # проверим, выставлена ли переменная $RPM_BUILD_ROOT |
if [ -z $RPM_BUILD_ROOT ]; then | if [ -z $RPM_BUILD_ROOT ]; then | ||
exit 0 | exit 0 | ||
fi; | fi; | ||
− | # | + | # проверим, указывает ли она на реальную директорию |
[ -d $RPM_BUILD_ROOT ] || exit 0 | [ -d $RPM_BUILD_ROOT ] || exit 0 | ||
− | # | + | # вызовем pngcrush для каждого png-файла |
for i in ind $RPM_BUILD_ROOT -type f -name '*.png' ; do | for i in ind $RPM_BUILD_ROOT -type f -name '*.png' ; do | ||
pngcrush -q $i $i.new | pngcrush -q $i $i.new | ||
Строка 43: | Строка 45: | ||
</pre> | </pre> | ||
− | + | Не забудьте сделать файл исполняемым! (<b>chmod a+x</b>). | |
− | + | Скрипт можно протестировать, вручную выставив переменную <b>RPM_BUILD_ROOT</b>, чтобы она указывала на некоторую директорию с png-файлами, и проверив, что при запуске скрипта действительно происходит обработка этих файлов. | |
− | = | + | = Добавление скрипта в spec-helper = |
− | + | Теперь добавим наш скрипт в {{prog|spec-helper}}. | |
− | + | Необходимо предусмотреть опцию и переменную окружения, отключающие запуск вашего конкретного скрипта. Например, можно добавить следующую опцию в соответствующие секции {{prog|spec-helper}}: | |
<pre> | <pre> | ||
− | echo "-png | + | echo "-png не запускать pngcrsuh на png-файлах." 1>&2 |
</pre> | </pre> | ||
− | + | и ее обработку: | |
<pre> | <pre> | ||
Строка 63: | Строка 65: | ||
</pre> | </pre> | ||
− | + | в конструкцию switch/case. | |
− | + | Остается только добавить команду запуска вашего скрипта: | |
<pre> | <pre> | ||
− | test -z "$DONT_PNG_CRUSH" && echo -n " | + | test -z "$DONT_PNG_CRUSH" && echo -n "Пережимаем png..." && png_crush_rpm && echo "done" |
</pre> | </pre> | ||
− | + | Теперь {{prog|rpm}} будет автоматически запускать ваш скрипт при сборке пакетов. | |
− | + | Если вы полагаете, что написали скрипт, потенциально полезный многим мэйнтейнерам - на забудьте прислать его разработчикам РОСЫ для включения в штатные {{prog|spec-helper}}. | |
− | = | + | = Отключение запуска скриптов spec-helper в spec-файлах = |
− | + | Могут возникать ситуации, когда вы намеренно хотите нарушить одну из политик, автоматически претворяемых в жизнь посредством {{prog|spec-helper}}. Например, вы хотите собрать пакет, оставив отладочную информацию непосредственно в его бинарных файлах - для облегчения отладки. Для этого вам необходимо выставить соответствующую переменную в секции {{macro|%install}}: | |
<pre> | <pre> | ||
%install | %install | ||
− | |||
%makeinstall | %makeinstall | ||
.... | .... | ||
− | # | + | # не запускать "strip" на исполнимых файлах |
export DONT_STRIP=1 | export DONT_STRIP=1 | ||
− | |||
</pre> | </pre> | ||
− | + | Перечень всех доступных переменных можно найти в файле {{file|/etc/rpm/macros.d/spec-helper.macros}}. На момент написания данной статьи список переменных был таков: | |
+ | |||
+ | * {{var|DONT_CLEANUP}} - не удалять резервные копии и прочие бесполезные файлы | ||
+ | * {{var|DONT_CLEAN_PERL}} - не удалять некоторые вспомогательные файлы для {{prog|perl}}, не требуемые при работе программ (например, {{file|.packlist}}) | ||
+ | * {{var|DONT_COMPRESS}} - не архивировать справочные страницы man и info | ||
+ | * {{var|DONT_STRIP}} - не удалять отладочныую информацию из исполнимых баинарных файлов и разделяемых библиотек | ||
+ | * {{var|DONT_RELINK}} - не превращать символьные ссылки в относительные | ||
+ | * {{var|DONT_SYMLINK_LIBS}} - не создавать автоматически символьные ссылки для библиотек | ||
+ | * {{var|DONT_FIX_PAMD_CONFIGS}} - не заменять {{file|/lib}} на {{file|/lib64}} в конфигурационных файлах {{prog|pam}} для 64-битных пакетов | ||
+ | * {{var|DONT_REMOVE_INFO_DIR}} - не удалять {{file|/usr/share/info/dir/}} | ||
+ | * {{var|DONT_FIX_MO}} - не исправлять часто встречающиеся ошибки переводов | ||
+ | |||
+ | = Скрипты для ручного запуска = | ||
+ | |||
+ | Пакет {{pkg|spec-helper}} также содержит несколько скриптов, которые не запускаются автоматически при сборке, но предназначены для самостоятельного использования мэйнтейнерами. | ||
+ | |||
+ | == spec-cleaner == | ||
+ | Скрипт {{prog|Spec-cleaner}} предназначен для очистки spec-файлов от ненужных и устаревших конструкций. В частности, {{prog|spec-cleaner}} выполняет следующие действия: | ||
+ | * удаляет устаревшие и ненужные декларации — например, определение BuildRoot и Packager, зависимость от install-info, очистку buildroot и так далее; | ||
+ | * изменяет оформление использования макросов и переменных — переменные печатаются в фигурных скобках — %{const}, а макросы — без них — %{macro}. Такие изменения производятся только для макросов и переменных, определенных в самом rpm (а точнее, перечисленных непосредственно в скрипте spec-cleaner). Если вы сами определяете какие-то сущности, то их оформление скрипт изменять не будет; | ||
+ | * изменяет форматирование Summary — делает первую букву заглавной, удаляет точку в конце; | ||
+ | * удаляет явные определения переменных %{name}, %{version} и %{release}; | ||
+ | * заменяет устаревшие макросы на современные аналоги; | ||
+ | * … и много других мелочей. | ||
+ | |||
+ | По умолчанию, {{prog|spec-cleaner}} удаляет из spec-файлов секцию %changelog, поскольку в РОСЕ перечень изменений для пакета формируется на основе истории коммитов в Git на ABF, а большинство spec-файлов в секции %changelog содержат только очень старые записи. Если же вы не хотите, чтобы {{prog|spec-cleaner}} удалял секцию %changelog, просто выставьте переменную окружения {{var|SPEC_LEAVE_CHANGELOG}} в 1. | ||
+ | |||
+ | == rediff_patch == | ||
+ | |||
+ | {{prog|Rediff_patch}} пытается переделать имеющийся патч под новую версию тарболла с исходным кодом. Использовать его надо следующим образом: | ||
+ | |||
+ | # запускать {{prog|rediff_patch}} необходимо в директории склонированного проекта — там, где лежит spec-файл и патчи. Spec-файл используется для того, чтобы определить — как именно применяется патч; | ||
+ | # в эту же директорию необходимо поместить новый тарболл с исходным кодом, для которого надо переделать патч; | ||
+ | # непосредственно запуск скрипта выглядит так: | ||
+ | |||
+ | rediff_patch <patch_ro_rediff> <tarball> | ||
+ | |||
+ | Если у вас в директории только один тарболл, то второй параметр можно опустить — {{prog|rediff_patch}} возьмет единственный тарболл самостоятельно. | ||
+ | |||
+ | В ходе работы {{prog|rediff_patch}} создаст директорию {{file|rediff_patch}}, распакует в нее новый тарболл и попытается применить к нему патч с параметрами, взятыми из spec-файла, добавив к ним опцию «--force» и используя значение fuzz по умолчанию (при сборке в rpmbuild используется «--fuzz=0»). Сейчас скрипт рассчитан на работу с тарболлами, при распаковке которых получается одна директория — обрабатывать tar-бомбы он откажется. | ||
+ | |||
+ | В случае, если все сложится успешно, рядом с вашим патчем вы обнаружите новый патч с суффиксом «.new», а остальные следы деятельности скрипта (директория {{file|rediff_patch}} со всем содержимым) будут уничтожены. | ||
− | + | Если же что-то не заладится (например, патч применился не целиком), то вам останется директория {{file|rediff_patch}} с двумя поддиректориями — исходной и новой, к которой пробовали применить патч. Так что вы сможете вручную завершить работу, которую не получилось сделать автоматически, и уже самостоятельно сформировать новый патч с помощью стандартного {{cmd|diff -Naur}}. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Практика показывает, что большинство патчей все-таки требуют доработки, переделать их автоматически с использованием --force и более мягкого значения fuzz получается не очень часто. Однако даже если {{prog|rediff_patch}} справился со всем самостоятельно, обязательно проверьте результирующий патч — ведь '--force' иногда может привести к нежелательному результату. А если {{prog|rediff_patch}} не справился — что ж, по крайней мере, мы немного сэкономим на распаковке архива и первой попытке применить патч. | |
− | + | [[en:Spec-helper]] |
Текущая версия на 11:28, 28 марта 2014
Содержание
Как это работает
Spec-helper предоставляет набор скриптов, которые автоматически запускаются по время сборки пакетов и производят ряд действий, приводящих пакеты в соответствие с политиками сборки РОСЫ. Также в пакет spec-helper входят несколько скриптов, которые могут использовать мэйнтейнеры для автоматизации рутинных задач.
Обратите также внимание на файлы /usr/lib/rpm/brp-*. Сокращение "brp" происходит от "build root policies", "политик сборочного контейнера". Эти файлы определяют инструкции, которые будут выполнены в директории сборки сразу после завершения ее. Запуск скриптов BRP регулируется макросом %_os_install_post, который в РОСЕ определяется в файлах настройки внутри /usr/lib/rpm/.
Например, согласно политикам РОСЫ, справочные страницы man должны архивироваться с помощью xz. Чтобы избавить мэйнтейнера от необходимости самостоятельно вызывать команды сжатия и облегчит возможность изменения политики (например, смену программы архивации), мы используем специальный хук для rpm, который архивирует man-страницы автоматически в процессе сборки пакета и тем самым автоматически приводит пакет в соответствие политикам.
Скрипты, используемые spec-helper, размещаются в директории /usr/share/spec-helper. Запуск тех или иных скриптов регулируется в файле /etc/rpm/macros.d/spec-helper.macros.
Далее мы объясним, как можно добавить свой скрипт в spec-helper.
Создание скрипта
Для примера, напишем скрипт, запускающий pngcrush на каждом png-файле пакета.
Для начала, необходимо выбрать имя скрипта. Использовать "pngcrus" не следует, поскольку так называется непосредственно программа, которую будет вызывать наш скрипт, и вы не сможете гарантированно сказать, что вы запускаете - ваш скрипт или программу. Поэтому давайте назовем скрипт png_crush_rpm.
Что касается языка, на котором писать скрипт, то здесь у вас есть некоторая свобода выбора. У нас уже есть скрипты на perl, bash и python. В нашем примере мы будем использовать shell.
Можно использовать и другие интерпретируемые языки, но помните, что добавление скрипта на новом языке добавит еще одну зависимость пакету spec-helper. Использование компилируемого языка и создание программы сделает spec-helper зависящим от аппаратной платформы и может затруднить его перенос на другие архитектуры, чего нам бы очень хотелось избежать..
Что касается тела скрипта, то в нашем случае оно очень простое - мы должны применить pngcrush к каждому файлу, находящемуся внутри сборочно директории, имя которой содержится в переменной окружения $RPM_BUILD_ROOT. Обязательно убедитесь, что эта переменная выставлена и указывает на реально существующую директорию.
#!/bin/sh # проверим, выставлена ли переменная $RPM_BUILD_ROOT if [ -z $RPM_BUILD_ROOT ]; then exit 0 fi; # проверим, указывает ли она на реальную директорию [ -d $RPM_BUILD_ROOT ] || exit 0 # вызовем pngcrush для каждого png-файла for i in ind $RPM_BUILD_ROOT -type f -name '*.png' ; do pngcrush -q $i $i.new mv -f $i.new $i done;
Не забудьте сделать файл исполняемым! (chmod a+x).
Скрипт можно протестировать, вручную выставив переменную RPM_BUILD_ROOT, чтобы она указывала на некоторую директорию с png-файлами, и проверив, что при запуске скрипта действительно происходит обработка этих файлов.
Добавление скрипта в spec-helper
Теперь добавим наш скрипт в spec-helper.
Необходимо предусмотреть опцию и переменную окружения, отключающие запуск вашего конкретного скрипта. Например, можно добавить следующую опцию в соответствующие секции spec-helper:
echo "-png не запускать pngcrsuh на png-файлах." 1>&2
и ее обработку:
-png) DONT_PNG_CRUSH=1;;
в конструкцию switch/case.
Остается только добавить команду запуска вашего скрипта:
test -z "$DONT_PNG_CRUSH" && echo -n "Пережимаем png..." && png_crush_rpm && echo "done"
Теперь rpm будет автоматически запускать ваш скрипт при сборке пакетов.
Если вы полагаете, что написали скрипт, потенциально полезный многим мэйнтейнерам - на забудьте прислать его разработчикам РОСЫ для включения в штатные spec-helper.
Отключение запуска скриптов spec-helper в spec-файлах
Могут возникать ситуации, когда вы намеренно хотите нарушить одну из политик, автоматически претворяемых в жизнь посредством spec-helper. Например, вы хотите собрать пакет, оставив отладочную информацию непосредственно в его бинарных файлах - для облегчения отладки. Для этого вам необходимо выставить соответствующую переменную в секции %install:
%install %makeinstall .... # не запускать "strip" на исполнимых файлах export DONT_STRIP=1
Перечень всех доступных переменных можно найти в файле /etc/rpm/macros.d/spec-helper.macros. На момент написания данной статьи список переменных был таков:
- DONT_CLEANUP - не удалять резервные копии и прочие бесполезные файлы
- DONT_CLEAN_PERL - не удалять некоторые вспомогательные файлы для perl, не требуемые при работе программ (например, .packlist)
- DONT_COMPRESS - не архивировать справочные страницы man и info
- DONT_STRIP - не удалять отладочныую информацию из исполнимых баинарных файлов и разделяемых библиотек
- DONT_RELINK - не превращать символьные ссылки в относительные
- DONT_SYMLINK_LIBS - не создавать автоматически символьные ссылки для библиотек
- DONT_FIX_PAMD_CONFIGS - не заменять /lib на /lib64 в конфигурационных файлах pam для 64-битных пакетов
- DONT_REMOVE_INFO_DIR - не удалять /usr/share/info/dir/
- DONT_FIX_MO - не исправлять часто встречающиеся ошибки переводов
Скрипты для ручного запуска
Пакет spec-helper также содержит несколько скриптов, которые не запускаются автоматически при сборке, но предназначены для самостоятельного использования мэйнтейнерами.
spec-cleaner
Скрипт Spec-cleaner предназначен для очистки spec-файлов от ненужных и устаревших конструкций. В частности, spec-cleaner выполняет следующие действия:
- удаляет устаревшие и ненужные декларации — например, определение BuildRoot и Packager, зависимость от install-info, очистку buildroot и так далее;
- изменяет оформление использования макросов и переменных — переменные печатаются в фигурных скобках — %{const}, а макросы — без них — %{macro}. Такие изменения производятся только для макросов и переменных, определенных в самом rpm (а точнее, перечисленных непосредственно в скрипте spec-cleaner). Если вы сами определяете какие-то сущности, то их оформление скрипт изменять не будет;
- изменяет форматирование Summary — делает первую букву заглавной, удаляет точку в конце;
- удаляет явные определения переменных %{name}, %{version} и %{release};
- заменяет устаревшие макросы на современные аналоги;
- … и много других мелочей.
По умолчанию, spec-cleaner удаляет из spec-файлов секцию %changelog, поскольку в РОСЕ перечень изменений для пакета формируется на основе истории коммитов в Git на ABF, а большинство spec-файлов в секции %changelog содержат только очень старые записи. Если же вы не хотите, чтобы spec-cleaner удалял секцию %changelog, просто выставьте переменную окружения SPEC_LEAVE_CHANGELOG в 1.
rediff_patch
Rediff_patch пытается переделать имеющийся патч под новую версию тарболла с исходным кодом. Использовать его надо следующим образом:
- запускать rediff_patch необходимо в директории склонированного проекта — там, где лежит spec-файл и патчи. Spec-файл используется для того, чтобы определить — как именно применяется патч;
- в эту же директорию необходимо поместить новый тарболл с исходным кодом, для которого надо переделать патч;
- непосредственно запуск скрипта выглядит так:
rediff_patch <patch_ro_rediff> <tarball>
Если у вас в директории только один тарболл, то второй параметр можно опустить — rediff_patch возьмет единственный тарболл самостоятельно.
В ходе работы rediff_patch создаст директорию rediff_patch, распакует в нее новый тарболл и попытается применить к нему патч с параметрами, взятыми из spec-файла, добавив к ним опцию «--force» и используя значение fuzz по умолчанию (при сборке в rpmbuild используется «--fuzz=0»). Сейчас скрипт рассчитан на работу с тарболлами, при распаковке которых получается одна директория — обрабатывать tar-бомбы он откажется.
В случае, если все сложится успешно, рядом с вашим патчем вы обнаружите новый патч с суффиксом «.new», а остальные следы деятельности скрипта (директория rediff_patch со всем содержимым) будут уничтожены.
Если же что-то не заладится (например, патч применился не целиком), то вам останется директория rediff_patch с двумя поддиректориями — исходной и новой, к которой пробовали применить патч. Так что вы сможете вручную завершить работу, которую не получилось сделать автоматически, и уже самостоятельно сформировать новый патч с помощью стандартного diff -Naur.
Практика показывает, что большинство патчей все-таки требуют доработки, переделать их автоматически с использованием --force и более мягкого значения fuzz получается не очень часто. Однако даже если rediff_patch справился со всем самостоятельно, обязательно проверьте результирующий патч — ведь '--force' иногда может привести к нежелательному результату. А если rediff_patch не справился — что ж, по крайней мере, мы немного сэкономим на распаковке архива и первой попытке применить патч.