Creating packages (Русский)

From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи Creating packages. Дата последней синхронизации: 23 августа 2023. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Эта статья призвана помочь пользователям в создании собственных пакетов с помощью «портоподобной» системы сборки, в том числе для публикации в 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), который делает следующее:

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

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

Загрузите исходный 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(), так как проверка помогает убедиться в том, что программа правильно и хорошо работает с зависимостями.

Пользователи, которым она не нужна (а иногда и сопровождающие, которые не могут исправить пакет для её прохождения), могут отключить её с помощью BUILDENV+=('!check') в PKGBUILD/makepkg.conf или вызвать 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 выполнит:

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

и многое другое.

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

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

Пожалуйста, прочитайте правила отправки пакетов в AUR, где подробно описан процесс отправки.

Резюме

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

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

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

Более подробные руководства

Указания по созданию пакетов

32-bitCLRCMakeCrossDKMSEclipseElectronFontFree PascalGNOMEGoHaskellJavaKDEKernelLispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustShellVCSWebWine

Автоматизация

Контрольные суммы

Процесс обновления контрольных сумм для новых выпусков программ может быть автоматизирован с помощью инструмента updpkgsums; подробнее об этом см. в разделе makepkg (Русский)#Вычисление новых контрольных сумм.

Генераторы PKGBUILD

PKGBUILD для некоторых пакетов могут быть созданы автоматически.

Примечание: Пользователи по-прежнему несут ответственность за обеспечение соответствия пакета высоким стандартам качества перед отправкой созданных файлов в AUR.

Смотрите также