Creating packages (Русский)
Эта статья призвана помочь пользователям в создании собственных пакетов с помощью «портоподобной» системы сборки, в том числе для публикации в AUR. В ней рассказывается о создании файла описания сборки пакета — PKGBUILD, используемого утилитой makepkg
для создания бинарного пакета из исходного кода. Если у вас уже есть PKGBUILD
, смотрите статью makepkg (Русский). Инструкции относительно существующих правил и способов улучшения качества пакетов описаны в статье Стандарты создания пакетов для Arch.
Обзор
Пакеты в Arch Linux собираются с помощью утилиты makepkg и информации, хранящейся в файле PKGBUILD. При запуске makepkg
ищет PKGBUILD
в текущем каталоге и выполняет записанные в нём инструкции для получения необходимых файлов и/или их компиляции для упаковки в файл пакета (pkgname.pkg.tar.zst
). Полученный пакет содержит двоичные файлы и инструкции по установке, готовые к установке с помощью pacman.
Пакет Arch — это не более чем tar-архив, или «tarball», сжатый с помощью zstd(1), который содержит следующие созданные утилитой makepkg файлы:
- Бинарные файлы для установки.
.PKGINFO
: содержит все метаданные, необходимые pacman для работы с пакетами, зависимостями и т.д..BUILDINFO
: содержит информацию, необходимую для воспроизводимых сборок. Этот файл присутствует, только если пакет собран с помощью pacman 5.1 или более новой версии. См. BUILDINFO(5)..MTREE
: содержит хэши и временные метки файлов, которые включаются в локальную базу данных, чтобы pacman мог проверить целостность пакета..INSTALL
: необязательный файл, используемый для выполнения команд после этапа установки/обновления/удаления. (Этот файл присутствует, только если он указан вPKGBUILD
)..Changelog
: необязательный файл, хранящийся у сопровождающего пакета и документирующий изменения пакета. (Он присутствует не во всех пакетах).
Подготовка
Необходимое программное обеспечение
Сперва убедитесь, что необходимые инструменты установлены: мета-пакета base-devel должно быть достаточно; он подтягивает make
и дополнительные инструменты, необходимые для компиляции из исходного кода.
Ключевым инструментом для сборки пакетов является makepkg (предоставляется пакетом pacman), который делает следующее:
- Проверяет, установлены ли зависимости пакета.
- Загружает исходные файлы с указанного сервера(ов).
- Распаковывает исходные файлы.
- Компилирует программу и устанавливает её в окружении fakeroot.
- Удаляет символы из двоичных файлов и библиотек.
- Генерирует метафайл пакета, который включается в каждый пакет.
- Сжимает окружение fakeroot в файл пакета.
- Сохраняет файл пакета в настроенном каталоге назначения, который по умолчанию является текущим рабочим каталогом.
Загрузка и тестирование установки
Загрузите исходный tarball программы, которую хотите упаковать, распакуйте его и следуйте указаниям автора для установки программы. Запишите все команды и/или шаги, необходимые для компиляции и установки. Вы будете повторять эти же команды в файле PKGBUILD
.
Большинство авторов программ придерживаются трёхэтапного цикла сборки:
./configure make make install
Это подходящее время, чтобы убедиться, что программа работает правильно.
Установка в чистый chroot
Рекомендуется следовать DeveloperWiki:Building in a clean chroot, чтобы убедиться, что пакеты и конфигурация вашей системы не приведут к ошибкам в PKGBUILD. Это более надёжный и корректный способ сборки пакетов, позволяющий обнаружить отсутствующие зависимости, о необходимости которых вы не подозревали, поскольку они уже присутствовали в вашей системе.
Создание PKGBUILD
При запуске makepkg
ищет в текущем рабочем каталоге файл PKGBUILD
. Если он найден, то загружает исходный код программы и компилирует его в соответствии с инструкциями, указанными в файле PKGBUILD
. Инструкции должны быть полностью интерпретируемы оболочкой Bash. После успешного завершения результирующие двоичные файлы и метаданные пакета, то есть версия пакета и зависимости, упаковываются в файл пакета pkgname.pkg.tar.zst
. Получившийся пакет можно установить, просто используя makepkg --install
, который вызовет pacman в фоновом режиме, или непосредственно используя pacman -U pkgname.pkg.tar.zst
.
Чтобы начать сборку нового пакета, сначала создайте новый каталог для пакета и измените текущий каталог на него. Затем необходимо создать файл PKGBUILD
: можно использовать прототип PKGBUILD, находящийся в /usr/share/pacman/
, или начать с файла PKGBUILD
из другого пакета. Последний вариант может оказаться удобным, если уже существует похожий пакет.
Определение переменных PKGBUILD
Примеры PKGBUILD находятся в /usr/share/pacman/
. Объяснение возможных переменных PKGBUILD
можно найти в статье PKGBUILD (Русский).
makepkg определяет две переменные, которые следует использовать в процессе сборки и установки:
srcdir
- Указывает на каталог, в который makepkg помещает файлы, указанные в массиве source.
pkgdir
- Указывает на каталог, в который makepkg собирает установленный пакет, который становится корневым каталогом вашего собранного пакета.
Они содержат абсолютные пути — это означает, что при правильном использовании этих переменных вам не нужно беспокоиться о своём рабочем каталоге.
build()
и package()
, предназначены для неинтерактивной работы. Интерактивные утилиты или скрипты, вызываемые в этих функциях, могут нарушить работу makepkg, особенно если они вызываются с включенным протоколированием сборки (--log
). (См. FS#13214.)Функции PKGBUILD
При сборке пакета makepkg
будет вызывать следующие пять функций, если они определены в PKGBUILD. Функция package()
является обязательной в каждом PKGBUILD и будет вызываться всегда. Если какая-либо из других функций не определена, то makepkg
просто пропустит вызов этой функции.
Во время сборки функции вызываются в том порядке, в котором они перечислены здесь.
prepare()
С помощью этой функции выполняются команды, используемые для подготовки исходных текстов к сборке, например применение патчей. Эта функция запускается сразу после извлечения пакета, перед pkgver() и функцией сборки. Если извлечение пропущено (makepkg --noextract
), то prepare()
не выполняется.
bash -e
, то есть любая команда, которая завершает работу с ненулевым статусом, приводит к выходу из функции.Когда неясно, куда поместить ту или иную функцию — в prepare()
или build()
, можно воспользоваться эмпирическим правилом: помещать в prepare()
те шаги, которые должны выполняться ровно один раз после извлечения исходных текстов, а в build()
— те шаги, которые имеет смысл повторно выполнять после внесения любых ручных правок в извлечённые файлы.
pkgver()
pkgver()
запускается после извлечения исходных текстов, их распаковки и выполнения prepare(). Таким образом, переменную pkgver можно обновить на этапе makepkg.
Это особенно полезно при создании пакетов git/svn/hg/etc., когда процесс сборки может оставаться неизменным, но исходники могут обновляться каждый день, а то и каждый час. Старый способ сделать это заключался в том, чтобы поместить дату в поле pkgver, но тогда даже если если программа не обновлялась, то makepkg все равно пересобирал её из-за изменившегося номера версии. Некоторые полезные команды для этого — git describe
, hg identify -ni
и т. д. Пожалуйста, проверяйте их перед отправкой PKGBUILD, так как сбой в функции pkgver()
может остановить сборку на корню.
-
). Для исправления этого часто используется sed.build()
Теперь необходимо реализовать функцию build()
в файле PKGBUILD
. Эта функция использует обычные команды оболочки в синтаксисе Bash для автоматической компиляции программ и создания каталога pkg
для их установки. Она позволяет makepkg упаковывать файлы без необходимости рыться в файловой системе.
Первым шагом в функции build()
является переход в каталог, созданный в результате распаковки архива с исходным кодом. makepkg изменит текущий каталог на $srcdir
перед выполнением функции build()
. Поэтому в большинстве случаев, как это предлагается в /usr/share/pacman/PKGBUILD.proto
, первая команда будет выглядеть следующим образом:
cd "$pkgname-$pkgver"
Теперь необходимо прописать те же команды, которые использовались при ручной компиляции программы. Функция build()
, по сути, автоматизирует всё, что вы делали вручную, и компилирует программу в среде сборки fakeroot. Если в упаковываемом программном обеспечении используется скрипт configure, то при сборке пакетов для pacman рекомендуется использовать --prefix=/usr
. Многие программы устанавливают файлы относительно каталога /usr/local
, что следует делать только в случае ручной сборки из исходных текстов. Все пакеты Arch Linux должны использовать каталог /usr
. Как видно из файла /usr/share/pacman/PKGBUILD.proto
, следующие две строки часто выглядят следующим образом:
./configure --prefix=/usr make
build()
. Функция build()
не является обязательной, а вот package()
является таковой.check()
Место для вызовов make check
и аналогичных процедур проверки. Настоятельно рекомендуется иметь check()
, так как проверка помогает убедиться в том, что программа правильно и хорошо работает с зависимостями.
Пользователи, которым она не нужна (а иногда и сопровождающие, которые не могут исправить пакет для её прохождения), могут отключить её, добавив !check
в массив options
в PKGBUILD
/makepkg.conf(5) или вызвать makepkg
с флагом --nocheck
.
package()
Последним шагом является помещение скомпилированных файлов в каталог, из которого makepkg сможет получить их для создания пакета. По умолчанию это каталог pkg
— простая среда fakeroot. Каталог pkg
повторяет иерархию корневой файловой системы путей установки программного обеспечения. Если вам приходится вручную размещать файлы в корне вашей файловой системы, то их следует устанавливать в каталог pkg
в той же структуре каталогов. Например, если вы хотите установить файл в /usr/bin
, то вместо этого его следует поместить в $pkgdir/usr/bin
. Лишь немногие процедуры установки требуют от пользователя копирования десятков файлов вручную. Вместо этого для большинства программ достаточно вызвать команду make install
. Для корректной установки программы в каталог pkg
последняя строка должна выглядеть следующим образом:
make DESTDIR="$pkgdir/" install
Makefile
не используется DESTDIR
; вместо него может потребоваться использовать prefix
. Если пакет собран с помощью autoconf / automake, используйте DESTDIR
; именно это документировано в руководствах. Если DESTDIR
не работает, попробуйте собрать с помощью make prefix="$pkgdir/usr/" install
. Если и это не сработает, то придётся подробнее изучить команды установки, выполняемые командой "make <...> install
".makepkg --repackage
запускает только функцию package()
, то есть создаёт пакет без сборки. Это может сэкономить время, например, если вы изменили только переменную depends
пакета.
Тестирование PKGBUILD и пакета
В процессе написания функции build()
необходимо часто тестировать изменения, чтобы убедиться в отсутствии ошибок. Это можно сделать с помощью команды makepkg
в каталоге, содержащем файл PKGBUILD
. При правильно оформленном PKGBUILD
makepkg создаст пакет; при неработающем или незавершённом PKGBUILD
она выдаст ошибку.
При успешном завершении работы makepkg поместит в рабочий каталог файл с именем pkgname-pkgver.pkg.tar.zst
. Этот пакет может быть установлен командой pacman -U
. Однако то, что файл пакета был собран, не означает, что он полностью работоспособен. Он может содержать только каталог и ни одного файла, если, например, неправильно указан префикс. С помощью функций запроса pacman можно вывести список файлов, содержащихся в пакете, и зависимостей, которые он требует, с помощью pacman -Qlp [package file]
и pacman -Qip [package file]
соответственно.
Если пакет выглядит нормально, то все готово! Однако если вы планируете опубликовать файл PKGBUILD
, то обязательно проверьте и перепроверьте содержимое массива depends
.
Также убедитесь, что двоичные файлы пакета действительно работают безупречно! Очень неприятно выпускать пакет, содержащий все необходимые файлы, но аварийно завершающий работу из-за непонятной опции конфигурации, которая не совсем корректно работает с остальной частью системы. Впрочем, если вы собираете пакеты только для себя, то можно об этом не слишком беспокоиться, ведь в конце концов от своих ошибок будете страдать только вы.
Проверка целостности пакета
После тестирования работоспособности пакета проверьте его на наличие ошибок с помощью namcap:
$ namcap PKGBUILD $ namcap <имя файла пакета>.pkg.tar.zst
Namcap выполнит:
- Проверку содержимого PKGBUILD на наличие типичных ошибок и иерархию файлов пакета на наличие ненужных или неправильно размещённых файлов
- Сканирование всех ELF-файлов пакета с помощью
ldd
, автоматически сообщая, какие пакеты с необходимыми разделяемыми библиотеками отсутствуют вdepends
, а какие могут быть опущены как транзитивные зависимости - Эвристический поиск отсутствующих и избыточных зависимостей
и многое другое.
Возьмите за привычку проверять свои пакеты с помощью namcap во избежание необходимости исправлять простейшие ошибки после отправки пакета.
Отправка пакетов в AUR
Пожалуйста, прочитайте правила отправки пакетов в AUR, где подробно описан процесс отправки.
Резюме
- Загрузите исходный архив программы, для которой создаётся пакет.
- Попробуйте скомпилировать пакет и установить его в произвольный каталог.
- Скопируйте прототип
/usr/share/pacman/PKGBUILD.proto
и переименуйте его вPKGBUILD
во временный рабочий каталог. - Отредактируйте
PKGBUILD
в соответствии с потребностями вашего пакета. - Запустите
makepkg
и проверьте, правильно ли собран пакет. - Если нет - повторите два предыдущих шага.
Предупреждения
- Прежде чем автоматизировать процесс сборки пакета, необходимо хотя бы раз выполнить его вручную, если только вы не знаете точно, что делаете, заранее, но в этом случае вы бы не читали эту статью. К сожалению, хотя многие авторы программ придерживаются трёхэтапного цикла сборки "
./configure
;make
;make install
", он не всегда таков, и ситуация может стать очень неприятной, если придётся применять патчи, чтобы вообще заставить всё работать. Правило: если вы не можете заставить программу скомпилироваться из исходного архива и установить себя в определённый временный подкаталог — не стоит даже пытаться упаковать её. Вmakepkg
нет волшебной пыльцы фей, избавляющей от проблем. - В некоторых случаях пакеты вообще недоступны в виде исходных текстов, и для того, чтобы заставить их работать, приходится использовать что-то вроде
sh installer.run
. Вам придётся провести довольно много исследований (прочитать README, инструкции INSTALL, man-страницы, возможно, ebuild'ы от Gentoo или других программ установки пакетов, возможно, даже MAKEFILE или исходный код), чтобы заставить их работать. В некоторых очень запущенных случаях приходится редактировать исходные файлы, чтобы заставить их работать. Однакоmakepkg
должен отработать полностью автономно, без участия пользователя. Поэтому если необходимо отредактировать make-файлы, то, возможно, придётся дополнитьPKGBUILD
патчем и применять его в функцииprepare()
, либо выполнить несколько командsed
внутри функцииprepare()
.
Более подробные руководства
32-bit – CLR – CMake – Cross – DKMS – Eclipse – Electron – Font – Free Pascal – GNOME – Go – Haskell – Java – KDE – Kernel – Lisp – Meson – MinGW – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – Shell – VCS – Web – Wine
Автоматизация
Контрольные суммы
Процесс обновления контрольных сумм для новых выпусков программ может быть автоматизирован с помощью инструмента updpkgsums
; подробнее об этом см. в разделе makepkg (Русский)#Вычисление новых контрольных сумм.
Генераторы PKGBUILD
PKGBUILD для некоторых пакетов могут быть созданы автоматически.
- Haskell: cblrepo, arch-hs
- Node.js: nodejs-npm2archAUR
- Perl: perl-cpanplus-dist-arch
- Python: pipman-gitAUR, pip2arch-gitAUR, python-pypi2pkgbuildAUR
- Ruby: gem2archAUR, pacgemAUR
- Rust: cargo-pkgbuildAUR