ALT Packaging HOWTO: различия между версиями

Материал из ALT Linux Wiki
Нет описания правки
Нет описания правки
Строка 42: Строка 42:
{{rpmmacro|_optflags_optimization}}: параметры, отвечающие за оптимизацию, кроме архитектурно-зависимых
{{rpmmacro|_optflags_optimization}}: параметры, отвечающие за оптимизацию, кроме архитектурно-зависимых


{{rpmmacro|_optflags_warnings}}: warning options
{{rpmmacro|_optflags_warnings}}: ''warning options''


{{rpmmacro|_optflags_debug}}: debugging options
{{rpmmacro|_optflags_debug}}: ''debugging options''


{{rpmmacro|_optflags_shared}}: параметры, применяемые для создания relocatable файлов
{{rpmmacro|_optflags_shared}}: параметры, применяемые для создания relocatable файлов
Строка 50: Строка 50:
{{rpmmacro|_optflags_nocpp}}: параметры, отключающие поддержку C++ exceptions и C++ RTTI
{{rpmmacro|_optflags_nocpp}}: параметры, отключающие поддержку C++ exceptions и C++ RTTI


{{rpmmacro|_optflags_notraceback}}: -fomit-frame-pointer
{{rpmmacro|_optflags_notraceback}}: ''-fomit-frame-pointer''
   
   
{{rpmmacro|_optflags_fastmath}}: -ffast-math
{{rpmmacro|_optflags_fastmath}}: ''-ffast-math''


{{rpmmacro|_optflags_strict}}: -fstrict-aliasing
{{rpmmacro|_optflags_strict}}: ''-fstrict-aliasing''


{{rpmmacro|_optflags_kernel}}: параметры, используемые при компиляции ядра и его модулей.
{{rpmmacro|_optflags_kernel}}: параметры, используемые при компиляции ядра и его модулей.
Строка 114: Строка 114:
'''Вызов вспомогательных программ.'''
'''Вызов вспомогательных программ.'''


%find_lang:
{{rpmmacro|find_lang}}: вызов ''/usr/lib/rpm/find-lang''
    вызов /usr/lib/rpm/find-lang  
%strip_executable:
{{rpmmacro|strip_executable}}: вызов ''/usr/lib/rpm/brp-strip'' для обработки ELF executables
    вызов /usr/lib/rpm/brp-strip для обработки ELF executables;
 
%strip_relocatable:
{{rpmmacro|strip_relocatable}}: вызов ''/usr/lib/rpm/brp-strip'' для обработки ELF relocatables  
    вызов /usr/lib/rpm/brp-strip для обработки ELF relocatables;
{{rpmmacro|strip_shared}}: вызов ''/usr/lib/rpm/brp-strip'' для обработки ELF shared objects
%strip_shared:
    вызов /usr/lib/rpm/brp-strip для обработки ELF shared objects;
{{rpmmacro|strip_static}}: вызов ''/usr/lib/rpm/brp-strip'' для обработки ELF ar archives
%strip_static:
{{rpmmacro|cleanup_build}}: вызов ''/usr/lib/rpm/brp-cleanup''
    вызов /usr/lib/rpm/brp-strip для обработки ELF ar archives;
{{rpmmacro|compress_docs}}: вызов ''/usr/lib/rpm/brp-compress''
%cleanup_build:
{{rpmmacro|strip_binaries}}: вызов ''/usr/lib/rpm/brp-strip''
    вызов /usr/lib/rpm/brp-cleanup;
{{rpmmacro|clean_buildroot}}: выполнение ''rm -rf %buildroot'', если ''%buildroot'' не указывает на настоящий ''/''.  
%compress_docs:
    вызов /usr/lib/rpm/brp-compress;
%strip_binaries:
    вызов /usr/lib/rpm/brp-strip;
%clean_buildroot:
    выполнение rm -rf %buildroot, если %buildroot не указывает на настоящий /.  


'''Управление процессом сборки.'''
'''Управление процессом сборки.'''


%buildmulti:
{{rpmmacro|buildmulti}}: Альтернативная директива ''%build'' для случая, когда в секции ''%build'' происходит заполнение ''%buildroot''. Вообще говоря, такой техники стоит избегать во всех случаях, когда это возможно.  
    Альтернативная директива %build для случая, когда в секции %build происходит заполнение %buildroot. Вообще говоря, такой техники стоит избегать во всех случаях, когда это возможно.  


'''Версии некоторых установленных в системе пакетов.'''
'''Версии некоторых установленных в системе пакетов.'''


glibc:
'''glibc''': {{rpmmacro|__glibc_version}}, {{rpmmacro|__glibc_version_major}}, {{rpmmacro|__glibc_version_minor}}
    %__glibc_version, %__glibc_version_major, %__glibc_version_minor;
 
python:
'''python''': {{rpmmacro|__python_version}}
    %__python_version;
 
%get_version:
{{rpmmacro|get_version}}: Версия указанного пакета  
    Версия указанного пакета;
 
%get_release:
{{rpmmacro|get_release}}: Релиз указанного пакета
    Релиз указанного пакета;
%get_serial:
{{rpmmacro|get_serial}}: Serial указанного пакета
    Serial указанного пакета;
 
%add_serial:
{{rpmmacro|add_serial}}: Serial указанного пакета в виде, пригодном для включения в ''spec''-файл.  
    Serial указанного пакета в виде, пригодном для включения в spec-файл.  


Эти макросы, как правило, используются в пакетах, сборка которых возможна с различными версиями этих программ, если эти версии правильно учитывать.
Эти макросы, как правило, используются в пакетах, сборка которых возможна с различными версиями этих программ, если эти версии правильно учитывать.
Строка 157: Строка 149:
'''Прочие макросы.'''
'''Прочие макросы.'''


%intel:
{{rpmmacro|intel}}: список архитектур ''intel'', совместимых с ''i386''
    список архитектур intel, совместимых с i386;
%amd:
{{rpmmacro|amd}}: список архитектур ''amd'', совместимых с ''i386''
    список архитектур amd, совместимых с i386;
 
%ix86:
{{rpmmacro|ix86}}: список всех архитектур, совместимых с ''i386''
    список всех архитектур, совместимых с i386;
компоненты макроса %packager:
компоненты макроса {{rpmmacro|packager}}: {{rpmmacro|packagerName}}, {{rpmmacro|packagerAddress}}.  
    %packagerName, %packagerAddress.  


==== Новыe параметры rpm. ====
==== Новыe параметры rpm. ====


-bE:
-'''bE''': новый режим работы ''rpm'', при котором происходит только подстановка макросов
    новый режим работы rpm, при котором происходит только подстановка макросов;
 
-nowait-lock:
-'''nowait-lock''': не блокировать процесс, если база данных ''rpm'' занята  
    не блокировать процесс, если база данных rpm занята;
 
-fancypercent:
-'''fancypercent''': отображать дополнительную информацию о процентах проделанной работы при установке/обновлении пакетов.  
    отображать дополнительную информацию о процентах проделанной работы при установке/обновлении пакетов.  


==== Новые возможности rpm. ====
==== Новые возможности rpm. ====


'''Автоматический поиск требуемых и предоставляемых зависимостей.'''
'''Автоматический поиск требуемых и предоставляемых зависимостей.'''
В дополнение к стандартному поиску зависимостей от/для разделяемых библиотек, реализована поддержка поиска требуемых зависимостей для shell и perl-скриптов, а также поддержка поиска предоставляемых зависимостей для perl-скриптов.
 
В дополнение к стандартному поиску зависимостей от/для разделяемых библиотек, реализована поддержка поиска требуемых зависимостей для ''shell'' и ''perl''-скриптов, а также поддержка поиска предоставляемых зависимостей для ''perl''-скриптов.


'''Изменение семантики тэгов, управляющих поиском зависимостей.'''
'''Изменение семантики тэгов, управляющих поиском зависимостей.'''
Новые возможности rpm по автоматическому поиску зависимостей при сборке пакетов управляются, как и прежде, значениями тэгов AutoReq, AutoProv и AutoReqProv. К стандартным значениям yes/no (true/false), таким образом, добавлены новые возможные значения, являющиеся именами методов поиска зависимостей:


    * lib: включение поиска зависимостей от/для разделяемых библиотек;
Новые возможности ''rpm'' по автоматическому поиску зависимостей при сборке пакетов управляются, как и прежде, значениями тэгов ''AutoReq'', ''AutoProv'' и ''AutoReqProv''. К стандартным значениям ''yes/no'' (''true/false''), таким образом, добавлены новые возможные значения, являющиеся именами методов поиска зависимостей:
    * shell: включение поиска зависимостей в shell-скриптах;
 
    * perl: включение поиска зависимостей в perl-скриптах;
*''lib'': включение поиска зависимостей от/для разделяемых библиотек
    * nolib: выключение поиска зависимостей от/для разделяемых библиотек;
*''shell'': включение поиска зависимостей в ''shell''-скриптах
    * noshell: выключение поиска зависимостей в shell-скриптах;
*''perl'': включение поиска зависимостей в ''perl''-скриптах
    * noperl: выключение поиска зависимостей в perl-скриптах;
*''nolib'': выключение поиска зависимостей от/для разделяемых библиотек
    * default: то же, что и yes;
*''noshell'': выключение поиска зависимостей в ''shell''-скриптах
    * none,off: то же, что и no;
*''noperl'': выключение поиска зависимостей в ''perl''-скриптах
    * all: включение всех возможных методов поиска зависимостей.
*''default'': то же, что и ''yes'';
*''none,off'': то же, что и ''no'';
*''all'': включение всех возможных методов поиска зависимостей.
 
Значением тэга может являться как один метод, так и перечисление методов. По умолчанию, для каждого под пакета собираемого пакета ''AutoReq'' = ''AutoProv'' = ''yes'', что на практике означает использование макросов
{{rpmmacro|findreq_default_method}} и {{rpmmacro|findprov_default_method}} для определения методов поиска зависимостей.


Значением тэга может являться как один метод, так и перечисление методов. По умолчанию, для каждого под пакета собираемого пакета AutoReq = AutoProv = yes, что на практике означает использование макросов %_findreq_default_method и %_findprov_default_method для определения методов поиска зависимостей.
'''Автоматическое сжатие ''man'' и ''info''-документации с поддержкой различных методов сжатия.'''


'''Автоматическое сжатие man и info-документации с поддержкой различных методов сжатия.'''
Вся документация пакета, распознаваемая как ''man'' или ''info''-документация, по окончании работы секции ''%install'', сжимается согласно выбранному методу. Поддерживаются следующие методы сжатия:
Вся документация пакета, распознаваемая как man или info-документация, по окончании работы секции %install, сжимается согласно выбранному методу. Поддерживаются следующие методы сжатия:


    * bzip2: сжатие с помощью ``bzip2 -9'';
*''bzip2'': сжатие с помощью ''bzip2 -9''
    * gzip: сжатие с помощью ``gzip -9n'';
*''gzip'': сжатие с помощью ''gzip -9n''
    * auto: сжатие с помощью ``gzip -9n'' либо ``bzip2 -9'' в зависимости от того, какой вариант окажется эффективнее;
*''auto'': сжатие с помощью ''gzip -9n'' либо ''bzip2 -9'' в зависимости от того, какой вариант окажется эффективнее
    * none: производится декомпрессия файлов вместо сжатия;
*''none'': производится декомпрессия файлов вместо сжатия
    * skip: процедура сжатия пропускается полностью.
*''skip'': процедура сжатия пропускается полностью.


Какой метод будет использован в каждом конкретном случае, зависит от значения макроса %_compress_method; значение по умолчанию для этого макроса - auto. По окончании процедуры сжатия производится выравнивание ссылок, которые, возможно, требуют коррекции в связи с изменениями имен файлов в процессе их сжатия.
Какой метод будет использован в каждом конкретном случае, зависит от значения макроса {{rpmmacro|_compress_method}}; значение по умолчанию для этого макроса - ''auto''. По окончании процедуры сжатия производится выравнивание ссылок, которые, возможно, требуют коррекции в связи с изменениями имен файлов в процессе их сжатия.


'''Автоматическое удаление отладочной информации из ELF-файлов с поддержкой различных стратегий выбора файлов, подлежащих обработке.'''
'''Автоматическое удаление отладочной информации из ELF-файлов с поддержкой различных стратегий выбора файлов, подлежащих обработке.'''
Зачастую возможно уменьшить размер получаемых в результате сборки пакета ELF-файлов без потери качества за счет удаления из них отладочной информации. Поэтому по окончании работы секции %install все ELF-файлы выбранных типов обрабатываются программой strip. Выбор типов файлов определяется значением макроса %_strip_method, которое есть набор из следующих возможных значений:


    * executable: ELF executable;
Зачастую возможно уменьшить размер получаемых в результате сборки пакета ELF-файлов без потери качества за счет удаления из них отладочной информации. Поэтому по окончании работы секции ''%install'' все ELF-файлы выбранных типов обрабатываются программой ''strip''. Выбор типов файлов определяется значением макроса {{rpmmacro|_strip_method}}, которое есть набор из следующих возможных значений:
    * relocatable: ELF relocatable;
    * shared: ELF shared object;
    * static: ar archive.


Кроме того, есть возможность вызывать strip вручную, для этой цели предназначены макросы %strip_executable, %strip_relocatable, %strip_shared, %strip_static. Синтаксис этих макросов подробно изложен в ``/usr/lib/rpm/brp-strip -help''.
*''executable'': ELF executable;
*''relocatable'': ELF relocatable;
*''shared'': ELF shared object;
*''static'': ar archive.
 
Кроме того, есть возможность вызывать ''strip'' вручную, для этой цели предназначены макросы {{rpmmacro|strip_executable}}, {{rpmmacro|strip_relocatable}}, {{rpmmacro|strip_shared}}, {{rpmmacro|strip_static}}. Синтаксис этих макросов подробно изложен в ''/usr/lib/rpm/brp-strip -help''.


'''Автоматическая перекомпиляция python-модулей.'''
'''Автоматическая перекомпиляция python-модулей.'''
Как известно, python-модули обычно компилируют в байтовую форму для увеличения быстродействия при последующей работе с ними. Каждый такой модуль, помимо всего прочего, хранит время своего создания и полное имя файла, в котором должен находиться. В связи с последним обстоятельством скомпилированные модули, созданные в результате работы секции %install, непригодны, ибо не могут быть использованы после установки пакета. По этой причине теперь по окончании работы секции %install производится перекомпиляция всех python-модулей таким образом, чтобы их можно было использовать после установки пакета. В качестве байт-компилятора будет использоваться программа, имя которой хранится в макросе %__python. Обычно это /usr/bin/python, однако в некоторых случаях может потребоваться изменить это значение на другое (например, в случае сборки пакета python или если по какой-то причине перекомпиляция не нужна).
 
Как известно, python-модули обычно компилируют в байтовую форму для увеличения быстродействия при последующей работе с ними. Каждый такой модуль, помимо всего прочего, хранит время своего создания и полное имя файла, в котором должен находиться. В связи с последним обстоятельством скомпилированные модули, созданные в результате работы секции ''%install'', непригодны, ибо не могут быть использованы после установки пакета. По этой причине теперь по окончании работы секции ''%install'' производится перекомпиляция всех python-модулей таким образом, чтобы их можно было использовать после установки пакета. В качестве байт-компилятора будет использоваться программа, имя которой хранится в макросе {{rpmmacro|__python}}. Обычно это ''/usr/bin/python'', однако в некоторых случаях может потребоваться изменить это значение на другое (например, в случае сборки пакета python или если по какой-то причине перекомпиляция не нужна).


'''BuildRoot.'''
'''BuildRoot.'''
Времена, когда тэг BuildRoot в spec-файле определял, какой каталог rpm будет использовать в качестве BuildRoot, прошли безвозвратно. Теперь этот таг не несет никакой информации и может (и должен) быть опущен. Вместо этого используется значение макроса %buildroot, который определен как ``%{_tmppath}/%{name}-buildroot'' в файле /usr/lib/rpm/macros и может быть переопределен в любом месте, где допускается определять макросы. В случае, если макрос %buildroot не определен либо его значение представляет собой недопустимое значение ``/'', сборка пакета не будет выполнена.
 
Времена, когда тэг ''BuildRoot'' в ''spec''-файле определял, какой каталог ''rpm'' будет использовать в качестве ''BuildRoot'', прошли безвозвратно. Теперь этот таг не несет никакой информации и может (и должен) быть опущен. Вместо этого используется значение макроса {{rpmmacro|buildroot}}, который определен как ''%{_tmppath}/%{name}-buildroot'' в файле ''/usr/lib/rpm/macros'' и может быть переопределен в любом месте, где допускается определять макросы. В случае, если макрос {{rpmmacro|buildroot}} не определен либо его значение представляет собой недопустимое значение ''/'', сборка пакета не будет выполнена.


'''Автоматическая очистка BuildRoot.'''
'''Автоматическая очистка BuildRoot.'''
Перед выполнением секции %install и по окончании выполнения секции %clean rpm автоматически очищает BuildRoot с помощью макроса %clean_buildroot. Это значит, что больше не нужно использовать эти ужасные ``rm -rf $RPM_BUILD_ROOT''. Секция %clean вообще может (и должна) быть опущена, если в ней не содержится ничего, кроме этого ``rm''. В тех редких случаях, когда в spec-файле производится заполнение BuildRoot не в секции %install, как это должно быть, а в секции %build, что в принципе неправильно, можно перенести точку очистки BuildRoot из начала секции %install в начало секции %build, если заменить директиву %build на макрос %buildmulti.
 
Перед выполнением секции ''%install'' и по окончании выполнения секции ''%clean'' ''rpm'' автоматически очищает ''BuildRoot'' с помощью макроса {{rpmmacro|clean_buildroot}}. Это значит, что больше не нужно использовать эти ужасные ''rm -rf $RPM_BUILD_ROOT''. Секция ''%clean'' вообще может (и должна) быть опущена, если в ней не содержится ничего, кроме этого ''rm''. В тех редких случаях, когда в ''spec''-файле производится заполнение ''BuildRoot'' не в секции ''%install'', как это должно быть, а в секции ''%build'', что в принципе неправильно, можно перенести точку очистки ''BuildRoot'' из начала секции ''%install'' в начало секции ''%build'', если заменить директиву ''%build'' на макрос {{rpmmacro|buildmulti}}.


'''Упрощение секции %files.'''
'''Упрощение секции %files.'''
Ранее в начале каждой секции %files было необходимо указывать атрибуты файлов и каталогов создаваемых пакетов с помощью довольно однообразно используемой директивы %defattr. Теперь это происходит автоматически в начале каждой секции %files, а также в начале каждого файла, включаемого в секцию %files с помощью опции -f. Точнее говоря, в качестве этой директивы используется значение макроса %_defattr. Таким образом, прежнее использование директивы %defattr в начале секций и файлов следует считать упраздненным.
Ранее в начале каждой секции %files было необходимо указывать атрибуты файлов и каталогов создаваемых пакетов с помощью довольно однообразно используемой директивы %defattr. Теперь это происходит автоматически в начале каждой секции %files, а также в начале каждого файла, включаемого в секцию %files с помощью опции -f. Точнее говоря, в качестве этой директивы используется значение макроса %_defattr. Таким образом, прежнее использование директивы %defattr в начале секций и файлов следует считать упраздненным.


'''Сборка пакетов привилегированным пользователем.'''
'''Сборка пакетов привилегированным пользователем.'''
То, что когда-то было необходимостью, со временем стало излишним, а порой и просто опасным. Теперь, когда все пакеты, кроме одного-единственного MAKEDEV, можно (и нужно) собирать непривилегированным пользователем во избежание риска разрушения системы и некорректной сборки, сборка пакетов привилегированным пользователем по умолчанию запрещена. Этот запрет можно снять путем изменения значения макроса %_allow_root_build.
 
То, что когда-то было необходимостью, со временем стало излишним, а порой и просто опасным. Теперь, когда все пакеты, кроме одного-единственного MAKEDEV, можно (и нужно) собирать непривилегированным пользователем во избежание риска разрушения системы и некорректной сборки, сборка пакетов привилегированным пользователем по умолчанию запрещена. Этот запрет можно снять путем изменения значения макроса {{rpmmacro|_allow_root_build}}.


=== Пожелания packager'у. ===
=== Пожелания packager'у. ===
==== Устаревшие конструкции. ====
==== Устаревшие конструкции. ====
Не следует использовать устаревшие конструкции - они лишь загромождают spec-файл, снижая тем самым его читабельность. К устаревшим конструкциям, в частности, относятся:
 
тэг BuildRoot:;
Не следует использовать устаревшие конструкции - они лишь загромождают ''spec''-файл, снижая тем самым его читабельность. К устаревшим конструкциям, в частности, относятся:
cтроки вида rm -rf $RPM_BUILD_ROOT;
тэг ''BuildRoot:''
%_defattr со стандартными аргументами в начале файлов и секций %files;
cтроки вида ''rm -rf $RPM_BUILD_ROOT''
секция %clean, пустая либо без разумного содержания.
{{rpmmacro|_defattr}} со стандартными аргументами в начале файлов и секций ''%files''
секция ''%clean'', пустая либо без разумного содержания.


==== Фигурные скобки. ====
==== Фигурные скобки. ====
Нет смысла засорять текст spec-файла ненужными фигурными скобками. Избавится от них легко:
Нет смысла засорять текст spec-файла ненужными фигурными скобками. Избавится от них легко:


perl -pi -e 's/%\{([A-Za-z_0-9]+)\}([^A-Za-z_0-9?*]|$)/%$1$2/g' spec-файл
''perl -pi -e 's/%\{([A-Za-z_0-9]+)\}([^A-Za-z_0-9?*]|$)/%$1$2/g' spec''-файл


==== Порядок тэгов. ====
==== Порядок тэгов. ====
Рекомендуемый порядок заголовочных тэгов: Name, Version, Release, Serial, далее Summary, License, Group, Url, Packager, BuildArch, потом Source, Patch, далее Provides, Requires, PreReqs, Conflicts, и, наконец, Prefix, BuildPreReqs, BuildRequires. Разумеется, не все из вышеперечисленных тэгов, как правило, используются, равно как встречаются и другие редко используемые тэги. В связи с тем, что BuildRequires зарезервирован для автоматически вычисляемых зависимостей, для указания особых зависимостей следует использовать BuildPreReq.
 
Рекомендуемый порядок заголовочных тэгов:  
*Name
*Version
*Release
*Serial
 
далее
 
*Summary
*License
*Group
*Url
*Packager
*BuildArch
 
потом  
 
*Source
*Patch
 
далее
 
*Provides
*Requires
*PreReqs
*Conflicts
и, наконец,
 
*Prefix
*BuildPreReqs
*BuildRequires.
 
Разумеется, не все из вышеперечисленных тэгов, как правило, используются, равно как встречаются и другие редко используемые тэги. В связи с тем, что ''BuildRequires'' зарезервирован для автоматически вычисляемых зависимостей, для указания особых зависимостей следует использовать ''BuildPreReq''.
 
==== Файлы локализации. ====
==== Файлы локализации. ====
Если в состав пакета входят файлы локализации либо другие файлы на разных языках, стоит использовать макрос %find_lang. Подробная информация есть в ``/usr/lib/rpm/find-lang -h''
 
Группы.
Если в состав пакета входят файлы локализации либо другие файлы на разных языках, стоит использовать макрос {{rpmmacro|find_lang}}. Подробная информация есть в ''/usr/lib/rpm/find-lang -h''
Следите за значением тэгов Group: они должны соответствовать действительности и при этом принадлежать фиксированному множеству, перечисленному в файле /usr/lib/rpm/GROUPS.
 
==== Группы. ====
 
Следите за значением тэгов ''Group'': они должны соответствовать действительности и при этом принадлежать фиксированному множеству, перечисленному в файле ''/usr/lib/rpm/GROUPS''.
 
==== Внутрипакетные зависимости. ====
==== Внутрипакетные зависимости. ====
При работе с мультипакетными spec-файлами соблюдайте правило внутрипакетных зависимостей: Если один пакет в какой-либо мере зависит от другого подпакета, то эта зависимость должна быть указана полностью, включая не только имя, но также верcию, релиз и serial (если есть). Например, ``Requires: %name = %version-%release''. Обратите внимание на синтаксис: знак равенства, в отличие от дефиса, окружен пробелами.
 
При работе с мультипакетными spec-файлами соблюдайте правило внутрипакетных зависимостей: Если один пакет в какой-либо мере зависит от другого подпакета, то эта зависимость должна быть указана полностью, включая не только имя, но также верcию, релиз и serial (если есть). Например, ''Requires: %name = %version-%release''. Обратите внимание на синтаксис: знак равенства, в отличие от дефиса, окружен пробелами.
 
==== Разделяемые библиотеки. ====
==== Разделяемые библиотеки. ====
Пакеты, содержащие как разделяемые библиотеки, так и использующие их программы, должны быть разделены на подпакеты таким образом, чтобы в подпакет, содержащий разделяемые библиотеки, не входили использующие их программы. Это позволит уменьшить количество циклических зависимостей. По традиции, имена пакетов, состоящих только из разделяемых библиотек, должны начинаться с префикса ``lib`` либо содержать его внутри слова. При разделении подпакетов следует помнить о внутрипакетных зависимостях.
 
Пакеты, содержащие как разделяемые библиотеки, так и использующие их программы, должны быть разделены на подпакеты таким образом, чтобы в подпакет, содержащий разделяемые библиотеки, не входили использующие их программы. Это позволит уменьшить количество циклических зависимостей. По традиции, имена пакетов, состоящих только из разделяемых библиотек, должны начинаться с префикса ''lib'' либо содержать его внутри слова. При разделении подпакетов следует помнить о внутрипакетных зависимостях.
 
==== Статические библиотеки. ====
==== Статические библиотеки. ====
Статические библиотеки должны паковаться в отдельные подпакеты, что связано со спецификой их использования. Если имя devel-подпакета заканчивается суффиксом -devel, то имя нового devel-static-подпакета будет заканчиваться суффиксом -devel-static. При разделении подпакетов следует помнить о внутрипакетных зависимостях: В списке зависимостей devel-static-подпакета должна присутствовать зависимость от -devel = %version-%release.
 
Переименование пакетов.
Статические библиотеки должны паковаться в отдельные подпакеты, что связано со спецификой их использования. Если имя ''devel''-подпакета заканчивается суффиксом ''-devel'', то имя нового ''devel-static''-подпакета будет заканчиваться суффиксом ''-devel-static''. При разделении подпакетов следует помнить о внутрипакетных зависимостях: В списке зависимостей ''devel-static''-подпакета должна присутствовать зависимость от ''-devel = %version-%release''.
 
==== Переименование пакетов. ====
 
Иногда пакеты переименовывают. Например, это случается при упаковке разделяемых библиотек. В таких случаях следует указывать правильную информацию о зависимостях, необходимую для корректного обновления. В частности, дожен присутствовать:
Иногда пакеты переименовывают. Например, это случается при упаковке разделяемых библиотек. В таких случаях следует указывать правильную информацию о зависимостях, необходимую для корректного обновления. В частности, дожен присутствовать:
тэг Provides: старое_имя = %version
тэг ''Provides: старое_имя = %version''
тэг Obsoletes: старое_имя
тэг ''Obsoletes: старое_имя''


==== Литература ====
==== Литература ====
Официальный web-сайт rpm: http://www.rpm.org/
Официальный web-сайт rpm: http://www.rpm.org/



Версия от 14:28, 24 сентября 2009

ALT Packaging HOWTO (revision 0.3)

Dmitry V. Levin <ldv@altlinux.ru> ALT Linux Team

Введение

При разработке изменений и дополнений к rpm решались следующие задачи:

  • Обеспечить желаемую функциональность:

наши пакеты должны отвечать определенным правилам, о которых пойдет речь несколько позже. Для этого надо, чтобы spec-файлы обеспечивали выполнение этих правил.

  • Помочь разработчику:

так как spec-файлы все еще пишут люди, то их работу нужно свести к тому минимуму, который, собственно, и требует участия человека. Разработчик не должен копировать блоки кода из файла в файл, ибо эта неинтеллектуальная работа отнимает массу сил и чревата ошибками. Для этого есть макросы. Если какой-то код появляется в разных spec-файлах более одного раза, то надо написать макрос(ы).

  • Сделать spec-файлы более читабельными:

те, кто эти файлы читает - тоже живые люди. Им будет удобнее, если в наименовании, расположении и использовании различных элементов spec-файлов будет определенный порядок.

Особенности этой версии rpm

Новые макросы

Макросы для часто используемых каталогов.

Управление опциями компилятора gcc.

%_add_optflags <options>: добавить указанные параметры в стандартный набор %_%opflags

%_remove_optflags <options>: убрать указанные параметры из стандартного набора %_%opflags

%_optflags_core: базовые параметры

%__optlevel: уровень оптимизации

%_optflags_optimization: параметры, отвечающие за оптимизацию, кроме архитектурно-зависимых

%_optflags_warnings: warning options

%_optflags_debug: debugging options

%_optflags_shared: параметры, применяемые для создания relocatable файлов

%_optflags_nocpp: параметры, отключающие поддержку C++ exceptions и C++ RTTI

%_optflags_notraceback: -fomit-frame-pointer

%_optflags_fastmath: -ffast-math

%_optflags_strict: -fstrict-aliasing

%_optflags_kernel: параметры, используемые при компиляции ядра и его модулей.

По умолчанию, стандартный набор %_opflags состоит из "%_optflags_core %_optflags_warnings %_ptflags_optimization".

Макросы-надстройки над утилитой make.

%_make_build: вызов make с параметром, обеспечивающим оптимальную параллельную сборку в данной среде

%_make_install: вызов make c инициализацией переменной INSTALL, что в случае корректной реализации Makefileов пакета позволяет сохранить дату последней модификации файлов, что особенно важно для документации;

%_makeinstall: %make_install <инициализация других переменных, используемых многими Makefileами> install.

Регистрация документации в формате info.

%_install_info: регистрация новых/обновленных info-страниц

%_uninstall_info: отмена регистрации удаленных info-страниц.

Регистрация меню.

%_update_menus: регистрация новых/обновленных меню

%_clean_menus: отмена регистрации удаленных меню.

Вспомогательные макросы %configure.

%__libtoolize: путь к скрипту libtoolize

%_configure_script: путь к скрипту configure

%_configure_target: целевая платформа для configure

%_configure_gettext: -without-included-gettext.

Серверные макросы.

%_post_service: регистрация нового сервиса при установке, перезапуск при обновлении

%_preun_service: отмена регистрации сервиса и его выключение при удалении.

Макросы, определяющие некоторые аспекты packaging policy.

%buildroot: значение BuildRoot

%_defattr: атрибуты файлов и каталогов по умолчанию для каждой секции %files и для каждого файла, включаемого в этих секциях

%_compress_method: метод, используемый при сжатии документации в секции %install

%_strip_method: метод, используемый при обработке ELF-файлов в секции %install

%_findreq_default_method: метод, используемый по умолчанию при поиске требуемых зависимостей

%_findprov_default_method: метод, используемый по умолчанию при поиске предоставляемых зависимостей

%_set_strip_method: изменить значение макроса %_strip_method

Вызов вспомогательных программ.

%find_lang: вызов /usr/lib/rpm/find-lang

%strip_executable: вызов /usr/lib/rpm/brp-strip для обработки ELF executables

%strip_relocatable: вызов /usr/lib/rpm/brp-strip для обработки ELF relocatables %strip_shared: вызов /usr/lib/rpm/brp-strip для обработки ELF shared objects

%strip_static: вызов /usr/lib/rpm/brp-strip для обработки ELF ar archives %cleanup_build: вызов /usr/lib/rpm/brp-cleanup %compress_docs: вызов /usr/lib/rpm/brp-compress %strip_binaries: вызов /usr/lib/rpm/brp-strip %clean_buildroot: выполнение rm -rf %buildroot, если %buildroot не указывает на настоящий /.

Управление процессом сборки.

%buildmulti: Альтернативная директива %build для случая, когда в секции %build происходит заполнение %buildroot. Вообще говоря, такой техники стоит избегать во всех случаях, когда это возможно.

Версии некоторых установленных в системе пакетов.

glibc: %__glibc_version, %__glibc_version_major, %__glibc_version_minor

python: %__python_version

%get_version: Версия указанного пакета

%get_release: Релиз указанного пакета

%get_serial: Serial указанного пакета

%add_serial: Serial указанного пакета в виде, пригодном для включения в spec-файл.

Эти макросы, как правило, используются в пакетах, сборка которых возможна с различными версиями этих программ, если эти версии правильно учитывать.

Прочие макросы.

%intel: список архитектур intel, совместимых с i386

%amd: список архитектур amd, совместимых с i386

%ix86: список всех архитектур, совместимых с i386

компоненты макроса %packager: %packagerName, %packagerAddress.

Новыe параметры rpm.

-bE: новый режим работы rpm, при котором происходит только подстановка макросов

-nowait-lock: не блокировать процесс, если база данных rpm занята

-fancypercent: отображать дополнительную информацию о процентах проделанной работы при установке/обновлении пакетов.

Новые возможности rpm.

Автоматический поиск требуемых и предоставляемых зависимостей.

В дополнение к стандартному поиску зависимостей от/для разделяемых библиотек, реализована поддержка поиска требуемых зависимостей для shell и perl-скриптов, а также поддержка поиска предоставляемых зависимостей для perl-скриптов.

Изменение семантики тэгов, управляющих поиском зависимостей.

Новые возможности rpm по автоматическому поиску зависимостей при сборке пакетов управляются, как и прежде, значениями тэгов AutoReq, AutoProv и AutoReqProv. К стандартным значениям yes/no (true/false), таким образом, добавлены новые возможные значения, являющиеся именами методов поиска зависимостей:

  • lib: включение поиска зависимостей от/для разделяемых библиотек
  • shell: включение поиска зависимостей в shell-скриптах
  • perl: включение поиска зависимостей в perl-скриптах
  • nolib: выключение поиска зависимостей от/для разделяемых библиотек
  • noshell: выключение поиска зависимостей в shell-скриптах
  • noperl: выключение поиска зависимостей в perl-скриптах
  • default: то же, что и yes;
  • none,off: то же, что и no;
  • all: включение всех возможных методов поиска зависимостей.

Значением тэга может являться как один метод, так и перечисление методов. По умолчанию, для каждого под пакета собираемого пакета AutoReq = AutoProv = yes, что на практике означает использование макросов %findreq_default_method и %findprov_default_method для определения методов поиска зависимостей.

Автоматическое сжатие man и info-документации с поддержкой различных методов сжатия.

Вся документация пакета, распознаваемая как man или info-документация, по окончании работы секции %install, сжимается согласно выбранному методу. Поддерживаются следующие методы сжатия:

  • bzip2: сжатие с помощью bzip2 -9
  • gzip: сжатие с помощью gzip -9n
  • auto: сжатие с помощью gzip -9n либо bzip2 -9 в зависимости от того, какой вариант окажется эффективнее
  • none: производится декомпрессия файлов вместо сжатия
  • skip: процедура сжатия пропускается полностью.

Какой метод будет использован в каждом конкретном случае, зависит от значения макроса %_compress_method; значение по умолчанию для этого макроса - auto. По окончании процедуры сжатия производится выравнивание ссылок, которые, возможно, требуют коррекции в связи с изменениями имен файлов в процессе их сжатия.

Автоматическое удаление отладочной информации из ELF-файлов с поддержкой различных стратегий выбора файлов, подлежащих обработке.

Зачастую возможно уменьшить размер получаемых в результате сборки пакета ELF-файлов без потери качества за счет удаления из них отладочной информации. Поэтому по окончании работы секции %install все ELF-файлы выбранных типов обрабатываются программой strip. Выбор типов файлов определяется значением макроса %_strip_method, которое есть набор из следующих возможных значений:

  • executable: ELF executable;
  • relocatable: ELF relocatable;
  • shared: ELF shared object;
  • static: ar archive.

Кроме того, есть возможность вызывать strip вручную, для этой цели предназначены макросы %strip_executable, %strip_relocatable, %strip_shared, %strip_static. Синтаксис этих макросов подробно изложен в /usr/lib/rpm/brp-strip -help.

Автоматическая перекомпиляция python-модулей.

Как известно, python-модули обычно компилируют в байтовую форму для увеличения быстродействия при последующей работе с ними. Каждый такой модуль, помимо всего прочего, хранит время своего создания и полное имя файла, в котором должен находиться. В связи с последним обстоятельством скомпилированные модули, созданные в результате работы секции %install, непригодны, ибо не могут быть использованы после установки пакета. По этой причине теперь по окончании работы секции %install производится перекомпиляция всех python-модулей таким образом, чтобы их можно было использовать после установки пакета. В качестве байт-компилятора будет использоваться программа, имя которой хранится в макросе %__python. Обычно это /usr/bin/python, однако в некоторых случаях может потребоваться изменить это значение на другое (например, в случае сборки пакета python или если по какой-то причине перекомпиляция не нужна).

BuildRoot.

Времена, когда тэг BuildRoot в spec-файле определял, какой каталог rpm будет использовать в качестве BuildRoot, прошли безвозвратно. Теперь этот таг не несет никакой информации и может (и должен) быть опущен. Вместо этого используется значение макроса %buildroot, который определен как %{_tmppath}/%{name}-buildroot в файле /usr/lib/rpm/macros и может быть переопределен в любом месте, где допускается определять макросы. В случае, если макрос %buildroot не определен либо его значение представляет собой недопустимое значение /, сборка пакета не будет выполнена.

Автоматическая очистка BuildRoot.

Перед выполнением секции %install и по окончании выполнения секции %clean rpm автоматически очищает BuildRoot с помощью макроса %clean_buildroot. Это значит, что больше не нужно использовать эти ужасные rm -rf $RPM_BUILD_ROOT. Секция %clean вообще может (и должна) быть опущена, если в ней не содержится ничего, кроме этого rm. В тех редких случаях, когда в spec-файле производится заполнение BuildRoot не в секции %install, как это должно быть, а в секции %build, что в принципе неправильно, можно перенести точку очистки BuildRoot из начала секции %install в начало секции %build, если заменить директиву %build на макрос %buildmulti.

Упрощение секции %files.

Ранее в начале каждой секции %files было необходимо указывать атрибуты файлов и каталогов создаваемых пакетов с помощью довольно однообразно используемой директивы %defattr. Теперь это происходит автоматически в начале каждой секции %files, а также в начале каждого файла, включаемого в секцию %files с помощью опции -f. Точнее говоря, в качестве этой директивы используется значение макроса %_defattr. Таким образом, прежнее использование директивы %defattr в начале секций и файлов следует считать упраздненным.

Сборка пакетов привилегированным пользователем.

То, что когда-то было необходимостью, со временем стало излишним, а порой и просто опасным. Теперь, когда все пакеты, кроме одного-единственного MAKEDEV, можно (и нужно) собирать непривилегированным пользователем во избежание риска разрушения системы и некорректной сборки, сборка пакетов привилегированным пользователем по умолчанию запрещена. Этот запрет можно снять путем изменения значения макроса %_allow_root_build.

Пожелания packager'у.

Устаревшие конструкции.

Не следует использовать устаревшие конструкции - они лишь загромождают spec-файл, снижая тем самым его читабельность. К устаревшим конструкциям, в частности, относятся: тэг BuildRoot: cтроки вида rm -rf $RPM_BUILD_ROOT %_defattr со стандартными аргументами в начале файлов и секций %files секция %clean, пустая либо без разумного содержания.

Фигурные скобки.

Нет смысла засорять текст spec-файла ненужными фигурными скобками. Избавится от них легко:

perl -pi -e 's/%\{([A-Za-z_0-9]+)\}([^A-Za-z_0-9?*]|$)/%$1$2/g' spec-файл

Порядок тэгов.

Рекомендуемый порядок заголовочных тэгов:

  • Name
  • Version
  • Release
  • Serial

далее

  • Summary
  • License
  • Group
  • Url
  • Packager
  • BuildArch

потом

  • Source
  • Patch

далее

  • Provides
  • Requires
  • PreReqs
  • Conflicts

и, наконец,

  • Prefix
  • BuildPreReqs
  • BuildRequires.

Разумеется, не все из вышеперечисленных тэгов, как правило, используются, равно как встречаются и другие редко используемые тэги. В связи с тем, что BuildRequires зарезервирован для автоматически вычисляемых зависимостей, для указания особых зависимостей следует использовать BuildPreReq.

Файлы локализации.

Если в состав пакета входят файлы локализации либо другие файлы на разных языках, стоит использовать макрос %find_lang. Подробная информация есть в /usr/lib/rpm/find-lang -h

Группы.

Следите за значением тэгов Group: они должны соответствовать действительности и при этом принадлежать фиксированному множеству, перечисленному в файле /usr/lib/rpm/GROUPS.

Внутрипакетные зависимости.

При работе с мультипакетными spec-файлами соблюдайте правило внутрипакетных зависимостей: Если один пакет в какой-либо мере зависит от другого подпакета, то эта зависимость должна быть указана полностью, включая не только имя, но также верcию, релиз и serial (если есть). Например, Requires: %name = %version-%release. Обратите внимание на синтаксис: знак равенства, в отличие от дефиса, окружен пробелами.

Разделяемые библиотеки.

Пакеты, содержащие как разделяемые библиотеки, так и использующие их программы, должны быть разделены на подпакеты таким образом, чтобы в подпакет, содержащий разделяемые библиотеки, не входили использующие их программы. Это позволит уменьшить количество циклических зависимостей. По традиции, имена пакетов, состоящих только из разделяемых библиотек, должны начинаться с префикса lib либо содержать его внутри слова. При разделении подпакетов следует помнить о внутрипакетных зависимостях.

Статические библиотеки.

Статические библиотеки должны паковаться в отдельные подпакеты, что связано со спецификой их использования. Если имя devel-подпакета заканчивается суффиксом -devel, то имя нового devel-static-подпакета будет заканчиваться суффиксом -devel-static. При разделении подпакетов следует помнить о внутрипакетных зависимостях: В списке зависимостей devel-static-подпакета должна присутствовать зависимость от -devel = %version-%release.

Переименование пакетов.

Иногда пакеты переименовывают. Например, это случается при упаковке разделяемых библиотек. В таких случаях следует указывать правильную информацию о зависимостях, необходимую для корректного обновления. В частности, дожен присутствовать: тэг Provides: старое_имя = %version тэг Obsoletes: старое_имя

Литература

Официальный web-сайт rpm: http://www.rpm.org/

Список рассылки для разработчиков rpm: rpm-list@redhat.com

Edward C. Bailey ``Maximum RPM February 17, 1997. (доступна также online-версия по адресу http://www.rpmdp.org/rpmbook/ и в формате PostScript по адресу http://www.rpm.org/maximum-rpm.ps.gz)