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

Jump to content

# PKGBUILD (Русский)

From ArchWiki

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

- 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:лицензия`). Когда некая лицензия используется в двух или более пакетах из официальных репозиториев, её добавляют в пакет 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-cppAUR[ссылка недействительна: package not found] предоставляет `netbeans` и конфликтует с `netbeans`.
- netbeans-phpAUR[ссылка недействительна: package not found] предоставляет `netbeans` и конфликтует с `netbeans`; пакет netbeans-cppAUR[ссылка недействительна: package not found] в `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 (Русский)

Hidden category:

- Pages with broken package links

PKGBUILD (Русский)
Add topic