Creating packages (Русский)

Состояние перевода:
На этой странице представлен перевод статьи
Creating packages
. Дата последней синхронизации: 23 августа 2023. Вы можете
помочь
синхронизировать перевод, если в английской версии произошли
изменения
.
Ссылки по теме
Система сборки Arch
Стандарты создания пакетов для Arch
Пользовательский репозиторий Arch
Creating packages for other distributions
makepkg (Русский)
pacman (Русский)
Patching packages
PKGBUILD (Русский)
.SRCINFO (Русский)
DeveloperWiki:Building in a clean chroot
Эта статья призвана помочь пользователям в создании собственных пакетов с помощью «портоподобной»
системы сборки
, в том числе для публикации в
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
собирает установленный пакет, который становится корневым каталогом вашего собранного пакета.
Они содержат
абсолютные
пути — это означает, что при правильном использовании этих переменных вам не нужно беспокоиться о своём рабочем каталоге.
Примечание
makepkg
, а значит, и функции
build()
и
package()
, предназначены для неинтерактивной работы. Интерактивные утилиты или скрипты, вызываемые в этих функциях, могут нарушить работу
makepkg
, особенно если они вызываются с включенным протоколированием сборки (
--log
). (См.
FS#13214
.)
Функции PKGBUILD
При сборке пакета
makepkg
перейдёт в каталог с исходными файлами, перед тем, как вызвать следующие пять функций, если они определены в PKGBUILD. Функция
package()
является обязательной в каждом PKGBUILD и будет вызываться всегда. Если какая-либо из других функций не определена, то
makepkg
просто пропустит вызов этой функции.
Во время сборки функции вызываются в том порядке, в котором они перечислены здесь.
prepare()
С помощью этой функции выполняются команды, используемые для подготовки исходных текстов к сборке, например
применение патчей
. Эта функция запускается сразу после извлечения пакета, перед
pkgver()
и функцией сборки. Если извлечение пропущено (
makepkg --noextract
), то
prepare()
не выполняется.
Примечание
(Из
PKGBUILD(5)
) Функция выполняется в режиме
bash -e
, то есть любая команда, которая завершает работу с ненулевым статусом, приводит к выходу из функции.
Когда неясно, куда поместить ту или иную функцию — в
prepare()
или
build()
, можно воспользоваться эмпирическим правилом: помещать в
prepare()
те шаги, которые должны выполняться ровно один раз после извлечения исходных текстов, а в
build()
— те шаги, которые имеет смысл повторно выполнять после внесения любых ручных правок в извлечённые файлы.
pkgver()
pkgver()
запускается после извлечения исходных текстов, их распаковки и выполнения
prepare()
. Таким образом, переменную pkgver можно обновить на этапе makepkg.
Это особенно полезно при
создании пакетов git/svn/hg/etc.
, когда процесс сборки может оставаться неизменным, но исходники могут обновляться каждый день, а то и каждый час. Старый способ сделать это заключался в том, чтобы поместить дату в поле pkgver, но тогда даже если если программа не обновлялась, то makepkg все равно пересобирал её из-за изменившегося номера версии. Некоторые полезные команды для этого —
git describe
,
hg identify -ni
и т. д. Пожалуйста, проверяйте их перед отправкой PKGBUILD, так как сбой в функции
pkgver()
может остановить сборку на корню.
Примечание
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 во избежание необходимости исправлять простейшие ошибки после отправки пакета.
Использование pkgctl для сборки в чистом chroot-окружении
Вы можете использовать
pkgctl
из
devtools
для проверки возможно ли собрать пакет там, где ещё не установлены другие пакеты. Находясь в каталоге PKGBUILD выполнить:
$ pkgctl build
И проверьте вывод на наличие возможных ошибок или предупреждений. Если пакет зависит от других пакетов AUR, эти пакеты должны быть собраны и перенесены в окружение chroot:
$ pkgctl build -I path/to/somepkg.tar.gz -I ...
Примечание
Если пакет установлен с помощью помощника AUR, велика вероятность того, что его tarball можно найти в его кэш-каталоге.
Дополнительные опции см. в
pkgctl-build(1)
.
Отправка пакетов в 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 для некоторых пакетов могут быть созданы автоматически.
Примечание
Пользователи по-прежнему несут ответственность за обеспечение соответствия пакета высоким стандартам качества перед отправкой созданных файлов в
AUR
.
Haskell
:
cblrepo
,
arch-hs
Node.js
:
nodejs-npm2arch
AUR
Perl
:
perl-cpanplus-dist-arch
AUR
Python
:
pipman-git
AUR
,
pip2arch-git
AUR
,
python-pypi2pkgbuild
AUR
Ruby
:
gem2arch
AUR
,
pacgem
AUR
Rust
:
cargo-pkgbuild
AUR
Смотрите также
How to correctly create a patch file
.
Arch Linux Classroom IRC Logs of classes about creating PKGBUILDs
.
Fakeroot approach for package installation