Если Вы уже давно пользуетесь операционной системой Linux и хоть немного разбираетесь в программировании, рано или поздно Вам может понадобиться собрать программу из исходного кода. Может быть, нужной программы не окажется в репозиториях дистрибутива. Или в этих репозиториях программа старой версии, а Вам нужна самая свежая. А может, Вы создали новую программу и хотите поделиться ей с другими пользователями.
Конечно, можно установить программу по инструкциям, прилагаемым к исходному коду. Но тогда управлять файлами программы и следить за её зависимостями нужно будет вручную. Намного лучше собрать пакет с программой и использовать встроенный в операционную систему менеджер приложений.
Надеюсь, эта статья поможет быстрее разобраться со сборкой пакета RPM для Rosa Linux или для другого дистрибутива, использующего менеджер пакетов RPM (Mandriva, RedHat). Или хотя бы подскажет, где искать информацию.
Здесь я покажу, как создавать пакеты RPM на своём локальном компьютере, на простом примере. Будем собирать программу xkb-switch в операционной системе Rosa Linux. Исходники программы будем брать с GitHub.
Оглавление
- Немного о Rosa Linux
- Немного об xkb-switch
- Настройка, доработка, проверка программы
- Проверяем исходный код без своего профиля в GitHub
- Проверка с сохранением проекта в свой профиль GitHub
- Подготовим «рабочее место» для создания пакета
- Начнём создавать спек-файл
- Немного о синтаксисе спек-файла
- Заголовок спек-файла
- Подготовка исходников
- Компиляция
- Инсталляция
- Упаковка файлов
- Если нужно разделить пакет на части
- Добавим немного макросов
- Немного изменим заголовок
- Определим пакеты библиотек
- Определим файлы для пакетов
- Решение дополнительных проблем
- Вывод
- Основные команды
- Полезные ссылки (основные источники)
Немного о Rosa Linux
Rosa Linux — дистрибутив, созданный и поддерживаемый российскими разработчиками. Он сделан на основе Mandriva, но с некоторыми особенностями. Я использую 32-битную версию Rosa Fresh R8, которая выпущена в 2014 году. Сейчас версия R8 уже не поддерживается разработчиками (репозитории для неё не обновляются), но хорошо работает на моём ноутбуке, поэтому не хочется устанавливать новую версию.
Rosa Fresh R8 Использует рабочий стол KDE4. Все версии дистрибутива используют для управления пакетами с приложениями менеджеры rpm
и urpm
, и соответствующие команды: rpm
, urpmi
, urpme
, urpmq
, urpmf
.
Принципы сборки программных пакетов обычно редко изменяются в пределах одного семейства дистрибутивов Linux. Поэтому то, что описано в данной статье, должно работать во всех вариантах дистрибутивов Rosa.
Построение пакетов в Rosa Linux немного проще, чем в некоторых других дистрибутивах, основанных на RPM. Некоторые моменты автоматизированы и не нуждаются в настройке.
Немного об xkb-switch
Мне понравилась идея использовать плагин для текстового редактора Vim — xkbswitch, о котором есть статья на Хабре. Он автоматически переключает раскладку клавиатуры на английский язык при выходе из режима ввода, и обратно — на тот, на котором вводили текст в прошлый раз — если войти в режим ввода снова. Для работы этого плагина нужна программа xkb-switch, которая позволяет переключать раскладку клавиатуры из командной строки и из плагинов для редактора Vim. В репозиториях Rosa Linux R8 этой программы не оказалось (и, скорее всего, никто не будет его добавлять, ведь дистрибутив уже старый, а программа xkb-switch не слишком популярна).
Настройка, доработка, проверка программы
Часто бывает нужно настроить компиляцию программы для правильной работы в конкретном дистрибутиве или даже для конкретной системы. Бывает, что программу нужно собрать с другими опциями или с поддержкой какого-нибудь специального драйвера. А может быть, Вы захотите исправить ошибки в коде программы или просто проверить, работает ли она. Для этого лучше перед началом сборки пакета RPM скопировать исходный код к себе на компьютер, попробовать его собрать и проверить, как работает скомпилированная программа.
Если Вы уверены, что файлы проекта изменять не понадобится, то можно использовать оригинальный исходный код с сайта проекта и сразу приступить к сборке пакета. Но если нужно изменить настройки компиляции, то обычно гораздо проще изменить файл в папке с исходным кодом (так называемый makefile), чем потом разбираться с опциями команд компиляции и внутренним устройством макросов для спек-файла.
Проверяем исходный код без своего профиля в GitHub
Если Вы решили поработать с исходным кодом или настройками компиляции проекта, но у Вас нет своего профиля в GitHub или не хочется его использовать, можно просто скачать и распаковать исходный код. В нашем случае это могло бы выглядеть так (я использую папку ~/Projects/cpp
для исходных кодов на C++):
cd ~/Projects/cpp
git clone https://github.com/ierton/xkb-switch.git
Это создаст папку ~/Projects/cpp/xkb-switch
, содержащую исходный код. Конечно, вместо использования git
можно скачать архив с программой и распаковать его.
Из файла README.md
в папке проекта несложно догадаться, что для сборки программы используется утилита cmake
. Поэтому если нужно изменить настройки компиляции — в нашем случае они находятся в файле CMakeLists.txt
. А мы просто попробуем скомпилировать программу и проверить, работает ли она. Какие команды для этого нужно использовать, написано в том же файле README.md
в корне проекта.
cd xkb-switch
mkdir build && cd build
cmake ..
make
./xkb-switch
#здесь должно быть выведено имя текущей группы раскладок клавиатуры
./xkb-switch -l
#здесь должны быть выведены все доступные группы
./xkb-switch -s ru
#после этого раскладка должна переключиться на русскую (если она есть)
После этого, чтобы использовать изменённый проект, придётся очистить или удалить папку build
из проекта и упаковать исходный код в архив. Это может выглядеть так:
cd ~/Projects/cpp/xkb-switch
rm -rf ./build
cd ~/Projects/cpp
zip -r xkb-switch.zip xkb-switch
Файл xkb-switch.zip
потом нужно будет использовать для сборки пакета.
Проверка с сохранением проекта в свой профиль GitHub
Я предполагаю что тот, кто читает этот раздел, хоть немного знаком с работой с git и уже завёл себе профиль в GitHub. Считаю этот способ самым лучшим, поэтому в оставшейся части статьи будет подразумеваться, что используется именно он, если не сказано другое.
Сначала нужно «форкнуть» оригинальный проект в свой GitHub. После этого, как в прошлом способе, клонируем проект к себе на компьютер, но уже из своего репозитория (в моём случае, имя пользователя — alexandersolovyov):
cd ~/Projects/cpp
git clone https://github.com/alexandersolovyov/xkb-switch.git
Для добавления любых изменений, лучше использовать новую ветку. Тогда при желании можно будет использовать разные версии программы. А ещё можно будет предлагать свои изменения автору проекта с помощью pull-request'ов. Например, если Вы решили немного исправить файл CMakeLists.txt
, перед этим нужно создать новую ветку с помощью:
git branch cmake_corrections
После того, как изменения сделаны, проверены и добавлены в ветку (с помощью git commit -am "описание изменений"
), можно добавить новую ветку в свой GitHub:
git push origin cmake_corrections
После этого можно сделать pull-request, если это нужно.
Можно сделать ссылку на оригинальный репозиторий:
git remote add ierton https://github.com/ierton/xkb-switch.git
И потом обновлять основную ветку своего репозитория, чтобы она соответствовала оригиналу:
git pull ierton master
Код программы, соответствующий исправленной ветке, можно будет использовать при сборке RPM. Для этого в спек-файле нужно будет указать адрес к архиву в таком виде:
Source0: https://github.com/ваше-имя/имя-проекта/archive/имя-ветки-с-исправлениями.zip
Но, как подсказал пользователь specblog, вообще-то так делать неправильно. Лучше передать свои изменения в виде патчей. Для этого нужно создать файлы патчей из изменений в своей ветке и скопировать их в папку с исходниками для сборки пакета (~/rpmbuild/SOURCES/
). Потом нужно будет указать их в спек-файле. Это мы рассмотрим немного позже, но если хотите — можно прочитать здесь. Если Вы не знаете, как создавать патчи, — можно заглянуть под спойлер.
Создание патчей
Патчи, они же Заплатки — это файлы, в которых записаны изменения в исходном коде программы. Их используют как альтернативу командам git pull
и git push
для связи между локальными репозиториями кода в том случае, если «вытягивать» изменения из удалённого репозитория не удобно, или история изменений проекта и принципы работы с ним такие, что лучше использовать патчи.
Давайте представим, что нам нужно внести изменения в файл CMakeLists.txt
. Сначала нужно сделать всё как описано выше: ветка master в нашем репозитории на GitHub должна соответствовать главной ветке оригинального проекта, а для своих изменений нужно использовать ветку cmake_corrections. Потом нужно перейти в эту ветку, сделать необходимые изменения и сохранить их в git с помощью коммитов.
Теперь нужно сохранить изменения в виде файлов патчей в папку ~/rpmbuild/SOURCES
(если Вы используете не Rosa Linux, путь к папке SOURCES
может быть другим). Например так (подразумеваю, что мы находимся в папке проекта — например, ~/Projects/cpp/xkb-switch
— и на ветке cmake_corrections
):
git format-patch -o ~/rpmbuild/SOURCES origin/master
Команда git format-patch
создаёт по одному файлу-патчу на каждый коммит. В таком виде она сделает патчи начиная от коммита, указанного последним аргументом, и заканчивая последним коммитом текущей ветки. Коммит можно указать любым способом: по началу хэша, с помощью указателя HEAD или имени ветки, которое сейчас указывает на нужный коммит. Главное, чтобы в качестве начала был взят один из коммитов, которые видны при выполнении git log
. То есть нельзя начинать делать патчи от коммита, который находится в другой ветке.
А можно вспомнить (или посмотреть), сколько коммитов назад мы ответвились от основной ветки, и сделать патчи на определённое количество коммитов назад. Например, если мы сделали два коммита, команда будет такая:
git format-patch -o ~/rpmbuild/SOURCES -2
Здесь количество коммитов задаётся с помощью -2
. Можно указать любое их количество вместо этой цифры.
Можно указать диапазон коммитов, из которых нужно сделать патчи, поставив две точки между ссылками на начальный и конечный коммит:
git format-patch -o ~/rpmbuild/SOURCES master..cmake_corrections
Название каждого файла патча состоит из порядкового номера и первой строки комментария коммита. Поэтому лучше переименовать каждый файл так, чтобы описание патча более коротко и ясно описывало его суть. Например так:
mv 0001-Return-memory-allocated-by-XkbRf-getNamesProp()-for-tmp.patch 001-Fix-memory-leak.patch
соглашение о наименованиях патчей в статье о синтаксисе спек-файла советует перед описанием каждого файла патча добавить название_пакета-версия-rosa-. Может быть, это хорошая практика, если Вы передаёте патчи по электронной почте, но не для построения пакетов. Мы строим пакеты на своём компьютере, поэтому лучше очищать папку ~/rpmbuild/SOURCES
каждый раз перед тем, как собирать пакет с другой программой или пакет новой версии.
Теперь если будет нужно обновить основную ветку репозитория (master), чтобы она соответствовала оригиналу, то после этого ветку с изменениями (cmake_corrections) нужно будет обновить с помощью команды git rebase
. О том, как это сделать, можно посмотреть здесь. После этого патчи нужно будет создать заново.
Подготовим «рабочее место» для создания пакета
Для начала нужно создать структуру каталогов. Вся сборка происходит в папке rpmbuild
в домашней папке пользователя. Создадим начальную структуру каталогов и перейдём в папку для спек-файлов:
mkdir -p ~/rpmbuild/SPECS && cd ~/rpmbuild/SPECS
Для Rosa Linux этого достаточно: остальные папки будут созданы автоматически.
В другом дистрибутиве для построения пакета может использоваться другое расположение файлов. А ещё, может быть, придётся создать всю иерархию папок вручную. Ищите информацию для Вашего дистрибутива, если Вы используете не Rosa Linux. Например, вот так это может выглядеть в Red Hat.
Если пакет собран с ошибками, то все файлы, созданные командой rpmbuild
, не удаляются — так же, как и при успешной сборке. Мы будем пытаться собирать пакет много раз, и файлы, оставшиеся после прошлого раза, будут мешать. Поэтому лучше сделать простой скрипт, который поможет быстро их удалять. Создадим файл cleanup.sh и поместим его в папку ~/rpmbuild/SPECS
. Вот его содержимое:
!#/bin/sh
rm -rf ~/rpmbuild/BUILD/*
rm -rf ~/rpmbuild/BUILDROOT/*
rm -rf ~/rpmbuild/RPMS/*
rm -rf ~/rpmbuild/SRPMS/*
Конечно, лучше добавить для него право исполнения с помощью команды chmod u+x cleanup.sh
.
Если Вы хотите собрать пакет из файлов, которые находятся на локальном компьютере, — если Вы не используете GitHub и сделали изменения в файлах проекта, или хотите создать пакет из своей собственной программы, которая хранится только на Вашем компьютере, — нужно упаковать проект в архив (например, .zip
, .tar
или .tar.gz
) и поместить его в папку SOURCES
. Например, так:
cd ~/Projects/cpp/
zip -r xkb-switch.zip xkb-switch
mkdir -p ~/rpmbuild/SOURCES
cp xkb-switch.zip ~/rpmbuild/SOURCES/
Если после сборки программы Вы захотите собрать ещё одну или ту же самую, но другой версии, то нужно будет удалить все файлы из папки ~/rpmbuild/SOURCES
, и уже после этого скопировать туда свой архив (если Вы не скачиваете его с GitHub) и файлы патчей (если они используются). Иначе файл архива, скорее всего, не будет скачиваться с GitHub (почему — увидим позже), а также будет тяжело разобраться в том, какой файл патча какой программе принадлежит.
Начнём создавать спек-файл
Основа построения пакета RPM — так называемый спек-файл. Этот файл содержит инструкции для программы rpmbuild
(вернее rpm
), необходимые для сборки пакета.
Создадим файл xkb-switch.spec
в папке ~/rpmbuild/SPECS/
. Проще всего начать с шаблона, который можно найти на сайте Template Spec Files.
Из файла README
на странице проекта xkb-switch известно, что программа компилируется с помощью утилиты cmake
. Поэтому выберем Spec file for a program built using CMake и скопируем весь шаблон в наш спек-файл. Конечно, для того, чтобы правильно собрать наш RPM-пакет, этот шаблон нужно сильно изменить, чем мы и займёмся.
Немного о синтаксисе спек-файла
- Синтаксис спек-файла позволяет добавлять комментарии в стиле bash.
- В качестве промежутков между значениями в одной строке, чтобы создать вид ровных колонок, можно использовать пробелы, но документация настойчиво рекомендует использовать символ табуляции (один или два — сколько нужно, чтобы колонки были ровными). Внимание: во всех примерах кода в этой статье использованы только пробелы, поэтому лучше не копировать весь текст отсюда в свой спек-файл, а печатать самостоятельно.
- Поля-опции состоят из специального имени опции с двоеточием и следующего через табуляцию (или пробелы) значения. Регистр символов в названиях полей не имеет значения. Например:
Name: xkb-switch
- Если перед словом стоит символ
%
(например,%description
), то это — специальное ключевое слово. Оно может быть вызовом команды, макроса или скрипта. Тогда после него могут быть указаны параметры, которые он использует. А есть ключевые слова, которые обозначают начало блока команд или опций. Тогда рядом с ним могут быть указаны параметры, а на следующих строках должны быть команды или список опций, которые я описал в предыдущем пункте. После такого блока должна быть оставлена пустая строка.
- Чтобы использовать значение константы, нужно вставить в любое место конструкцию вида
%{имя_константы}
. Её значение может быть предопределённым, а может определяться опцией (например,Name: xkb-switch
) или с помощью ключевого слова%define
. Все эти константы тоже считаются макросами. Подробнее их использование будет рассмотрено ниже.
Заголовок спек-файла
В спек-файле сначала всегда пишется заголовок. Это список опций, которые относятся к основному пакету RPM. Когда пакет будет готов, почти вся эта информация будет показана при просмотре его описания. Вот что обозначают отдельные строки:
Summary:
Короткое описание пакета. Я подсмотрел описание в файле
README.md
в проекте xkb-switch: Query and change XKB layout state
.Name:
Имя пакета. В нашем случае это
xkb-switch
.Version:
Версия программы. Чтобы её узнать, лучше всего посмотреть файл
CMakeLists.txt
в корневой папке проекта. Конечно, нужно брать файл из той копии проекта, которая будет использоваться для сборки. Если использовать оригинальный проект, файл можно открыть прямо на его странице GitHub. Как видно, версия складывается из MAJOR_VERSION
, MINOR_VERSION
и RELEASE_VERSION
. Я использовал программу версии 1.6.0
.Release:
Номер версии самого пакета. Отображает, который раз собирается пакет с программой одной и той же версии. В нашем случае это «1», так как никто раньше не собирал программу этой версии. В идеальном случае, если мы уже пытались собрать пакет и сборка доходила до конца (даже если были ошибки), то после каждой новой попытки нужно увеличивать это число на 1 и при этом не удалять старые собранные пакеты из папок
rpmbuild/RPMS
и rpmbuild/SRPMS
: рядом будут созданы новые пакеты с новым номером сборки. Наверное, так нужно делать если использовать специальный сервер для сборки. Мы же используем свой компьютер и вместо этого будем очищать папки. Если пакет с программой такой версии уже есть в репозиториях дистрибутива Linux, но Вы собираете с другими настройками, то лучше указать номер релиза на 1 больше, чем у того пакета.License:
Короткое название лицензии, под которой распространяется программа. По правилам Rosa Linux можно собирать пакеты только с той лицензией, которая разрешает свободное распространение. Из файла
README.md
можно узнать, что лицензия — GNU GPLv3. Значит пишем: GPLv3+
.Group:
Группа или категория, к которой принадлежит программа. С помощью этих групп программы сортируются в меню запуска приложений и в оконном менеджере программ («Установка и удаление программ»). Список групп для Rosa Linux можно посмотреть здесь. Я думаю, нам лучше всего подходит
Development\X11
, так как программа связана с X11 и нужна, в основном, для создания скриптов и плагинов для Vim.URL:
Адрес в интернете, откуда можно скачать оригинальный исходный код программы. Он будет указан при просмотре информации о пакете RPM. Этот пункт заполнять не обязательно, но мы укажем:
https://github.com/ierton/xkb-switch
Source0:
Имя файла архива, содержащего исходный код, или адрес в интернете, по которому его можно скачать. Если указать адрес в интернете, то при первой сборке файл будет скачан в
~/rpmbuild/SOURCES/
. Если такой файл уже есть, он больше не будет скачиваться, то есть программа rpmbuild
будет использовать только имя файла, указанное в конце этого URL. Можно указать просто имя файла, но тогда его нужно будет поместить в папку ~/rpmbuild/SOURCES/
вручную. Лучше указать адрес своей копии проекта в GitHub. Я использовал файл https://github.com/alexandersolovyov/xkb-switch/archive/master.zip
. Можно указать несколько разных источников, чтобы собрать исходники из нескольких архивов с помощью одного спек-файла. Тогда в названии опции для добавления каждого следующего архива цифра должна увеличиваться (Source1
, Source2
и т. д.). Эти адреса файлов не видны при просмотре информации о пакете RPM.Patch0:
Этой опции нет в файле-шаблоне. Она может пригодиться, если Вы решили передать свои изменения в файлах проекта программы в виде патчей. Так же, как и для опции
Source0
, каждый файл должен быть указан в отдельной строке, и число в конце имени опции должно увеличиваться с каждым разом. Файлы патчей должны находиться в папке ~/rpmbuild/SOURCES
(рядом со скачанным архивом с исходниками). Имя каждого файла нужно писать без пути к нему. Здесь не обязательно указывать все файлы патчей, — можно только те, которые Вы хотите применить.BuildRequires:
Пакеты, необходимые для сборки программы. В шаблоне предложено указать
cmake
. В файле CMakeLists.txt
указано, что минимальная версия CMake для сборки должна быть не ниже, чем 2.6, поэтому лучше указать cmake >= 2.6
. Можно добавить и другие пакеты, каждый из них — на отдельной строке, с помощью отдельной опции BuildRequires:
. Список пакетов, необходимых для сборки, можно узнать, прочитав файл README
проекта и внимательно просмотрев файл CMakeLists.txt
(особенно функции FIND_PACKAGE
, TARGET_LINK_LIBRARY
, FIND_PROGRAM
). Потом нужно найти правильное название пакетов в репозиториях с помощью команды urpmq -a предполагаемое_имя_библиотеки
. В нашем случае файл настроек компиляции (CMakeLists.txt
) уже содержит строки, которые проверяют наличие нужных пакетов в системе. Но лучше здесь тоже указать весь список:# CMake версии 2.6 и выше
BuildRequires: cmake >= 2.6
# Компилятор C/C++
BuildRequires: gcc
# Заголовочные файлы библиотеки libxkbfile
BuildRequires: libxkbfile-devel
# От библиотеки X11 уже зависит libxkbfile,
# поэтому libx11-devel указывать не нужно.
# Архиватор для файла man:
BuildRequires: xz
Requires:, Provides:
В образце этих опций нет, но иногда они могут пригодиться. Они устанавливают зависимости между пакетами. С помощью опции
Provides
указываются Возможности, предоставляемые собираемым пакетом. Это может быть имя заголовочного файла языка C или имя динамической библиотеки, или какая-нибудь специальная функция. А опция Requires
указывает, от каких Возможностей других пакетов зависит собираемый пакет. Менеджер пакетов (rpm
, urpm
, или другой, который используется в Вашем дистрибутиве), при поиске зависимостей ищет именно эти Возможности, а не названия пакетов. Поэтому для Provides
лучше указывать версию предоставляемой Возможности, а для Requires
— какие версии предоставляемых Возможностей подходят. Версия указывается через знаки >=
, =
, или <=
, окружённые пробелами. Обычно сначала указывают все опции Requires
, потом — Provides
, по одному имени возможности на строку — так же, как и для BuildRequires:
. Обычно при построении пакетов в Rosa Linux зависимости распознаются автоматически, и эти опции редко нужно указывать.AutoReq:, AutoProv:
Если Вы собираете программу, которая написана на языке, с которым менеджер rpm плохо знаком, или которая является проприетарной, и зависимости не определяются правильно автоматически, то можно отключить автоматическое определение Возможностей (с помощью
AutoProv: no
) и/или Зависимостей (с помощью AutoReq: no
).%description
Этот блок уже не является частью заголовка, но связан с ним. Он добавит полное описание программы в пакет RPM. После него должна быть оставлена пустая строка. Описание может быть таким:
%description
xkb-switch is a C++ program that allows to query and change the keyboard layout
state for X11 Window System (XKB) via command line. It provides a command
'xkb-switch', and bindings for API of the Vim text editor via
'libxkbswitch.so'. It is mainly used by a plugin for Vim text editor,
vim-xkbswitch. Originally ruby-based code written by J.Broomley.
Строки из шаблона, начинающиеся на %files
и %find_lang
, нужны только если собирать приложение с поддержкой нескольких языков, поэтому удалим их.
Дальше, после разделительной черты-комментария, следуют команды и макросы, которые нужно выполнить до упаковывания файлов. Все эти команды разделены на блоки, определённые с помощью специальных ключевых слов.
Подготовка исходников
Первым идёт блок %prep
, в котором указываются команды для подготовки к компиляции. В нём — команда-макрос %setup
. Она запускает скрипт, который делает следующее:
- Скачивает архивы с файлами исходного кода программы, указанные опциями с именами вида
SourceX:
в заголовке файла (у нас — толькоSource0:
). Если файл уже скачан или указано только имя файла, то ничего не скачивается.
- Скачанные файлы сохраняются в папку
~/rpmbuild/SOURCES/
.
- Распаковывает эти архивы в папку
~/rpmbuild/BUILD/
.
- Переходит в папку с распакованными файлами.
Её опция -q
указывает, чтобы выводилось меньше информации в процессе выполнения.
Можно сразу попробовать собрать пакет, останавливаясь после выполнения блока %prep
:
rpmbuild -bp ~/rpmbuild/SPECS/xkb-switch.spec
Для сборки используется команда rpmbuild
. Если в Вашей системе нет этой команды, то вместо неё можно использовать rpm
с теми же опциями: rpmbuild
это её ограниченный синоним, который предназначен только для построения пакетов. Все команды для сборки нужно выполнять от имени обычного пользователя (не от имени root
и без команды sudo
). Описание всех опций rpmbuild
можно увидеть, выполнив man rpmbuild
. Там же можно увидеть список папок, в которых находятся макросы и другие файлы, используемые этой командой, — на случай, если Вам захочется подробнее разобраться в порядке работы команды rpmbuild
.
В результате получим сообщение об ошибке: xkb-switch-1.6.0: No such file or directory
. По выводу команды видно, что после распаковки архива скрипт пытается перейти в папку ~/rpmbuild/BUILD/xkb-switch-1.6.0
, которой нет. Выполнив команду
ls ~/rpmbuild/BUILD/
Видим, что там находится папка xkb-switch-master
. Её нужно указать команде %setup
с помощью опции -n
. В результате блок %prep
в спек-файле должен выглядеть так:
%prep
%setup -q -n xkb-switch-master
Выполним наш скрипт ~/rpmbuild/SPECS/cleanup.sh
, чтобы очистить папку BUILD
, и попробуем снова построить пакет, заканчивая блоком %prep
. Теперь видим, что последним сообщением выводится exit 0
. Это значит, что блок выполнен без ошибок.
Если Вы добавили свои изменения в программе с помощью патчей, то недостаточно указать файлы патчей опциями в заголовке файла. Ещё их надо добавить в блок %prep
. Если Вы просто хотите добавить все патчи, которые указаны в заголовке, то добавьте в конец блока строку:
%apply_patches
После этого попробуйте ещё раз выполнить rpmbuild -bp xkb-switch.spec
. Если обнаружатся ошибки — их нужно будет исправить.
Подробнее о добавлении патчей можно почитать на сайте Maximum RPM.
Теперь можно двигаться дальше.
Компиляция
Компиляция исходного кода выполняется блоком %build
. В файле README
проекта сказано, что компиляция делается командами cmake ..
и make
, но в нашем шаблоне спек-файла используются одноимённые макросы. Это правильно: так команды будут выполнены со всеми переходами в папки и опциями, которые нужны для правильной компиляции. Оставим всё как есть, очистим папки и выполним построение до пункта %build
включительно:
~/rpmbuild/SPECS/cleanup.sh
rpmbuild -bc ~/rpmbuild/SPECS/xkb-switch.spec
В конце вывода видим exit 0
: всё сделано без ошибок.
Вообще, в блоках команд не обязательно использовать только одни макросы. Можно добавить любые команды shell (то есть bash или zsh, или что там у Вас). Команда rpmbuild
во время сборки перемещается по папкам, поэтому нужно добавить переход в правильную рабочую папку перед своей командой. В этих командах shell можно использовать константы спек-файла — как и в любом другом месте этого файла. (Использование констант мы увидим ниже.)
Если Вам нужно собрать какой-нибудь необычный пакет, тогда, скорее всего, придётся использовать в блоке %build
команды shell вместо макросов.
Изменить опции компиляции для проекта, не изменяя его файлов, может быть сложно. Если для сборки используется команда cmake
, то, возможно, для этого придётся изучить содержимое файла макроса %cmake
и составить группу команд для спек-файла таким образом, чтобы они делали то же самое, но с необходимыми изменениями. Обычно гораздо проще изменить файл настроек компиляции проекта (в нашем случае — CMakeLists.txt
). Вот поэтому я рекомендовал использовать свою копию проекта или папки с исходным кодом, сделав там необходимые изменения.
Инсталляция
Вернее, псевдоинсталляция. В блоке %install
должны выполниться действия, в результате которых скомпилированные файлы программы будут находиться в папках с точно такой же иерархией, как у корневой папки системы, но внутри папки ~/rpmbuild/BUILDROOT/полное_имя_пакета-buildroot/
.
Здесь полное_имя_пакета
будет состоять из имени, указанного с помощью опции Name:
в заголовке спек-файла, версии программы (Version:
в спек-файле), номера релиза (Release:
в спек-файле), названия дистрибутива, его версии и архитектуры процессора.
В файле README
проекта написано, что установка выполняется командой make install
, находясь в папке build
внутри папки проекта. В спек-файле команда-макрос %makeinstall_std -C build
делает то же самое, но более правильно. Построим проект до пункта инсталляции включительно (как всегда, сначала очистив папки):
~/rpmbuild/SPECS/cleanup.sh
rpmbuild -bi ~/rpmbuild/SPECS/xkb-switch.spec
В конце псевдоинсталляции проверяется список файлов, которые нужно будет добавить в пакет RPM. В нашем спек-файле его ещё нет, поэтому будет сообщение об ошибке.
Упаковка файлов
В сообщении об ошибке после псевдоинсталляции есть список файлов, которые ещё не отмечены в спек-файле для упаковывания. Этот же список можно узнать, просмотрев всё содержимое папки ~/rpmbild/BUILDROOT/
. (Для этого, обычно, очень удобно использовать команду tree
, которая по-умолчанию не установлена в большинстве дистрибутивов Linux.) Кроме файлов, о которых нам сказало сообщение об ошибке, там есть ещё файлы с расширением .debug
. Для работы с ними, обычно, ничего не нужно настраивать: пакет с отладочными символами будет создан полностью автоматически.
Чтобы указать, какие файлы должны быть добавлены в пакет, нужен блок %files
в спек-файле. Мы удалили строки, нужные для поддержки нескольких языков, поэтому такого блока в файле нет. Создадим его.
Во многих системах принято располагать блок %files
внизу спек-файла. Это логично, ведь он выполняется последним. Но в Rosa Linux его принято писать сразу перед блоком %prep
(и разделительной строкой-комментарием в нашем случае). Так все настройки, касающиеся подготовки файлов, будут находиться в конце файла, а то, что касается сборки пакета из этих файлов — в верхней части. Это особенно удобно если нужно построить несколько пакетов одним спек-файлом (да, так тоже можно делать, и мы рассмотрим это ниже).
В блоке %files
должен быть список файлов, которые должны быть в пакете RPM. Итак, создадим блок над разделительной чертой:
%files
%{_bindir}/%{name}
%{_libdir}/libxkbswitch.so
%{_libdir}/libxkbswitch.so.1
%{_libdir}/libxkbswitch.so.%{version}
%{_mandir}/man1/%{name}.1.xz
Здесь для указания папок установки лучше использовать специальные макросы-константы. Их полный список, обычно, можно посмотреть в файле /usr/lib/rpm/macros
. В частности, %{_bindir}
вставляет путь к исполняемым файлам, %{_libdir}
— к папкам библиотек, и %{_mandir}
— к файлам документации man. А константы %{name}
и %{version}
содержат значения полей Name:
и Version:
в заголовке спек-файла.
Теперь попробуем построить пакет полностью:
~/rpmbuild/SPECS/cleanup.sh
rpmbuild -ba ~/rpmbuild/SPECS/xkb-switch.spec
… И получим 2 сообщения и 1 предупреждение. Их выдаёт команда rpmlint
, которая автоматически выполняется после построения пакетов. Чтобы понять, что они значат, может помочь страница Rpmlint Errors Если коротко, они расшифровываются так:
`xkb-switch.i586: E: incoherent-version-in-name (Badness: 50) 1`
Ошибка: версия в имени библиотечного пакета указана неверно.
`xkb-switch.i586: E: executable-in-library-package (Badness: 1) /usr/bin/xkb-switch`
Ошибка: в библиотечном пакете находится исполняемый файл.
`xkb-switch.i586: W: devel-file-in-non-devel-package /usr/lib/libxkbswitch.so`
Предупреждение о том, что файл пакета для разработки (
-devel
) обнаружен в пакете, не предназначенном для разработки.Всё понятно? Не думаю. Давайте разберёмся подробнее, что здесь происходит.
Что такое rpmlint
После построения пакетов в Rosa Linux команда rpmbuild
вызывает программу rpmlint
, которая проверяет правильность сборки. Если rpmlint
выдала сообщения об ошибках, это не значит, что пакет совсем непригоден к использованию. Она только проверяет, насколько пакет соответствует стандартам Rosa Linux (или другого дистрибутива, в котором была запущена rpmlint
) и насколько правильно указаны зависимости.
Если Вы пользуетесь другим дистрибутивом, и проверка не запускается автоматически, тогда нужно проверить построенные пакеты вручную. Для этого нужно перейти в папку ~/rpmbuild/RPMS/архитектура_процессора/
и запустить для каждого построенного пакета команду вида rpmlint -i имя_файла_пакета
.
Кстати, если Вы скачали готовый пакет RPM на сайте какого-нибудь проекта, то прежде, чем устанавливать такой пакет, можно проверить, насколько правильно он собран для Rosa Linux, с помощью той же команды rpmlint -i имя_файла_пакета
.
Виды пакетов RPM для Rosa Linux
Пакеты для Rosa Linux делятся на 6 видов. В идеальном случае, каждый собранный пакет должен соответствовать только одному из этих видов.
Исполняемый пакет
Он же бинарный. Содержит только двоичный файл или скрипт, предназначенный непосредственно для выполнения. Файлы этих пакетов, чаще всего, устанавливаются в папку
/bin/
или в /usr/bin
. Может также содержать ссылки — для возможности вызова программы с помощью нескольких разных имён. Имя пакета соответствует названию программы. Такие пакеты часто зависят от библиотек.Библиотека
Содержит скомпилированные файлы динамически подключаемой («общей», «shared») библиотеки, используемые программами. Обычно это сам файл библиотеки, имя которого заканчивается версией, и ссылка на этот файл, имя которой заканчивается первым числом версии. Например, для библиотеки
libxkbfile
версии 1.0.2 это будет файл libxkbfile.so.1.0.2
и ссылка на него, libxkbfile.so.1
. Само имя пакета библиотеки, по которому его узнают в репозитории программы-установщики, заканчивается первым числом версии и начинается приставкой lib
. У библиотеки libxkbfile
правильное имя — libxkbfile1
. Это делается из-за того, что обычно первое число версии изменяется только при несовместимых изменениях библиотеки, и так можно будет установить несколько пакетов с библиотекой разных версий, если одни программы используют старую версию библиотеки, а другие — более новую.Пакет для разработчиков
Файлы, необходимые для компиляции программ, которые используют библиотеку, но ненужные для работы готовых программ. Для простых программ на C/C++ — это ссылка на файл библиотеки, но без версий в имени (например,
libxkbfile.so
), а также заголовочные файлы (с расширением .h
). Имя такого пакета заканчивается на -devel
, например: libxkbfile-devel
. При установке всегда зависит от соответствующей библиотеки. Например, пакет libxkbfile-devel
зависит от libxkbfile1
.Исходный код
В репозиториях Rosa Linux есть RPM-пакеты, содержащие исходный код для некоторых программ — в основном только тех, которые действительно бывает нужно перестроить. Имена этих пакетов заканчиваются на
-src
или -source
(например, apache-source
). rpmbuild
всегда создаёт такой пакет автоматически и помещает его в ~/rpmbuild/SRPMS/
.Отладочные символы
Это информация, которая может использоваться для отладки готовой программы. Она связывает места в скомпилированных файлах с исходным кодом. Такие пакеты создаются командой
rpmbuild
автоматически, к их имени приписывается окончание -debuginfo
. В репозиториях Rosa Linux таких пакетов я не нашёл.Документация
В репозиториях Rosa Linux есть пакеты документации к разным программам и библиотекам. Особенностей построения таких пакетов я (пока) не знаю. Их имена обычно заканчиваются на
doc
: например, libx11-doc
, java-1.7.0-openjdk-javadoc
. Кстати, почти все они сделаны в стиле веб-сайтов, и, чтобы их просматривать, лучше всего открыть браузер, перейти по адресу file:///usr/share/doc/
и выбрать необходимую папку и файл.Наш результат
Теперь всё стало яснее.
- В нашем пакете
xkb-switch
содержится файлlibxkbswitch.so
, который, по правилам, должен содержаться в пакете для разработки. Поэтому выдаётся сообщение, что файл для разработки находится не в пакете для разработки:xkb-switch.i586: W: devel-file-in-non-devel-package /usr/lib/libxkbswitch.so
.
- Наш пакет распознан как библиотечный, ведь в нём есть файлы
/usr/lib/libxkbswitch.so.1
и/usr/lib/libxkbswitch.so.1.6.0
. Но также в нём есть исполняемый файл, которого в библиотечном пакете быть не должно. Отсюда ошибка:xkb-switch.i586: E: executable-in-library-package (Badness: 1) /usr/bin/xkb-switch
.
- Наш пакет признан библиотечным, но в конце его имени нет первого числа версии (1). Поэтому получено сообщение:
xkb-switch.i586: E: incoherent-version-in-name (Badness: 50) 1
.
Сообщения, выданные rpmlint
, не обязательно всегда полностью удовлетворять. Во многих случаях это бывает не нужно или даже невозможно. Особенности программы xkb-switch таковы, что она содержит библиотечный файл libxkbswitch.so.1.6.0
и ссылки на него только для того, чтобы его могли использовать плагины для редактора Vim. Эта библиотека разрабатывается и распространяется только одновременно и вместе с программой xkb-switch, и она не предназначена для использования другими программами на C или C++. Поэтому RPM-пакет можно считать успешно построенным.
В результате у нас получился такой спек-файл:
Summary: Query and change XKB layout state
Name: xkb-switch
Version: 1.6.0
Release: 1
License: GPLv3+
Group: Development/X11
URL: https://github.com/ierton/xkb-switch
Source0: https://github.com/alexandersolovyov/xkb-switch/archive/master.zip
BuildRequires: cmake >= 2.6
BuildRequires: gcc
BuildRequires: libxkbfile-devel
BuildRequires: xz
%description
xkb-switch is a C++ program that allows to query and change the keyboard layout
state for X11 Window System (XKB) via command line. It provides a command
'xkb-switch', and bindings for API of the Vim text editor via
'libxkbswitch.so'. It is mainly used by a plugin for Vim text editor,
vim-xkbswitch. Originally ruby-based code written by J.Broomley.
%files
%{_bindir}/%{name}
%{_libdir}/libxkbswitch.so
%{_libdir}/libxkbswitch.so.1
%{_libdir}/libxkbswitch.so.%{version}
%{_mandir}/man1/%{name}.1.xz
#------------------------------------------------------------------
%prep
%setup -q -n xkb-switch-master
%build
%cmake
%make
%install
%makeinstall_std -C build
Если нужно разделить пакет на части
Может понадобиться разделить проект на несколько пакетов — например, если библиотека из этой программы будет использоваться другой программой. Чтобы рассмотреть такой вариант, давайте представим, что нам нужно разделить файлы проекта xkb-switch
на 3 пакета: исполняемый, библиотечный и для разработки. Тогда:
- в исполняемом пакете должен быть файл
/usr/bin/xkb-switch
и его документация/usr/share/man/man1/xkb-switch.1.xz
,
- в библиотечном — файлы
/usr/lib/libxkbswitch.so.1
и/usr/lib/libxkbswitch.so.1.6.0
,
- а в пакете для разработки —
/usr/lib/libxkbswitch.so
.
Для этого нужно сделать изменения в спек-файле. О том, как это сделать,
можно узнать из соответствующего раздела онлайн-книги Maximum RPM. Также может быть полезен пример спек-файла для libxkbfile и Политика оформления библиотек Rosa Linux.
Давайте попробуем это сделать.
Добавим немного макросов
Для удобства работы можно добавить несколько макросов — по примеру спек-файла для libxkbfile. Добавим в начало нашего спек-файла такие строки:
%define major 1
%define libname %mklibname xkbswitch %{major}
%define develname %mklibname -d xkbswitch
Здесь ключевое слово %define
объявляет константу. После этого слова через пробел следует название константы, а за ним (через один или два символа табуляции) — значение или макрос, результат выполнения которого будет присвоен имени константы. То есть первая строка обозначает, что в константе %{major}
будет храниться 1
, это будет первое число номера версии.
Макрос %mklibname
берёт строку «lib», добавляет к нему первый аргумент, а к тому что получилось — второй аргумент (и все следующие). То есть значением константы %{libname}
будет «lib» + «xkbswitch» + (значение константы %{major}) = libxkbswitch1
— имя пакета библиотеки.
Опция -d
макроса %mklibname
добавляет окончание -devel
. Поэтому значением константы %{develname}
будет libxkbswitch-devel
— имя пакета для разработки.
Немного изменим заголовок
Приведём строку с опцией Version:
к виду
Version: %{major}.6.0
для того, чтобы указывать самое главное число версии только в одном месте спек-файла.
Теперь мы будем использовать заголовок спек-файла в качестве заголовка для пакета исполняемого файла. Поэтому можно немного изменить его описание. В итоге заголовок будет выглядеть так:
Name: xkb-switch
Version: %{major}.6.0
Release: 1
Summary: Query and change XKB layout state
License: GPLv3+
Group: Development/X11
URL: https://github.com/alexandersolovyov/xkb-switch
Source0: https://github.com/alexandersolovyov/xkb-switch/archive/master.zip
BuildRequires: cmake >= 2.6
BuildRequires: gcc
BuildRequires: libxkbfile-devel
BuildRequires: xz
%description
xkb-switch is a C++ program that allows to query and change the keyboard layout
state for X11 Window System (XKB) via command line. It provides a command
'xkb-switch', and bindings for API of the Vim text editor, a library
'libxkbswitch'. It is mainly used for some plugins for Vim text editor, such as
vim-xkbswitch. Originally ruby-based code written by J.Broomley.
Определим пакеты библиотек
Оформим пакеты библиотек как под-пакеты для пакета с исполняемой программой. Под-пакеты это самостоятельные пакеты, каким-то образом связанные с основным пакетом (это будут отдельные файлы rpm). Определить их нам поможет ключевое слово %package
. Рядом с этим словом нужно указать имя под-пакета. После этой строки следует блок, похожий на заголовок спек-файла. В каждом из этих блоков обязательно должны быть поля Version
, Summary
, Group
. Также там могут быть опции Provides
и Requires
для указания Возможностей и Зависимостей пакета, которые не могут определиться автоматически. Поля Name
быть не должно: имя пакета определяется именем, указанным рядом со словом %package
.
У каждого пакета должно быть описание. Для этого используется блок %description
с указанным рядом с ним именем — точно так же, как для соответствующего блока %package
.
В Rosa Linux принято объявлять под-пакеты под блоком %description
заголовка спек-файла. Определим пакет библиотеки libxkbswitch1
так:
%package -n %{libname}
Version: %{version}
Summary: A library for xkb-switch tool, provides API bindings for Vim text editor
Group: Development/X11
%description -n %{libname}
libxkbswitch library, required by xkb-switch tool. It provides bindings for API
of the Vim text editor, which can be used via 'libxkbswitch.so.1'.
Опция -n
после ключевых слов %package
и %description
нужна, чтобы следующее слово полностью переписало название пакета. Без неё имя под-пакета будет дописываться через дефис к имени основного пакета, и название будет xkb-switch-libxkbswitch1
. С этой опцией пакет будет называться libxkbswitch1
. Всё остальное было описано раньше и должно быть понятно без объяснений.
Ниже объявим пакет для разработчиков:
%package -n %{develname}
Version: %{version}
Summary: Development library libxkbswitch, provides API bindings for Vim text editor
Group: Development/X11
%description -n %{develname}
Development files for libxkbswitch. Provides bindings for
API of the Vim text editor via 'libxkbswitch.so'.
Определим файлы для пакетов
Теперь нужно определить, какие файлы будут в каких пакетах. Для этого используется блок %files
.
На самом деле правила обозначения того, к какому пакету относится блок, одинаковы для блоков %package
, %description
и %files
. Можно заметить, что для блока %description
заголовка спек-файла имя пакета не указано. Если так делать, то блок считается принадлежащим основному пакету, в нашем случае — xkb-switch
.
В спек-файлах для Rosa Linux обычно принято писать блоки %files
под определениями пакетов, но перед блоком %prep
. Наши блоки определения файлов будут выглядеть так:
%files
%{_bindir}/%{name}
%{_mandir}/%{name}.1.xz
%files -n %{libname}
%{_libdir}/libxkbswitch.so.%{major}
%{_libdir}/libxkbswitch.so.%{version}
%files -n %{develname}
%{_libdir}/libxkbswitch.so
Таким образом мы определили, что:
- в пакете
xkb-switch
будут файлы~/usr/bin/xkb-switch
и~/usr/share/man/man1/xkb-switch.1
,
- в пакете
libxkbswitch1
будут файлы~/usr/lib/libxkbswitch.so.1
и~/usr/lib/libxkbswitch.so.1.6.0
,
- а в пакете
libxkbswitch-devel
будет файл~/usr/lib/libxkbswitch.so
.
Теперь очистим папки с помощью скрипта cleanup.sh
и попробуем построить пакеты с помощью rpmbuild -ba ~/rpmbuild/SPECS/xkb-switch.spec
. В результате получим 3 предупреждения:
libxkbswitch1.i586: W: no-documentation
libxkbswitch-devel.i586: W: no-documentation
libxkbswitch-devel.i586: W: no-dependency-on
libxkbswitch/libxkbswitch-libs/liblibxkbswitch
Первые два обозначают, что для пакетов библиотек не указана документация. Это можно решить, добавив файл документации в пакет. Со вторым всё немного сложнее. Давайте попробуем разобраться.
Решение дополнительных проблем
Итак, чтобы убрать предупреждение об отсутствии документации, можно притвориться, что документация к библиотекам хранится в файле README.md
проекта. Добавим его в блоки %files
для пакетов библиотеки и разработки — с помощью макроса %doc
:
%doc README.md
Здесь не нужно указывать полный путь. Рабочая папка макроса %doc
— папка с распакованными исходниками. Поэтому в документацию пакетов будет добавлен файл ~/rpmbuild/BUILD/xkb-switdh-master/README.md
.
Теперь у нас осталось только одно предупреждение: libxkbswitch-devel.i586: W: no-dependency-on libxkbswitch/libxkbswitch-libs/liblibxkbswitch
. Оно обозначает, что у пакета libxkbswitch-devel
нет зависимости от libxkbswitch
или подобных.
С помощью команды rpm -qp опция имя-файла-пакета
можно узнать любую информацию о файлах пакетов. Мы можем проверить предоставляемые возможности и зависимости между получившимися пакетами таким образом:
[user@pc ~] $ cd ~/rpmbuild/RPMS/i586/
[user@pc ~/rpmbuild/RPMS/i586] $ ls
libxkbswitch1-1.6.0-1-rosa2014.1.i586.rpm
xkb-switch-1.6.0-1-rosa2014.1.i586.rpm
libxkbswitch-devel-1.6.0-1-rosa2014.1.i586.rpm
xkb-switch-debuginfo-1.6.0-1-rosa2014.1.i586.rpm
[user@pc ~/rpmbuild/RPMS/i586] $ rpm -qp --provides libxkbswitch1-1.6.0-1-rosa2014.1.i586.rpm
libxkbswitch.so.1
libxkbswitch1 = 1.6.0-1:2014.1
[user@pc ~/rpmbuild/RPMS/i586] $ rpm -qp --provides libxkbswitch-devel-1.6.0-1-rosa2014.1.i586.rpm
devel(libxkbswitch)
libxkbswitch-devel = 1.6.0-1:2014.1
[user@pc ~/rpmbuild/RPMS/i586] $ rpm -qp --requires libxkbswitch-devel-1.6.0-1-rosa2014.1.i586.rpm
devel(libX11)
devel(libgcc_s)
devel(libstdc++)
devel(libxkbfile)
rpmlib(PayloadIsXz) <= 5.2-1
[user@pc ~/rpmbuild/RPMS/i586] $ rpm -qp --requires xkb-switch-1.6.0-1-rosa2014.1.i586.rpm
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1.3)
libgcc_s.so.1
libgcc_s.so.1(GCC_3.0)
libstdc++.so.6
libstdc++.so.6(CXXABI_1.3)
libstdc++.so.6(GLIBCXX_3.4)
libstdc++.so.6(GLIBCXX_3.4.11)
libstdc++.so.6(GLIBCXX_3.4.20)
libstdc++.so.6(GLIBCXX_3.4.9)
libxkbswitch.so.1
rpmlib(PayloadIsXz) <= 5.2-1
Отсюда видно, что пакет библиотеки libxkbswitch1
предоставляет возможности libxkbswitch.so.1
и libxkbswitch1
. Пакет xkb-switch
зависит от libxkbswitch.so.1
, а вот у пакета libxkbswitch-devel
нет зависимостей от libxkbswitch1
. Это можно исправить, добавив зависимость в блок %package
для libxkbswitch-devel
. Теперь этот блок будет выглядеть так:
%package -n %{develname}
Version: %{version}
Summary: Development library libxkbswitch, provides API bindings for Vim text editor
Group: Development/X11
Requires: %{libname} >= %{version}
Можно попробовать очистить папки и собрать пакеты заново, но… предупреждение об отсутствии зависимости всё равно останется. Если проверить зависимости пакета libxkbswitch-devel
ещё раз, то увидим, что зависимость успешно добавляется. Скорее всего сообщение остаётся потому, что в нашем пакете для разработки нет заголовочных файлов, и rpmbuild
не может определить эту зависимость автоматически.
Спек-файл, который у нас получился (с файлом README.md
в качестве документации библиотек), — под спойлером:
%define major 1
%define libname %mklibname xkbswitch %{major}
%define develname %mklibname -d xkbswitch
# Main package. Automaticaly requires libxkbswitch and libxkbswitch-devel
Name: xkb-switch
Version: %{major}.6.0
Release: 1
Summary: Query and change XKB layout state
License: GPLv3+
Group: Development/X11
URL: https://github.com/alexandersolovyov/xkb-switch
Source0: https://github.com/alexandersolovyov/xkb-switch/archive/master.zip
BuildRequires: cmake >= 2.6
BuildRequires: gcc
BuildRequires: libxkbfile-devel
BuildRequires: xz
%description
xkb-switch is a C++ program that allows to query and change the keyboard layout
state for X11 Window System (XKB) via command line. It provides a command
'xkb-switch', and bindings for API of the Vim text editor, a library
'libxkbswitch'. It is mainly used for some plugins for Vim text editor, such as
vim-xkbswitch. Originally ruby-based code written by J.Broomley.
# libxkbswitch
%package -n %{libname}
Version: %{version}
Summary: A library for xkb-switch tool, provides API bindings for Vim text editor
Group: Development/X11
%description -n %{libname}
libxkbswitch library, required by xkb-switch tool. It provides bindings for API
of the Vim text editor, which can be used via 'libxkbswitch.so.1'.
# libxkbswitch-devel
%package -n %{develname}
Version: %{version}
Summary: Development library libxkbswitch, provides API bindings for Vim text editor
Group: Development/X11
Requires: %{libname} >= %{version}
%description -n %{develname}
Development files for libxkbswitch. Provides bindings for
API of the Vim text editor via 'libxkbswitch.so'.
# xkb-switch
%files
%{_bindir}/%{name}
%{_mandir}/man1/%{name}.1.xz
# libxkbswitch1
%files -n %{libname}
%{_libdir}/libxkbswitch.so.%{major}
%{_libdir}/libxkbswitch.so.%{version}
%doc README.md
# libxkbswitch-devel
%files -n %{develname}
%{_libdir}/libxkbswitch.so
%doc README.md
#------------------------------------------------------------------
%prep
%setup -q -n xkb-switch-master
%build
%cmake
%make
%install
%makeinstall_std -C build
Вывод
Мы рассмотрели, как можно построить несложный пакет RPM для операционной системы Rosa Linux (и других систем использующих такой же менеджер пакетов). Также мы научились создавать несколько связанных пакетов, используя один спек-файл. Конечно, здесь не затронуто очень много тем — таких, как применение патчей, использование настроек rpmrc, или сборка пакетов на сервере ABF вместо локального компьютера, — но это было бы слишком много для одной статьи.
Если Вам нужно собрать более сложный пакет — пользуйтесь приведённой ниже информацией, анализируйте готовые пакеты и примеры спек-файлов, и не забудьте о поиске в Интернет и ман-страницах команд, — и у Вас всё получится.
Основные команды
Команды для сборки пакета
rpmbuild -bp specfile.spec
Выполнить подготовку (%prep).
rpmbuild -bc specfile.spec
Выполнить компиляцию (%build) и все предшествующие действия.
rpmbuild -bi specfile.spec
Выполнить псевдоустановку (%install) и все предшествующие действия.
rpmbuild -ba specfile.spec
Построить пакеты полностью.
Проверка готового пакета
rpmlint -i имя-файла-пакета.rpm
Общая проверка — насколько правильно собран пакет.
rpm -qp --provides имя-файла-пакета.rpm
Проверить, какие «возможности» предоставляются пакетом.
rpm -qp --requires имя-файла-пакета.rpm
Проверить, от каких «возможностей» других пакетов зависит данный пакет.
rpm -qpl имя-файла-пакета.rpm
Список файлов, содержащихся в пакете.
rpm -qpi имя-файла-пакета.rpm
Информация о пакете (из «заголовка» спек-файла или из блока %package).
Можно проанализировать уже установленные пакеты с помощью тех же команд, но без опции p
. А можно анализировать пакеты, которые находятся в репозиториях Rosa Linux, не устанавливая их. Сделать это поможет команда urpmq
, подставленная вместо rpm -q
. Например, urpmq -l имя_пакета
выведет список файлов пакета, а urpmq --requires имя_пакета
выведет его зависимости.
Полезные ссылки (основные источники)
- Building RPMs — Quick Start — одна из лучших статей об основах создания пакетов RPM для Rosa Linux.
- Основы RPM — статья на русском языке, похожая на предыдущую, но недоделанная и с несколькими мелкими ошибками. Помогла мне начать.
- RPM: Синтаксис spec файла — соглашения об оформлении спек-файлов для Rosa Linux.
- Maximum RPM — самая полная онлайн книга о работе с
rpm
и построении RPM-пакетов для RedHat Linux. В ней можно найти почти любую информацию об этом, но есть небольшие отличия от Rosa Linux. Хорошо использовать как справочник. - Template Spec Files — шаблоны файлов
.spec
. Чаще всего, с них лучше начинать создание спек-файла. - Automatic Build Farm (ABF) — сайт автоматической фермы построения пакетов Rosa Linux. С помощью строки поиска в шапке сайта можно найти по названию любой пакет, и посмотреть файлы, которые используются при его построении, в том числе
.spec
файл. Самый лучший источник примеров спек-файлов. - Rpmlint Errors — краткий справочник по ошибкам, которые выдаёт
rpmlint
. - Packaging Group — список категорий программ Rosa Linux.
- Политика оформления библиотек Rosa Linux.
- Git — перебазирование — альтернативный способ слияния веток в Git.