Руководство по упаковке 2: GNU Hello
В этом руководстве демонстрируется упаковка RPM на примере программы GNU Hello. Хотя сама программа проста, она также включает множество сопутствующих компонентов проекта FOSS: среда настройки/сборки/установки, документация, интернационализация и т. д.
Это руководство является второй частью руководства по упаковке Fedora. Оно имеет ту же базовую структуру, что и часть 1. Если вы ещё не завершили её, пожалуйста, сделайте это, прежде чем продолжить.
Шаги в этой части аналогичны части 1. Однако у GNU Hello больше особенностей, чем у Banner, поэтому требуются некоторые обходные пути и пользовательские шаги. Особенности каждого пакета уникальны, поэтому их лучше рассматривать как примеры проблем, которые могут возникнуть при упаковке.
Установка инструментов упаковщика
Следуйте Установка инструментов упаковщика.
Создание каталога пакета
Для GNU Hello пакет можно просто назвать hello. Это также имя официального пакета GNU Hello в Fedora.
$ mkdir hello && cd hello
Внутри spec-файла
Создайте файл с именем hello.spec и вставьте следующий минимальный spec-файл. В нём уже есть теги BuildRequires для gcc и make, поскольку эта тема уже была рассмотрена в части 1. Аналогично, раздел %files уже включает результирующий двоичный файл, man-страницы, документацию и файл лицензии. Для GNU Hello все эти файлы очень похожи на соответствующие файлы в Banner и уже были рассмотрены в части 1.
Кроме того, по причинам, слишком сложным для объяснения в руководстве, в некоторых ситуациях также требуется пакет texinfo, поэтому для него добавлена строка BuildRequires.
Name: hello
Version: 2.10
Release: %autorelease
Summary: Выводит знакомое, дружелюбное приветствие
License: GPL-3.0-or-later
URL: https://www.gnu.org/software/hello/
Source: https://ftp.gnu.org/gnu/hello/hello-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
BuildRequires: texinfo
%description
Программа GNU Hello выводит знакомое, дружелюбное приветствие. Да, это
ещё одна реализация классической программы, которая печатает "Hello, world!"
при запуске.
%prep
%autosetup
%build
%configure
%make_build
%install
%make_install
%files
%{_bindir}/hello
%{_mandir}/man1/hello.1.*
%doc AUTHORS ChangeLog NEWS README THANKS TODO
%license COPYING
%changelog
%autochangelog
Загрузка исходных кодов
Загрузите исходные коды и проверьте, что они у вас есть:
$ spectool -g hello.spec $ ls *.tar.gz hello-2.10.tar.gz
Сборка пакета
$ fedpkg --release f42 mockbuild
Эта команда завершается ошибкой из-за неупакованных файлов.
Установка файлов
Как и в части 1, мы пройдёмся по списку файлов один за другим. Запускайте fedpkg --release f42 mockbuild снова после каждого изменения, чтобы видеть прогресс.
Texinfo-страницы
Installed (but unpackaged) file(s) found: /usr/share/info/dir /usr/share/info/hello.info.gz
Это Texinfo-страницы. Texinfo — это система документации, подобная man-страницам, но гораздо менее распространённая. Texinfo-страницы обрабатываются примерно так же, как и man-страницы. Каталог определяется стандартным макросом {_infodir}, поэтому руководство Texinfo можно добавить следующим образом:
%files
⋮
%{_infodir}/hello.info.*
Файл dir, создаваемый скриптом сборки GNU Hello, индексирует все texinfo-страницы в вашей системе. Поскольку установленные страницы различаются в разных системах, этот файл не может быть собран заранее и упакован. Вместо этого он должен быть создан и обновлён при установке пакета. Обновление автоматически выполняется триггерами RPM в двоичном пакете info из исходного пакета texinfo.
Чтобы предотвратить установку файла dir, удалите его из корня сборки в конце раздела %install с помощью команды rm.
Однако скрипт сборки GNU Hello создаёт файл dir только в том случае, если во время сборки установлен пакет info. Бездумное удаление файла вызовет ошибку, если пакет hello собирается в системе без пакета info. Чтобы обработать оба случая, удалите файл, если он существует:
%install
⋮
test -f %{buildroot}/%{_infodir}/dir && rm %{buildroot}/%{_infodir}/dir
Переводы
Installed (but unpackaged) file(s) found: /usr/share/locale/bg/LC_MESSAGES/hello.mo /usr/share/locale/ca/LC_MESSAGES/hello.mo /usr/share/locale/da/LC_MESSAGES/hello.mo ⋮
Поскольку наша программа использует переводы и интернационализацию, мы видим много необъявленных файлов i18n. Рекомендуемый метод для их объявления:
-
Добавьте необходимую зависимость сборки с
BuildRequires: gettext. -
Найдите имена файлов на шаге
%installс помощью%find_lang %{name}. -
Установите файлы с помощью
%files -f %{name}.lang.
После этих изменений сборка выполняется успешно.
Запуск тестов
GNU Hello, как и многие другие проекты, включает автоматический набор тестов в исходных кодах. Если это вообще возможно, набор тестов должен выполняться во время сборки RPM. Это помогает убедиться, что получена работающая сборка. Это делается путём добавления вызова набора тестов в раздел spec-файла %check%, который по порядку следует после %install. В случае GNU Hello:
%check
make check
Запустите mockbuild снова и проверьте вывод, чтобы убедиться, что тесты действительно были запущены. Что-то подобное должно быть где-то в выводе:
============================================================================ Сводка набора тестов для GNU Hello 2.10 ============================================================================ # TOTAL: 5 # PASS: 4 # SKIP: 1 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ============================================================================
Исправление автоматических зависимостей
Теперь пакет успешно собирается. Но это не означает, что файл .spec корректен.
Перечисление всех зависимостей времени сборки
Если вы внимательно прочитаете вывод сборки, вы сможете обнаружить строки, в которых упоминается команда sed:
+ /usr/bin/make -O -j4 V=1 VERBOSE=1 rm -f lib/arg-nonnull.h-t lib/arg-nonnull.h && \ sed -n -e '/GL_ARG_NONNULL/,$p' \
Поэтому вам нужно добавить эту строку рядом с другими строками BuildRequires:
BuildRequires: sed
Аналогично, изучение скрипта configure в распакованных исходных кодах, который выполняется макросом %configure, показывает, что это скрипт /bin/sh:
$ head configure #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for GNU Hello 2.10.
Таким образом, вы также должны записать эту зависимость от bash:
BuildRequires: bash
Почему bash? Потому что программа /bin/sh предоставляется пакетом bash:
$ rpm --queryformat '%{name}\n' --query --file /bin/sh
bash
Указание всех используемых зависимостей помогает сделать файл .spec устойчивым к изменениям в среде сборки. Если, например, пакет sed будет удалён из среды, этот пакет GNU Hello не сможет собраться.
Перечисление всех параметров сборки
Скрипт сборки GNU Hello, configure, имеет множество параметров сборки, которые включают или отключают дополнительные функции. Их нестандартные формы можно перечислить с помощью параметра --help:
$ ./configure --help
`configure' configures GNU Hello 2.10 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
⋮
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-silent-rules less verbose build output (undo: "make V=1")
--disable-silent-rules verbose build output (undo: "make V=0")
--enable-dependency-tracking
do not reject slow dependency extractors
--disable-dependency-tracking
speeds up one-time build
--disable-nls do not use Native Language Support
--disable-rpath do not hardcode runtime library paths
Некоторые из них уже указаны в макросах %configure и %make_build. Остальные параметры, если они важны для собираемого пакета, должны быть явно записаны в файле .spec, чтобы предотвратить их внезапные и незаметные изменения. Либо потому, что новая версия Hello меняет значение по умолчанию, либо потому, что пакет, от которого они зависят, появляется или исчезает из среды сборки.
Поэтому измените вызов %configure в разделе %build следующим образом:
%configure --enable-nls --disable-rpath
Проверка результата с помощью rpmlint
Проверка с помощью fedpkg lint выявляет проблему:
$ fedpkg --release f42 lint hello.x86_64: W: file-not-utf8 /usr/share/doc/hello/THANKS
Чтобы гарантировать чистую установку в кодировке UTF-8, файл необходимо преобразовать в %prep. Это можно сделать с помощью утилиты iconv, предоставляемой пакетом glibc-common, и инструмента mv из coreutils:
BuildRequires: coreutils BuildRequires: glibc-common ⋮ %prep ⋮ mv THANKS THANKS.old iconv --from-code=ISO-8859-1 --to-code=UTF-8 --output=THANKS THANKS.old
Запустите fedpkg lint снова и убедитесь, что предупреждение исправлено.
Полный файл hello.spec
Вот финальная версия hello.spec:
Name: hello
Version: 2.10
Release: %autorelease
Summary: Выводит знакомое, дружелюбное приветствие
License: GPL-3.0-or-later
URL: https://ftp.gnu.org/gnu/%{name}
Source: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz
BuildRequires: bash
BuildRequires: coreutils
BuildRequires: gcc
BuildRequires: gettext
BuildRequires: glibc-common
BuildRequires: make
BuildRequires: sed
BuildRequires: texinfo
%description
Программа GNU Hello выводит знакомое, дружелюбное приветствие. Да, это
ещё одна реализация классической программы, которая печатает "Hello, world!"
при запуске.
%prep
%autosetup
mv THANKS THANKS.old
iconv --from-code=ISO-8859-1 --to-code=UTF-8 --output=THANKS THANKS.old
%build
%configure --enable-nls --disable-rpath
%make_build
%install
%make_install
test -f %{buildroot}/%{_infodir}/dir && rm %{buildroot}/%{_infodir}/dir
%find_lang %{name}
%check
make check
%files -f %{name}.lang
%{_mandir}/man1/hello.1.*
%{_infodir}/hello.info.*
%{_bindir}/hello
%doc AUTHORS ChangeLog NEWS README THANKS TODO
%license COPYING
%changelog
%autochangelog
С этим файлом .spec вы должны иметь возможность успешно завершить процесс сборки и создать исходные и двоичные RPM-пакеты.
Проверка результата
Теперь вы можете проверить результат с помощью rpm, как это было сделано в части 1.
Файлы
Выведите список файлов, содержащихся в пакете:
$ rpm --query --package --list results_hello/2.10/1.fc42/hello-2.10-1.fc42.x86_64.rpm /usr/bin/hello /usr/lib/.build-id /usr/lib/.build-id/39 /usr/lib/.build-id/39/c97ecb15c6292ce23e8b00e15e6e72a61e5072 /usr/share/doc/hello /usr/share/doc/hello/AUTHORS ⋮ /usr/share/doc/hello/TODO /usr/share/info/hello.info.gz /usr/share/licenses/hello /usr/share/licenses/hello/COPYING /usr/share/locale/bg/LC_MESSAGES/hello.mo ⋮ /usr/share/locale/zh_TW/LC_MESSAGES/hello.mo /usr/share/man/man1/hello.1.gz
Вы можете видеть, что все файлы, перечисленные в разделе %files spec-файла, включены, включая автоматически обработанные файлы локалей. Также присутствует файл .build-id, как и в части 1.
Зависимости и предоставляемые возможности
Вы можете вывести список зависимостей времени выполнения пакета и предоставляемых им возможностей с помощью следующих двух команд. Вывод аналогичен соответствующему выводу в части 1.
$ rpm --query --package --requires results_hello/2.10/1.fc42/hello-2.10-1.fc42.x86_64.rpm $ rpm --query --package --provides results_hello/2.10/1.fc42/hello-2.10-1.fc42.x86_64.rpm
Want to help? Learn how to contribute to Fedora Docs ›