18.2.5 Построение окружения сборки RPM

Если дело начато с идеи сборки пакета для нескольких версий Linux, можно установить такое окружение сборки, которое поможет четко разделить вендор-зависимые характеристики.

Ключевые темы в данном подходе:

* Определение вендора

* Использование макросов для задания процесса сборки

* Обработка различных зависимостей

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

Соглашение для файлов следующее:

/etc/vendor-release

Например:

$ more /etc/redhat-release

Red Hat Linux release 8.0 (Psyche)

Для пакетов соглашение касается имен пакетов:

$ rpm -q redhat-release

redhat-release-8.0-8

Также можно использовать простое определение макроса для имени вендора и затем опцию --define для rpmbuild. Например:

# rpmbuild ba --define 'linuxVendor suse'

С такой опцией используется макрос %linuxVendor.

Альтернативный подход - автоматическое определение вендора скриптами сборки. Ручное определение работает, однако требует введения информации от пересборщика пакета.

18.2.5.2 Построение окружения сборки и макросов
Будучи единожды установленным, значение макроса "вендор" позволяет задать другие макросы, учитывающие различия дистрибутивов, которые влияют на ваши приложения.

Для учета платформы используют главным образом условные определения, заключенные между %if и %endif. Кроме того, часто бывает полезным использование опций --with, --without и --target утилиты rpmbuild, позволяющие контролировать особенности сборки путем передачи условий в скрипты и макросы, определенные в spec-файле.

Макрос %if позволяет задать условия. Например:

%if %{old_5x} && %{old_6x}

%{error: You cannot build for .5x and .6x at the same time}

%quit

%endif

%if %{old_5x}

%define b5x 1

%undefine b6x

%endif

%if %{old_6x}

%define b6x 1

%undefine b5x

%endif

Также %if можно использовать для настройки таких полей, как
Requires: (показано в нижеследующем примере):

%if %{build6x}

Requires: util-linux, pam >= 0.66-5

%else

Requires: util-linux, pam >= 0.75-37, /etc/pam.d/system-auth

%endif

Опция командной строки --with задает значение специального макроса _with_. Например, следующая команда вносит установки в макросы spec-файла:

Также %if можно использовать для настройки таких полей, как
Requires: (показано в нижеследующем примере):

$ rpmbuild bc --with ssh filename.spec

В этом примере значение макроса _with_ssh будет установлено в значение --with-ssh. Этот формат задан специально для конфигурирования в стиле GNU (формат опции скрипта configure). Такой подход широко используется для условной, платформеннозависимой сборки.

Подобно опции --with, опция командной строки --without определяет значение специального макроса with _without_. Он определяет области кода, которые не будут использованы.

Часто комбинируют --with и --without для повышения гибкости этого шаблона. Кроме того, ветвление можно образовать с помощью проверки значения. Например:

./configure %{?_with_ssh}

Если макрос _with_ssh определен, команда будет такой:

./configure --with-ssh

Если макрос не определен, тогда такой:

./configure

Опция командной строки --target в свою очередь определяет макросы %_target, %_target_arch и %_target_os. Например:

$ rpmbuild -bc --target ppc-ibm-aix /usr/src/redhat/SPECS/jikes.spec

18.2.5.3 Пакеты совместимости (compatibility packages) и ассоциативные пакеты (glue packages)
Все дистрибутивы Linux имеют отличия. Только макросы не в состоянии покрыть все эти отличия для полной унификации сборки и получаемых пакетов. Тем не менее проблемы должны быть решены и многие из них решаются с помощью пакетов совместимости и ассоциативных пакетов.

Пакет совместимости предоставляет старый, унаследованный API для новой системы, которая больше не поддерживает старый API. В соответствии с соглашением пакеты совместимости для основного пакета именуются compat-имя_пакета.

Например:

$ rpm -q --qf "%{description}" compat-libstdc++

The compat-libstdc++ package contains compatibility Standard C++

Использование compat- пакетов позволяет создавать программы, использующие подход наименьшего общего знаменателя и программировать для старых, но наиболее общих API. Если некоторые дистрибутивы исключают пакеты со старыми API, compat- пакеты могут предоставить эти API.

Подобно compat- пакетам, ассоциативные или glue- пакеты предоставляют зависимости, которые присутствуют в одних дистрибутивах и отсутствуют в других. Они помогают "приклеить" ваш пакет к конкретному дистрибутиву, в котором недостает нужных зависимостей.

Основная цель пакетов совместимости и ассоциативных пакетов - в как можно большей степени оставить исходный пакет приложения в неприкосновенности, чтобы он был как можно ближе к версии вендора, выпустившего пакет. compat- и glue- подходы позволяют обеспечить работоспособность исходного приложения в других системах.

Таким образом, приложения, разработанные для Linux демонстрируют высокую степень адаптивности к разным дистрибутивам, кроме того, огромный пул ПО работоспособен (и имеются соответствующие бинарные пакеты) на различных процессорных архитектурах, таких как SPARC, MIPS, ARM.

Далее - Работа с не-rpmbased дистрибутивами
Назад - Создание пакетов с переопределимыми путями
Содержание