Manjaro Создание пакетов Manjaro

Создание пакетов Manjaro

From Manjaro
This page is a translated version of the page Create Manjaro Packages and the translation is 100% complete.
Other languages:
English • ‎Türkçe • ‎русский

Руководство по созданию пакетов Manjaro

Эта статья призвана помочь пользователям в создании собственных пакетов с помощью оптимизированных инструментов разработчика Manjaro, а также для отправки в бинарные репозитории Manjaro. В ней рассказывается о создании PKGBUILD, файла описания сборки пакета, который используется makepkg для создания бинарного пакета из исходного кода. Если у вас уже есть PKGBUILD (см. makepkg). Инструкции относительно существующих правил и способов улучшения качества пакетов смотрите в Стандарт пакетизации Manjaro.

Обзор

Пакеты в Manjaro Linux собираются с помощью утилиты makepkg и информации, хранящейся в файле PKGBUILD. Когда запускается makepkg, она ищет PKGBUILD в текущем каталоге и следует инструкциям в нем чтобы скомпилировать или иным образом получить необходимые файлы для упаковки в файл пакета (pkgname.pkg.tar.xz). Полученный пакет содержит двоичные файлы и инструкции по установке; легко устанавливаемый с помощью pacman.

Пакет Manjaro - это не более чем tar-архив, или "tarball", сжатый с помощью xz, содержащий следующие файлы, созданные makepkg:

  • Бинарные файлы для установки.
  • .PKGINFO: содержит все метаданные, необходимые pacman для работы с пакетами, зависимостями и т.д.
  • .MTREE: содержит хэши и временные метки файлов, включаемые в локальную базу данных, чтобы pacman мог проверить целостность пакета.
  • .INSTALL: необязательный файл, используемый для выполнения команд после этапа установки/обновления/удаления. (Этот файл присутствует, только если он указан в PKGBUILD).
  • .Changelog: необязательный файл, хранящийся у сопровождающего пакета и документирующий изменения пакета. (Он присутствует не во всех пакетах).

Подготовка

Необходимое программное обеспечение

Сначала убедитесь, что необходимые инструменты установлены. Группы пакетов base-devel должно быть достаточно; она включает make и дополнительные инструменты, необходимые для компиляции из исходного кода.

# pacman -S base-devel

Одним из ключевых инструментов для сборки пакетов является makepkg (доступный в pacman), который делает следующее:

  1. Проверяет, установлены ли зависимости пакета.
  2. Скачивает исходный файл(ы) с указанного сервера(ов).
  3. Распаковывает исходный файл(ы).
  4. Компилирует программу и устанавливает ее в окружении fakeroot.
  5. Удаляет символы из двоичных файлов и библиотек.
  6. Генерирует метафайл пакета, включаемый в каждый пакет.
  7. Сжимает окружение fakeroot в файл пакета.
  8. Сохраняет файл пакета в настроенном каталоге назначения, который по умолчанию является текущим рабочим каталогом.

Загрузка и тестирование установки

Загрузите исходный tarball программы, которую вы хотите упаковать, распакуйте его и следуйте указаниям автора для установки программы. Запишите все команды и/или шаги, необходимые для компиляции и установки. Вы будете повторять эти же команды в файле PKGBUILD.

Большинство авторов программного обеспечения придерживаются трехэтапного цикла сборки:

./configure
make
make install

Это подходящее время, чтобы убедиться, что программа работает правильно.

Создание PKGBUILD

Когда вы запускаете makepkg, он будет искать файл PKGBUILD в текущем рабочем каталоге. Если файл PKGBUILD найден - он загрузит исходный код программы и скомпилирует его в соответствии с инструкциями, указанными в файле PKGBUILD. Инструкции должны быть полностью интерпретируемы оболочкой [[1]]. После успешного завершения, полученные двоичные файлы и метаданные пакета (версия пакета и зависимости) упаковываются в пакетный файл pkgname.pkg.tar.xz, который может быть установлен с помощью pacman -U <файл пакета>.

Чтобы начать работу с новым пакетом, сначала нужно создать пустой рабочий каталог (предпочтительно ~/abs/pkgname), перейти в этот каталог и создать файл PKGBUILD. Вы можете либо скопировать прототип PKGBUILD /usr/share/pacman/PKGBUILD.proto в свой рабочий каталог, либо скопировать PKGBUILD из аналогичного пакета. Последний вариант может быть полезен, если вам нужно изменить всего несколько параметров.

Определение переменных PKGBUILD

Примеры PKGBUILD находятся в /usr/share/pacman/. Объяснение возможных переменных PKGBUILD можно найти в статье PKGBUILD.

makepkg определяет три переменные, используемые в процессе сборки и установки:

startdir
Содержит абсолютный путь к директории, в которой находится файл PKGBUILD. Раньше эта переменная использовалась в сочетании с постфиксами /src или /pkg, но современным методом является использование переменных srcdir и pkgdir. $startdir/src не гарантированно совпадает с $srcdir, и то же самое для $pkgdir. Использование этой переменной является устаревшим и настоятельно не рекомендуется.
srcdir
Указывает на каталог, куда makepkg извлекает или копирует все исходные файлы.
pkgdir
Указывает на каталог, где makepkg собирает установленный пакет, который становится корневым каталогом вашего собранного пакета.

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


Note
makepkg, и, следовательно, функции build() и package(), предназначены для неинтерактивного использования. Интерактивные утилиты или скрипты, вызываемые в этих функциях, могут сломать makepkg, особенно если он вызывается с включенным протоколированием сборки (-l) (см. FS13214.)

.


Note
Помимо текущего сопровождающего (Maintainer) пакета, могут быть предыдущие, перечисленные выше как Contributors

.

Функции PKGBUILD

Существует 5 функций, перечисленных здесь в порядке их выполнения, если все они существуют. Если одна из них отсутствует - она просто пропускается.


Note
Это не относится к функции package(), поскольку она требуется в каждом PKGBUILD

Функция pkgver()

Начиная с pacman 4.1, вы можете обновлять переменную pkgver во время makepkg. pkgver() запускается сразу после получения и извлечения исходных текстов.

Это особенно полезно, если вы создание пакетов git/svn/hg/итд, где процесс сборки может оставаться неизменным, но исходники могут обновляться каждый день, даже каждый час. Старый способ сделать это состоял в том, чтобы поместить дату в поле pkgver, которое, если программа не была обновлена, makepkg все равно пересобирал ее, думая, что версия изменилась. Некоторые полезные команды для этого - git describe, hg identify -ni и т.д. Пожалуйста, проверьте их перед отправкой PKGBUILD, так как сбой в функции pkgver() может остановить сборку на корню.

Note
pkgver не может содержать пробелы или дефисы (-). Обычно для исправления этого используется sed

.

Функция prepare()

В Pacman 4.1 появилась функция prepare(). В этой функции выполняются команды, используемые для подготовки исходных текстов к сборке, например, патчинг. Эта функция выполняется перед функцией сборки и после извлечения пакета. Если извлечение пропущено (makepkg -e), то prepare() не выполняется.


Note
(Из man PKGBUILD) Функция выполняется в режиме bash -e, то есть любая команда, выполнившаяся с ненулевым статусом, вызовет выход функции.

Функция build()

Теперь вам нужно реализовать функцию build() в файле PKGBUILD. Эта функция использует обычные команды оболочки в синтаксисе [[2]] для автоматической компиляции программного обеспечения и создания каталога pkg для установки программного обеспечения. Это позволяет makepkg упаковывать файлы без необходимости рыться в файловой системе.

Первым шагом в функции build() является переход в каталог, созданный в результате распаковки исходного tarball. makepkg изменит текущий каталог на srcdir перед выполнением build(), поэтому в большинстве случаев первая команда будет выглядеть следующим образом:

cd "$pkgname-$pkgver"

Файл /usr/share/pacman/PKGBUILD.proto предлагает сделать

cd "$srcdir/$pkgname-$pkgver"

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

Теперь вам нужно перечислить те же команды, которые вы использовали при ручной компиляции программы. Функция build() по сути автоматизирует все, что вы делали вручную, и компилирует программу в среде сборки fakeroot. Если программное обеспечение, которое вы упаковываете, использует сценарий configure, хорошей практикой будет использование --prefix=/usr при сборке пакетов для pacman. Многие программы устанавливают файлы относительно каталога /usr/local, что следует делать только при ручной сборке из исходников. Все пакеты Arch Linux должны использовать каталог /usr. Как видно из файла /usr/share/pacman/PKGBUILD.proto, следующие две строки обычно выглядят следующим образом:

./configure --prefix=/usr
make


Note
Если вашей программе не нужно ничего собирать, НЕ используйте функцию build(). Функция build() в таком случае не требуется, но требуется функция package().

Функция check()

Место для вызовов make check и подобных процедур тестирования. Настоятельно рекомендуется иметь check(), так как это помогает убедиться, что программное обеспечение было собрано правильно и отлично работает со своими зависимостями.

Пользователи, которым это не нужно (и иногда сопровождающие, которые не могут исправить пакет, чтобы это прошло), могут отключить его с помощью !check в опциях PKGBUILD/makepkg или вызвать makepkg с флагом --nocheck.

Функция package()

Последний шаг - поместить скомпилированные файлы в каталог, из которого makepkg сможет получить их для создания пакета. По умолчанию это каталог pkg - простая среда fakeroot. Каталог pkg повторяет иерархию корневой файловой системы путей установки программного обеспечения. Если вам нужно вручную поместить файлы в корень вашей файловой системы, то вы должны установить их в каталог pkg в той же структуре каталогов. Например, если вы хотите установить файл в /usr/bin - вместо этого его следует поместить в $pkgdir/usr/bin. Очень немногие процедуры установки требуют от пользователя копирования десятков файлов вручную. Вместо этого для большинства программ достаточно вызвать команду make install. Чтобы правильно установить программу в каталог pkg последняя строка должна выглядеть следующим образом:

make DESTDIR="$pkgdir/" install


Note
В некоторых случаях DESTDIR не используется в Makefile; Вам может понадобиться использовать prefix вместо этого. Если пакет собран с помощью autoconf/ automake, используйте DESTDIR; именно это документировано в руководствах. Если DESTDIR не работает - попробуйте собрать с помощью make prefix="$pkgdir/usr/" install. Если и это не сработает, то Вам придется подробнее изучить команды установки, выполняемые командой "make <...> install"

.

В некоторых странных случаях программа ожидает запуска из одного каталога. В таких случаях разумно просто скопировать их в $pkgdir/opt.

Чаще всего процесс установки программного обеспечения создает все подкаталоги внутри каталога pkg. Однако если этого не происходит - makepkg будет выдавать множество ошибок и вам придется вручную создавать подкаталоги, добавляя соответствующие команды mkdir -p в функцию build() перед запуском процедуры установки.

В старых пакетах не было функции package(). Поэтому файлы помещались в каталог pkg в конце функции build(). Если package() отсутствует - build() запускается через fakeroot. В новых пакетах функция package() обязательна и запускается через fakeroot, а build() запускается без специальных привилегий.

makepkg --repackage запускает только функцию package(), поэтому создает файл *.pkg.* без компиляции пакета. Это может сэкономить время, например, если вы просто изменили переменную пакета depends.


Note
Функция package() является единственной обязательной функцией в PKGBUILD. Если для установки программы Вам нужно только скопировать файлы в соответствующие каталоги - не помещайте их в функцию build() - поместите их в функцию package()

.

Тестирование PKGBUILD и пакета

В процессе написания функции build() Вам придется часто тестировать свои изменения чтобы убедиться в отсутствии ошибок. Это можно сделать с помощью команды makepkg в каталоге, содержащем файл PKGBUILD. При правильно оформленном PKGBUILD makepkg создаст пакет; при поврежденном или незавершенном PKGBUILD он выдаст ошибку.

Если makepkg завершится успешно - он поместит файл с именем pkgname-pkgver.pkg.tar.xz в ваш рабочий каталог. Этот пакет можно установить с помощью команды pacman -U. Однако то, что файл пакета был собран, не означает что он полностью работоспособен. Он может содержать только каталог и ни одного файла, если, например, префикс был указан неправильно. Вы можете использовать функции запроса pacman для отображения списка файлов, содержащихся в пакете, и зависимостей, которые он требует, с помощью pacman -Qlp [файл пакета] и pacman -Qip [файл пакета] соответственно.

Если пакет выглядит нормально, то все готово! Однако, если Вы планируете выпустить файл PKGBUILD - обязательно проверьте и перепроверьте содержимое массива depends.

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

Проверка исправности пакета

После тестирования функциональности пакета проверьте его на наличие ошибок с помощью namcap:

$ namcap PKGBUILD
$ namcap <имя файла пакета>.pkg.tar.xz

Namcap будет:

  1. Проверять содержимое PKGBUILD на наличие распространенных ошибок и иерархию файлов пакета на наличие ненужных/замещенных файлов.
  2. Сканировать все ELF-файлы в пакете с помощью lddd, автоматически сообщая, какие пакеты с необходимыми разделяемыми библиотеками отсутствуют в depends, а какие могут быть опущены как переходные зависимости.
  3. Эвристически искать отсутствующие и избыточные зависимости

и многое другое. Возьмите за привычку проверять свои пакеты с помощью namcap чтобы избежать необходимости исправлять простейшие ошибки после отправки пакета.

Отправка пакетов в AUR

Пожалуйста, прочитайте Arch User Repository - Отправка пакетов для подробного описания процесса отправки.

Резюме

  1. Скачайте исходный tarball программы, которую вы хотите упаковать.
  2. Попробуйте скомпилировать пакет и установить его в произвольный каталог.
  3. Скопируйте прототип /usr/share/pacman/PKGBUILD.proto и переименуйте его в PKGBUILD во временный рабочий каталог - предпочтительно ~/abs/.
  4. Отредактируйте PKGBUILD в соответствии с потребностями вашего пакета.
  5. Запустите makepkg и проверьте правильно ли собран полученный пакет.
  6. Если нет - повторите два последних шага.

Предупреждения

  • Прежде чем автоматизировать процесс сборки пакета Вы должны были хотя бы раз проделать это вручную, если только не знаете точно, что Вы делаете заранее, и в этом случае не читали бы это в первую очередь. К сожалению, хотя многие авторы программ придерживаются трехэтапного цикла сборки "./configure; make; make install" - он не всегда таков и ситуация может стать действительно ужасной, если придется применять патчи, чтобы заставить все работать. Эмпирическое правило: если Вы не можете заставить программу скомпилироваться из исходного tarball'а и установить ее в определенный временный подкаталог - не стоит даже пытаться упаковать ее. В makepkg нет волшебного порошка, который заставит проблемы с исходниками исчезнуть.
  • В некоторых случаях пакеты даже не доступны в виде исходников и придется использовать что-то вроде sh installer.run чтобы заставить их работать. Вам придётся провести довольно много исследований (прочитать README, инструкции INSTALL, man-страницы, возможно, ebuilds от Gentoo или других установщиков пакетов, возможно, даже MAKEFILE или исходный код), чтобы заставить его работать. В некоторых действительно плохих случаях Вам придется редактировать исходные файлы чтобы заставить его работать вообще. Однако, makepkg должен быть полностью автономным - не вмешивать пользователя. Поэтому, если Вам нужно отредактировать make-файлы, то возможно, придется подключить пользовательский патч к PKGBUILD и установить его изнутри функции prepare(), или же придется выполнить некоторые команды sed изнутри функции prepare().

Создание файл патча

Пример для отдельного файла

 $ diff -Naur filename.ext.old filename.ext > filename-patchname.diff
 
 # PKGBUILD
 cd "${srcdir}/${pkgname}-${pkgver}"
 patch -uN filename.ext ../filename-patchname.diff || return 1

Пример для нескольких файлов

 $ diff -Naur package-ver.old package-ver > package-patchname.diff
 
 # PKGBUILD
 cd "${srcdir}/${pkgname}-${pkgver}"
 patch -uNp1 -i ../${pkgname}-patchname.diff || return 1
Cookies help us deliver our services. By using our services, you agree to our use of cookies.