PKGBUILD (Русский) - ArchWiki

# PKGBUILD (Русский)

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Ссылки по теме

- Arch package guidelines
- Создание пакетов
- .SRCINFO
- Пользовательский репозиторий Arch
- Category:Package development (Русский)
- Система сборки Arch
- makepkg (Русский)

Состояние перевода: На этой странице представлен перевод статьи PKGBUILD. Дата последней синхронизации: 11 июля 2021. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

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

`PKGBUILD` — сценарий оболочки, содержащий информацию, необходимую для сборки пакета Arch Linux.

В Arch Linux пакеты собираются утилитой makepkg. При запуске makepkg находит в рабочем каталоге файл `PKGBUILD` и выполняет содержащиеся в нём указания по получению необходимых файлов, их компиляции и сборке архива пакета `название_пакета.pkg.tar.zst`. Итоговый пакет состоит из двоичных файлов и инструкций по установке; с помощью pacman его можно установить в систему.

Обязательными являются переменные `pkgname`, `pkgver`, `pkgrel` и `arch`. Параметр `license` можно не указывать, но в этом случае makepkg выдаст предупреждение. Если вы планируете распространять `PKGBUILD` среди других пользователей, лучше его всё-таки добавить.

Как правило, переменные в файле `PKGBUILD` объявляются в том порядке, в каком перечислены здесь, но требованием это не является. Главное — соблюдать синтаксис Bash.

Совет: Утилита namcap позволяет проверить `PKGBUILD` на предмет распространённых ошибок.

## Название пакета

### pkgbase

При сборке обычных пакетов эту переменную указывать не нужно: она по умолчанию принимает значение #pkgname.

При сборке разделённого пакета в ней указывают значение, которым обозначается данная группа пакетов и которое используется в имени tar-архива с исходниками. Значение не должно начинаться с дефиса. Если никакое значение не указано, то берётся первый элемент массива `pkgname`.

Все параметры и указания для разделённых пакетов по умолчанию используют глобальные значения из `PKGBUILD`. Тем не менее, следующие параметры могут быть переопределены в функциях упаковки каждого из разделённых пакетов: #pkgdesc, #arch, #url, #license, #groups, #depends, #optdepends, #provides, #conflicts, #replaces, #backup, #options, #install и #changelog.

### pkgname

Либо название пакета (например, `pkgname='foo'`), либо, в случае разделённых пакетов, массив названий (например, `pkgname=('foo' 'bar')`). Название пакета должно состоять из латинских букв в нижнем регистре, цифр и символов `@._+-` ("собака", точка, подчёркивание, плюс, дефис). Название не может начинаться с дефиса или точки. Для удобства принято за правило, что `pkgname` должен совпадать с названием tar-архива исходников программы. Так, если код программы упакован в архив `foobar-2.5.tar.gz`, то используйте `pkgname=foobar`.

## Версия

### pkgver

Версия пакета. Должна совпадать с номером версии, который используется автором программы в апстриме. Состоит из букв, чисел, точек и подчёркиваний, но дефис использовать нельзя. Если автор программы использовал в номере версии дефис, замените его на символ подчёркивания. При дальнейшем использовании этой переменной в `PKGBUILD` подчёркивание можно легко изменить обратно на дефис, например: `source=("$pkgname-${pkgver//_/-}.tar.gz")`.

Примечание: Если в апстриме версии нумеруются на основе временных меток, вроде `30102014`, используйте "перевёрнутую" дату (`20141030`, формат ISO 8601). В противном случае пакет не будет отображаться как новейшая версия.
Совет:

- Относительный порядок для нестандартных значений можно протестировать утилитой vercmp(8) из пакета pacman.
- makepkg может автоматически обновлять значение данной переменной с помощью функции `pkgver()` файла `PKGBUILD`. Подробнее см. VCS package guidelines#The pkgver() function.

### pkgrel

Номер релиза. Обычно положительное целое число. Позволяет различать последовательные сборки одной и той же версии пакета. Каждый раз, когда в `PKGBUILD` вносятся исправления или дополнения, влияющие на итоговый пакет, значение этой переменной необходимо увеличить на 1. Когда выходит новая версия программы, `pkgrel` сбрасывается до значения 1. В исключительных случаях могут использоваться некоторые другие форматы, вроде старший.младший.

### epoch

Важно: Переменная `epoch` должна использоваться исключительно в тех случаях, когда без неё действительно не обойтись.

Позволяет сделать версию пакета более новой по отношению ко всем предыдущим версиям более низких "эпох". Может принимать неотрицательные значения; по умолчанию равна 0. Применяется в случаях, когда изменилась схема нумерации версий пакета (или используется буквенно-цифровая нумерация), что ломает обычную логику сравнения версий. Пример:

    pkgver=5.13
    pkgrel=2
    epoch=1

    1:5.13-2

О сравнении версий см. pacman(8).

## Общие

### pkgdesc

Описание пакета. Рекомендованная длина — не более 80 символов. Описание не должно содержать названия самого пакета в явном виде, за исключением случаев, когда название приложения от него отличается. Например, вместо `pkgdesc="Nedit is a text editor for X11"` ("Nedit — текстовый редактор для X11") лучше указать просто `pkgdesc="Text editor for X11"` ("Текстовый редактор для X11").

Также не забывайте использовать в описании пакета ключевые слова, чтобы его было проще найти с помощью поиска.

### arch

Массив названий архитектур, под которые пакет может быть собран по данному `PKGBUILD`. Arch официально поддерживает только `x86_64`, но существуют сторонние проекты для других архитектур. Например, Arch Linux 32 работает с `i686` и `pentium4`, а Arch Linux ARM предоставляет поддержку для `arm` (armv5), `armv6h` (armv6 hardfloat), `armv7h` (armv7 hardfloat) и `aarch64` (armv8 64-bit).

В параметре используются два типа значений:

- `arch=('any')` — пакет соберётся на любой архитектуре и в откомпилированном состоянии будет архитектурно-независимым (пакеты со сценариями оболочки, шрифтами, темами, многими типами расширений и т.п.).
- `arch=('x86_64')` — пакет соберётся только на указанной(-ых) архитектуре(-ах). После компиляции пакет становится архитектурно-зависимым. В параметре указываются все архитектуры, для которых будет работать данный `PKGBUILD`. Для пакетов из официальных репозиториев и AUR в параметре `arch` указывается значение x86_64, хотя пакеты из AUR могут также поддерживать дополнительные архитектуры.

В процессе сборки значение целевой архитектуры хранится в переменной `$CARCH`.

### url

Адрес официального сайта той программы, которая собирается в пакет.

### license

Лицензия, под которой распространяется программа. В пакете licenses (зависимость мета-пакета base) собраны наиболее распространённые лицензии; при установке они размещаются в каталоге `/usr/share/licenses/common/`. Если программа распространяется под одной из этих лицензий, то в параметре необходимо указать значение, совпадающее с названием соответствующего подкаталога (например, `license=('GPL')`). Если используется лицензия, отсутствующая в licenses, необходимо сделать следующее:

1. Укажите в параметре `license` значение `custom` (либо `custom:лицензия`). Когда некая лицензия используется в двух или более пакетах из официальных репозиториев (включая репозиторий community), её добавляют в пакет licenses.
2. Скопируйте файл лицензии в каталог `/usr/share/licenses/пакет/`, например, `/usr/share/licenses/foobar/LICENSE`. Проще всего это сделать командой

       install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"

3. Если лицензию можно найти только на веб-сайте, то её придётся включить в пакет отдельно.

- Лицензии BSD, ISC, MIT, zlib/png, Python и OFL являются особыми случаями и не включены в пакет licenses. В массиве `license` они указываются так же, как и обычные лицензии (`license=('BSD')`, `license=('ISC')`, `license=('MIT')`, `license=('ZLIB')`, `license=('Python')` и `license=('OFL')`), но технически это custom-лицензии из-за особых правил в отношении авторских прав. Файл любой из этих лицензий должен храниться в каталоге `/usr/share/licenses/пакет/`.
- Некоторые пакеты могут распространяться сразу под несколькими лицензиями. В этом случае их все нужно указать в массиве `license`, например: `license=('GPL' 'custom:лицензия')`.
- У лицензии (L)GPL есть разные версии и варианты. Приняты следующие соглашения:
  - (L)GPL — (L)GPLv2 или более поздняя
  - (L)GPL2 — только (L)GPL2
  - (L)GPL3 — (L)GPL3 или более поздняя
- Если необходимый тип лицензии определить не удаётся, в соответствии с рекомендациями из PKGBUILD.proto можно использовать `unknown`. Тем не менее, стоит отправить запрос разработчикам и уточнить условия, под которыми программа (не) распространяется.

Совет: Некоторые разработчики ПО не предоставляют отдельный файл лицензии или же описывают правила распространения в файле `ReadMe.txt`. Эту информацию можно извлечь в отдельный файл в процессе работы функции `build()` чем-то вроде `sed -n '/This software/,/ thereof./p' ReadMe.txt > LICENSE`.

См. также Nonfree applications package guidelines.

Информацию о лицензиях свободного ПО и их перспективах можно найти в следующих статьях:

- Википедия:Лицензия свободного программного обеспечения
- Википедия:Сравнение лицензий свободного ПО с открытым исходным кодом (англ.)
- Правовые вопросы для проектов свободного ПО (англ.)
- GNU Project - Различные лицензии с комментариями
- Debian - Информация о лицензиях
- Open Source Initiative - Список лицензий по названию (англ.)

### groups

Группа, к которой принадлежит пакет. Например, при установке группы plasma устанавливаются все пакеты, которые в неё входят.

## Зависимости

Примечание: Можно указать дополнительные параметры-массивы для конкретных архитектур, добавив к имени переменной символ подчёркивания и название архитектуры (например, `optdepends_x86_64=()`).

### depends

Список пакетов, которые необходимы для сборки и работы программы. Зависимости, определяемые в функции `package()`, нужны только для работы.

Версию пакета-зависимости можно ограничить операторами сравнения, например, `depends=('foobar>=1.8.0')`; если ограничений несколько, то они указываются по отдельности (`depends=('foobar>=1.8.0' 'foobar<2.0.0')`).

В массиве `depends` указываются все зависимости верхнего уровня, в том числе и те, которые теоретически могут установиться неявно. Представьте, что пакет foo зависит от bar и baz, причём bar тоже зависит от baz. Если не указать baz как зависимость foo, положившись на "неявную" установку, это однозначно приведёт к проблемам, если в какой-то момент bar откажется от использования baz. Pacman не установит baz при чистой установке foo, или же удалит baz из системы как пакет-сироту, в результате чего foo упадёт при работе или будет работать некорректно.

В некоторых особых случаях определённые пакеты всё же можно не указывать. Так, glibc не может быть удалён, так как в системе всегда должна быть стандартная библиотека Си, а python будет в любом случае установлен, если ваш пакет зависит хотя бы от одного python-модуля, так как для последнего python по определению является зависимостью.

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

Если зависимость представляет собой библиотеку (например, `depends=('libfoobar.so')`), то makepkg найдёт двоичный файл, которому она нужна, и определит необходимую версию библиотеки. Если указать версию явно (`depends=('libfoobar.so=2')`), то автоматический поиск версии выполняться не будет.

### makedepends

Список пакетов, которые нужны только для сборки пакета. Версия пакета обозначается так же, как и в массиве `depends`. Если пакеты из `depends` неявно используются при сборке, указывать их повторно в `makedepends` не нужно.

Совет: Команда ниже позволяет убедиться, что пакет входит в группу base-devel либо устанавливается неявно одним из пакетов этой группы:

    $ LC_ALL=C pacman -Si $(pactree -rl package) 2>/dev/null | grep -q "^Groups *:.*base-devel"

Примечание: При сборке пакета утилитой makepkg предполагается, что пакеты из группы base-devel уже установлены. Указывать их в массиве `makedepends` не нужно.

### optdepends

Список пакетов, которые не являются необходимыми для работы программы, но могут расширить её функционал. Иногда это означает, что некоторые исполняемые файлы, предоставляемые пакетом, откажутся работать без соответствующих опциональных зависимостей [1]. Если программа может работать с помощью нескольких альтернативных зависимостей, их все нужно указать здесь, а не в массиве `depends`.

Рядом с названием опциональной зависимости необходимо указать краткое описание дополнительной функциональности, которую она предоставляет:

    optdepends=('cups: printing support'
                'sane: scanners support'
                'libgphoto2: digital cameras support'
                'alsa-lib: sound support'
                'giflib: GIF images support'
                'libjpeg: JPEG images support'
                'libpng: PNG images support')

### checkdepends

Список пакетов, которые необходимы программе для различных проверок, но не во время выполнения. Формат описания пакетов тот же, что и в параметре `depends`. Эти зависимости нужны только для функции check() (если она есть), вызываемой makepkg в процессе работы.

Примечание: При сборке пакета утилитой makepkg предполагается, что пакеты из группы base-devel уже установлены. Указывать их в массиве `checkdepends` не нужно.

## Связи между пакетами

Примечание: Можно указать дополнительные параметры-массивы для конкретных архитектур, добавив к имени переменной символ подчёркивания и название архитектуры (например, `conflicts_x86_64=()`).

### provides

Список программ, функциональность которых предоставляется данным пакетом (или виртуальные пакеты вроде `cron` или `sh`). В системе могут быть установлены несколько пакетов с одинаковыми пунктами в `provides`, если они не конфликтуют (массив `conflicts`).

Примечание: Поскольку пакеты иногда требуют определённую версию пакета-зависимости, стоит указать версию предоставляемого пакета (`pkgver` и, возможно, `pkgrel`). Например, если qt-foobar является изменённым пакетом qt версии 3.3.8, то необходимо указать `provides=('qt=3.3.8')`; если этого не сделать, то пакеты, которые зависят от определённой версии qt, могут перестать работать. Указывать собственный `pkgname` пакета не нужно, поскольку это подразумевается неявно.

### conflicts

Список программ, которые, будучи установленными, создают проблемы в работе пакета. Такие пакеты (как и пакеты, "предоставляющие" их) должны быть удалены. Версии конфликтующих пакетов указываются в формате, принятом в массиве `depends`.

Обратите внимание, что на конфликты проверяются и `pkgname`, и массив `provides` пакета. Следовательно, если ваш пакет предоставляет какую-то функциональность и другой пакет предоставляет её же, указывать этот конфликтующий пакет в `conflicts` не нужно. Например:

- netbeans неявно предоставляет функциональность `netbeans` (самого себя).
- netbeans-javaseAUR предоставляет `netbeans` и конфликтует с `netbeans`.
- netbeans-phpAUR предоставляет `netbeans` и конфликтует с `netbeans`; пакет netbeans-javaseAUR в `conflicts` не указывается, поскольку предоставляющие одинаковую функциональность пакеты и так неявно конфликтуют друг с другом.

### replaces

Список устаревших программ, которые пакет должен заменить. Например, для пакета wireshark-qt используется параметр `replaces=('wireshark')`. При синхронизации баз данных pacman немедленно переустанавливает пакет, если в официальных репозиториях обнаружена подходящая замена с нужным пуктом в массиве `replaces`. Если вы хотите всего лишь создать альтернативную версию существующего пакета или собираетсь загрузить пакет в AUR, то лучше использовать массивы `conflicts` и `provides`, которые проверяются только при явной попытке установить конфликтующий пакет.

## Прочие

### backup

Список файлов, которые могут изменяться пользователем и по этой причине должны сохраняться во время обновления или удаления пакета. Чаще всего здесь указывают файлы настроек из каталога `/etc`.

В качестве значений `backup` используются относительные пути без ведущего слэша (`/`). Так, вместо `/etc/pacman.conf` необходимо указать `etc/pacman.conf`.

Во время обновления пакета новые версии файлов будут сохраняться с расширением .pacnew (например, `file.pacnew`), чтобы избежать перезаписи существующего, изменённого пользователем файла. При удалении пакета (кроме случая, когда удаление производится командой `pacman -Rn`) происходит аналогичная операция — изменённые пользователем файлы сохраняются с суффиксом .pacsave (`file.pacsave`).

Подробнее см. Файлы Pacnew и Pacsave.

### options

Позволяет переопределить стандартное поведение makepkg, определённое файлом `/etc/makepkg.conf`. Чтобы задать новый параметр, укажите его в данном массиве. Чтобы отключить параметр, добавьте перед ним символ `!`.

Список доступных параметров можно найти в руководстве PKGBUILD(5).

### install

Название входящего в пакет установочного сценария .install. pacman может сохранять и выполнять различные специфичные для пакета сценарии при установке, удалении и обновлении пакета. Сценарий содержит следующие функции, выполняемые на разных этапах:

- `pre_install` — выполняется перед извлечением файлов. Передаётся один аргумент: новая версия пакета.
- `post_install` — выполняется после извлечения файлов. Передаётся один аргумент: новая версия пакета.
- `pre_upgrade` — выполняется перед извлечением файлов. Передаётся два аргумента в следующем порядке: новая версия пакета, прежняя версия пакета.
- `post_upgrade` — выполняется после извлечения файлов. Передаётся два аргумента в следующем порядке: новая версия пакета, прежняя версия пакета.
- `pre_remove` — выполняется перед удалением файлов. Передаётся один аргумент: прежняя версия пакета.
- `post_remove` — выполняется после удаления файлов. Передаётся один аргумент: прежняя версия пакета.

Каждая функция выполняется в chroot-окружении внутри установочного каталога pacman. Подробнее см. это обсуждение.

Совет:

- Прототип .install-сценария находится в файле /usr/share/pacman/proto.install.
- pacman#Хуки работают схожим образом.

Примечание: Не завершайте сценарий командой `exit`. Это помешает выполнению функций.

### changelog

Название файла журнала изменений пакета. Следующая команда позволяет просмотреть журнал установленного пакета (при условии, что соответствующий файл существует):

    $ pacman -Qc пакет

## Исходный код

### source

Массив со списком необходимых для сборки пакета файлов. Как правило, описывает местонахождение файлов с исходным кодом, чаще всего в виде HTTP- или FTP-ссылки. В этом параметре часто находят применение установленные ранее значения `pkgname` и `pkgver` (например, `source=("https://example.com/$pkgname-$pkgver.tar.gz")`).

Файлы также могут находиться в одном каталоге с `PKGBUILD`, в этом случае их имена напрямую добавляются в массив. Перед началом процесса сборки все указанные в `source` файлы загружаются или проверяются на наличие, и если какие-то из них найдены не будут, то makepkg прекратит работу.

Файлы .install распознаются makepkg автоматически и включать их в `source` не нужно. Файлы с суффиксами .sig, .sign и .asc makepkg опознаёт как PGP-подписи и проверяет с их помощью целостность соответствующих файлов.

Важно: Имена загружаемых файлов с исходным кодом должны быть уникальными, так как система может быть настроена на использование единого каталога SRCDEST для сборки программ. Например, если использовать номер версии программы в качестве имени файла, потенциально возможен конфликт при наличии другой программы с совпадающей версией. Чтобы этого избежать, придумана специальная схема именования файлов, обеспечивающая уникальность: `source=('уникальное_название_пакета::ссылка_на_файл')`. Пример: `source=("$pkgname-$pkgver.tar.gz::https://github.com/coder/program/archive/v$pkgver.tar.gz")`.
Совет:

- Можно указать массив `source` для конкретной архитектуры, добавив к названию символ подчёркивания и архитектуру (например, `source_x86_64=()`). Каждому такому массиву должен соответствовать массив проверки целостности по контрольным суммам, например, `sha256sums_x86_64=()`.
- Некоторые серверы ограничивают загрузку, фильтруя запросы по строке User-Agent; это можно обойти с помощью DLAGENTS.
- С помощью URL типа `file://` можно указать в `source` название находящегося на вашем компьютере файла или каталога. Так, ссылка на локальный git-репозиторий будет иметь вид `"$pkgname"::"git+file:///путь/к/репозиторию"`.
- Подробнее об VCS-опциях (вроде работы с отдельной веткой git или коммитом) см. PKGBUILD(5) § USING VCS SOURCES и VCS package guidelines#VCS sources .

### noextract

Массив со списком файлов из `source`, которые makepkg не должен извлекать из архива. Используется, если архив не может быть распакован стандартной утилитой `/usr/bin/bsdtar` или же устанавливается "как есть". Если используется другая утилита для разархивации (например, lrzip), добавьте её в массив `makedepends`, а в первой строке функции prepare() извлеките исходники вручную, например:

    prepare() {
      lrzip -d исходник.tar.lrz
    }

Обратите внимание, что хотя `source` принимает в качестве значений ссылки, в `noextract` могут указываться только имена файлов:

    source=("http://foo.org/bar/foobar.tar.xz")
    noextract=('foobar.tar.xz')

Чтобы не извлекать вообще ничего, можно сделать следующее:

- Если `source` содержит только URL-ссылки без каких либо имён файлов, обрежьте всё до последнего символа слэша включительно:

      noextract=("${source[@]##*/}")

- Если `source` содержит только имена файлов, обрежьте часть после разделителя `::` (взято из файла PKGBUILD firefox-i18n):

      noextract=("${source[@]%%::*}")

### validpgpkeys

Массив с PGP-отпечатками. Если указать этот параметр, makepkg будет принимать подписи только от указанных в нём ключей, игнорируя связку ключей (keyring). Если файл исходников подписан подключом, makepkg будет по прежнему использовать основной ключ для сравнения.

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

Примечание: Узнать отпечаток нужного ключа можно командой `gpg --list-keys --fingerprint <KEYID>`.

Подробнее см. makepkg#Проверка цифровых подписей.

## Целостность

Перечисленные ниже переменные представляют собой массивы строк контрольных сумм, которые используются для проверки на целостность соответствующих файлов из массива source. Если вместо контрольной суммы указать значение `SKIP`, то соответствующий файл проверяться не будет.

Типы и значения контрольных сумм должны предоставляться разработчиками программы, например, в объявлении о релизе. Если доступны несколько типов сумм, следует выбирать более надёжную: `sha256` вместо `sha1`, а `sha1` вместо `md5`. Целостность файлов лучше проверять сразу после загрузки.

Примечание: Кроме того, если разработчики предоставляют цифровые подписи, то файлы подписей необходимо добавить в массив source, а отпечатки ключей PGP — в массив validpgpkeys. Это позволит проверить подлинность файлов во время сборки.

Значения переменных можно сгенерировать опцией makepkg `-g`/`--geninteg`; как правило, они добавляются командой `makepkg -g >> PKGBUILD`. Утилита `updpkgsums` из пакета pacman-contrib позволяет обновить значения переменных, когда они уже заданы в файле `PKGBUILD`. Оба инструмента используют те типы контрольных сумм, которые уже указаны в `PKGBUILD`, или `md5sums`, если ни одна переменная не задана.

Метод проверки целостности можно задать опцией `INTEGRITY_CHECK` в файле `/etc/makepkg.conf`. Подробнее см. makepkg.conf(5).

Примечание: Можно задать массив `source` для конкретной архитектуры, указав её название через символ подчёркивания (например, `sha256sums_x86_64=()`).

### md5sums

Массив 128-битных контрольных сумм MD5 для файлов из массива `source`.

### sha1sums

Массив 160-битных контрольных сумм SHA-1 для файлов из массива `source`.

### sha256sums

Массив контрольных сумм SHA-2 с размером дайджеста 256 битов.

### sha224sums, sha384sums, sha512sums

Массив контрольных сумм SHA-2 с размерами дайджеста 224, 384 и 512 битов соответственно. Редко используемые альтернативы `sha256sums`.

### b2sums

Массив контрольных сумм BLAKE2 с размером дайджеста 512 битов.

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

- Руководство PKGBUILD(5).
- Пример файла PKGBUILD.

Category:

- Package development (Русский)