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

Jump to content
From ArchWiki

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

- Создание пакетов
- PKGBUILD (Русский)
- .SRCINFO
- Пользовательский репозиторий Arch
- pacman (Русский)
- Официальные репозитории
- Система сборки Arch

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

makepkg — скрипт для автоматизации сборки пакетов. Требования для работы — Unix-платформа с системой сборки и файл PKGBUILD.

makepkg входит в состав пакета pacman.

## Настройка

Параметры настройки makepkg подробно описаны в руководстве makepkg.conf(5).

Общесистемные настройки хранятся в файле `/etc/makepkg.conf`, пользовательские — в `$XDG_CONFIG_HOME/pacman/makepkg.conf` или `~/.makepkg.conf`. Рекомендуется проверять настройки перед сборкой пакетов.

### Информация о создателе пакета

Каждый пакет содержит метаданные, в том числе информацию о создателе пакета (packager). По умолчанию скомпилированный пакет создаётся с пометкой `Unknown Packager`. Однако если на одной системе компиляцией занимаются несколько пользователей или вы планируете распространять пакет среди других пользователей, то имеет смысл указать настоящие контактные данные, задав переменную `PACKAGER` в файле `makepkg.conf`.

Создателя установленного пакета можно узнать командой:

    $ pacman -Qi пакет

    ...
    Packager       : John Doe <john@doe.com>
    ...

Кроме того, если указать цифровую подпись создателя в параметре `GPGKEY`, то она тоже будет автоматически добавляться к пакету.

### Расположение файлов пакета

makepkg создаёт пакет в рабочем каталоге в формате tar-архива, а исходный код загружает в подкаталог `src/`. Целевые каталоги можно переназначить, например, чтобы все собранные пакеты хранились в `~/build/packages/`, а все исходные данные — в `~/build/sources/`.

Можно задать следующие значения в `makepkg.conf`:

- `PKGDEST` — каталог для собранных пакетов (расширение `.pkg.tar.xz`);
- `SRCDEST` — каталог для исходных файлов (расширение `.tar.gz`; в каталог `src/` будут помещаться символические ссылки на новое местоположение);
- `SRCPKGDEST` — каталог для пакетов исходных данных (расширение `.src.tar.gz`, создаются командой `makepkg -S`).

Совет: Каталог `PKGDEST` можно очистить, например, командой `paccache -c ~/build/packages/` (см. pacman#Очистка кэша пакетов).

### Проверка цифровых подписей

Примечание: При проверке цифровых подписей makepkg полагается исключительно на пользовательские связки ключей. Связки ключей pacman не используются [1].

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

Если нужный открытый ключ отсутствует, то файл PKGBUILD, скорее всего, содержит пункт validpgpkeys с идентификаторами ключей. Ключи можно импортировать вручную или же найти их на сервере ключей и импортировать оттуда.

## Использование

Для корректной работы makepkg нужно установить группу пакетов base-devel. Пакеты из этой группы можно не указывать в качестве зависимостей для сборки (makedepends) в файле PKGBUILD.

Примечание:

- Убедитесь, что утилита sudo настроена должным образом для команд, передаваемых pacman.
- Запуск makepkg от root-пользователя запрещён: [2], [3]. Поскольку `PKGBUILD` может содержать произвольные команды, сборка пакетов под root-аккаунтом признана небезопасной [4]. Если у пользователя нет доступа к аккаунту обычного пользователя, то следует запускать makepkg от пользователя "nobody".

Чтобы собрать пакет, первым делом необходимо создать файл PKGBUILD, который представляет собой скрипт сборки. Написание скрипта описано в статье Создание пакетов. Скрипты для существующих пакетов можно найти в дереве каталогов Системы сборки Arch, а также в AUR. После того, как `PKGBUILD` получен, переместитесь в каталог с ним и выполните команду сборки пакета:

    $ makepkg

Если в системе не установлены необходимые зависимости, makepkg предупредит вас об этом и отменит сборку. Если задать флаг `-s`/`--syncdeps`, то makepkg самостоятельно установит недостающие зависимости и соберёт пакет.

    $ makepkg --syncdeps

С флагом `-r`/`--rmdeps` makepkg после сборки удалит те зависимости, которые будут больше не нужны. Если вы постоянно занимаетесь сборкой пакетов и не хотите загрязнять систему пакетами-сиротами, то стоит также ознакомиться со статьёй pacman/Tips and tricks#Удаление неиспользуемых пакетов.

Примечание:

- Устанавливаемые пакеты-зависимости должны находиться в подключённых репозиториях; в статье Pacman#Репозитории и зеркала описана настройка репозиториев. Кроме того, зависимости можно установить вручную командой `pacman -S --asdeps зависимость1 зависимость2`.
- При установке зависимостей используются только глобальные значения переменных, то есть переопределить значения, например, внутри функции упаковки разделённого пакета (split package) не получится.

Когда все зависимости установлены и сборка пакета завершилась успешно, в рабочем каталоге появится файл пакета (`имя-пакета-версия-пакета.pkg.tar.zst`). Чтобы установить его в систему, используйте флаг `-i`/`--install` (работает аналогично команде `pacman -U имя-пакета-версия-пакета.pkg.tar.zst`):

    $ makepkg --install

С флагом `-c`/`--clean` makepkg удалит оставшиеся после сборки промежуточные файлы и каталоги (например, распакованные в `$srcdir` файлы). Это полезно при многократных сборках одного и того же пакета или его обновления в одном рабочем каталоге. Это предотвратит добавление устаревших файлов в новые сборки:

    $ makepkg --clean

Подробнее см. makepkg(8).

## Советы и рекомендации

### Снижение времени загрузки и извлечения исходников

При многократной пересборке одного и того же пакета, особенно в случае VCS, используйте `SRCDEST`, чтобы сэкономить время на скачивание и распаковку файлов с исходным кодом.

### Оптимизация двоичных пакетов

Повысить производительность программ можно на этапе сборки пакета за счет возможностей компилятора по оптимизации кода. Однако нужно иметь в виду, что двоичные файлы, скомпилированные под специфическую архитектуру процессора, не будут правильно работать на других машинах. Если говорить об архитектуре x86_64, то редко когда достигнутый эффект повышения производительности стоит затраченного на пересборку официальных пакетов времени.

С другой стороны, снизить производительность, задав "нестандартные" флаги компилятора — проще простого. Чаще всего тонкая настройка компилятора приносит пользу лишь в определённой ситуации и не стоит применять её ко всем пакетам без разбора. Если вы не можете доказать повышение производительности путем тестов, то скорее всего, его просто нет! Статьи из Gentoo-wiki Оптимизации GCC и Safe CFLAGS содержат больше информации по оптимизации компилятора.

Опции, переданные компилятору C/C++ (например, gcc или clang) зависят от переменных окружения `CFLAGS`, `CXXFLAGS` и `CPPFLAGS`. В системе сборки Arch makepkg извлекает значения переменных окружения из файла настроек `makepkg.conf` и использует их в качестве опций. Значения по умолчанию выбраны таким образом, чтобы создаваемые двоичные программы работали на широком диапазоне машин.

Примечание:

- Следует помнить, что не все системы сборки используют переменные, указанные в файле `makepkg.conf`. Например, cmake игнорирует переменную `CPPFLAGS`. Как следствие, часто в файлах PKGBUILD можно увидеть различные обходные решения для систем сборки, используемых для конкретного программного обеспечения.
- Настройки в файле `Makefile` и аргументы в командах компиляции имеют приоритет над значениями в `makepkg.conf`, что может привести к их переопределению.

Компилятор GCC может автоматически обнаруживать и включать безопасные оптимизации, доступные для конкретной архитектуры. Чтобы использовать эту особенность, сначала удалите любые `-march` и `-mtune` флаги, а затем добавьте опцию `-march=native`. Например:

    /etc/makepkg.conf

    CFLAGS="-march=native -O2 -pipe -fno-plt"
    CXXFLAGS="${CFLAGS}"

Чтобы узнать, какие флаги эта команда разблокирует на вашей машине, выполните:

    $ gcc -march=native -v -Q --help=target

Примечание: Если вы укажете значение, отличное от `-march=native`, то `-Q --help=target` не сработает [5]. Вам придётся пройти через фазу компиляции, чтобы узнать, какие опции на самом деле были включены. Подробнее см. Gentoo:Safe CFLAGS#Manual.

Начиная с pacman версии 5.2.2 файл `makepkg.conf` также содержит переменную окружения `RUSTFLAGS`, в которой можно указать флаги, передаваемые компилятору языка Rust. Если указать в переменной `RUSTFLAGS` значение `-C target-cpu=native`, компилятор включит возможные для архитектуры вашего процессора алгоритмы оптимизации.

    /etc/makepkg.conf

    RUSTFLAGS="-C opt-level=2 -C target-cpu=native"

Чтобы узнать, какие возможности процессора можно включить этой настройкой, выполните:

    $ rustc -C target-cpu=native --print cfg

Если в команде выше указать `--print cfg` без `-C target-cpu=native`, то будет выведена стандартная конфигурация. Можно также изменить значение параметра `opt-level` на `3`, `s` или `z`, подробнее см. документацию компилятора Rust.

### Сокращение времени компиляции

#### Параллельная компиляция

Для сборки пакетов с помощью make используется переменная окружения `MAKEFLAGS`, которая определяет дополнительные опции для утилиты make. Установить значение этой переменной можно также в файле `makepkg.conf`.

Пользователи с многоядерными/многопроцессорными системами могут указать количество одновременно запускаемых задач. Это делается с помощью утилиты для определения количества доступных ядер nproc, например `MAKEFLAGS="-j$(nproc)"`. Некоторые файлы PKGBUILD переопределяют это значение на `-j1`, чтобы избежать состояний гонки или просто потому что многопоточная работа не поддерживается изначально. Если сборка пакета завершилась неудачно из-за описанных выше изменений в `MAKEFLAGS`, то нужно создать отчёт об ошибке или, в случае пакета из AUR, сообщить сопроводителю пакета.

Другие возможные опции можно найти в руководстве make(1).

#### Сборка из файлов в памяти

Если компиляция требует много операций ввода-вывода и обработки маленьких файлов, перемещение рабочего каталога во временную файловую систему tmpfs может сократить время компиляции.

Переменная `BUILDDIR` может быть временно экспортирована в makepkg, чтобы установить рабочий каталог в существующий раздел с tmpfs. Например:

    $ BUILDDIR=/tmp/makepkg makepkg

Чтобы сделать эту настройку постоянной, нужно раскомментировать опцию `BUILDDIR` файла настроек `/etc/makepkg.conf`. Если, к примеру, установить это значение `BUILDDIR=/tmp/makepkg`, то будет использоваться обычная временная файловая система Arch `/tmp`.

Примечание:

- Старайтесь не компилировать большие пакеты в tmpfs, чтобы не произошло исчерпания памяти.
- Каталог tmpfs должен быть смонтирован без опции `noexec`, потому что иначе собранный двоичный пакет будет невозможно исполнить.
- Также помните, что собранные в tmpfs пакеты будут удалены при перезагрузке. Задайте параметр PKGDEST, чтобы собранный пакет автоматически перемещался в "постоянный" каталог.

#### Использование кэша компиляции

Применение ccache сокращает время сборки за счет многократного использования кэша компиляции.

### Вычисление новых контрольных сумм

Установите пакет pacman-contrib и выполните следующую команду в каталоге с файлом `PKGBUILD`, чтобы сгенерировать новые контрольные суммы:

    $ updpkgsums

`updpkgsums` использует `makepkg --geninteg` для вычисления контрольных сумм. Подробнее см. обсуждение на форуме.

Контрольные суммы также можно получить посредством команды `sha256sum`, после чего полученные значения следует вручную добавить к массиву `sha256sums` в файле `PKGBUILD`.

### Применение других алгоритмов сжатия

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

    $ PKGEXT='.pkg.tar' makepkg

Другой пример, с использованием алгоритма сжатия lzop (необходим пакет lzop):

    $ PKGEXT='.pkg.tar.lzo' makepkg

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

### Использование нескольких ядер при сжатии

xz поддерживает симметричную многопроцессорность (SMP) посредством флага `--threads` для ускорения сжатия. Например, чтобы разрешить makepkg использовать все имеющиеся в наличии ядра CPU, отредактируйте массив `COMPRESSXZ` в `/etc/makepkg.conf`:

    COMPRESSXZ=(xz -c -z --threads=0 -)

pigz — параллельная реализация gzip, по умолчанию использует все доступные ядра CPU. Если необходимо задействовать меньшее количество ядер, то используется флаг `-p/--processes`:

    COMPRESSGZ=(pigz -c -f -n)

pbzip2 — параллельная реализация bzip2, также использует максимально возможное количество ядер по умолчанию. Флаг `-p#` используется для выбора меньшего количества ядер (примечание: между `-p` и числом ядер не должно быть пробелов):

    COMPRESSBZ2=(pbzip2 -c -f)

zstd поддерживает симметричную многопроцессорность (SMP) посредством флага `--threads` для ускорения сжатия. Например, чтобы разрешить makepkg использовать все имеющиеся в наличии ядра CPU, отредактируйте массив `COMPRESSZST` в `/etc/makepkg.conf`:

    COMPRESSZST=(zstd -c -z -q --threads=0 -)

### Вывод списка пакетов по имени создателя

expac — программа для работы с базой данных pacman. Если необходимо вывести список всех установленных пакетов, создателем которых является создатель-пакета, выполните:

    $ expac "%n %p" | grep "создатель-пакета" | column -t

Команда для вывода списка пакетов, создатель которых указан в переменной `PACKAGER` файла `/etc/makepkg.conf` (покажет только пакеты из репозиториев, определенных в `/etc/pacman.conf`):

    $ . /etc/makepkg.conf; grep -xvFf <(pacman -Qqm) <(expac "%n\t%p" | grep "$PACKAGER$" | cut -f1)

### Сборка 32-битных пакетов в 64-битной системе

Важно: Если вы попытаетесь собрать пакет linux указанным ниже способом, результатом будет сообщение об ошибке.

Предварительно разблокируйте репозиторий multilib и установите группу пакетов multilib-devel.

Затем создайте 32-битный файл настроек

    ~/.makepkg.i686.conf

    CARCH="i686"
    CHOST="i686-unknown-linux-gnu"
    CFLAGS="-m32 -march=i686 -mtune=generic -O2 -pipe"
    CXXFLAGS="${CFLAGS}"
    LDFLAGS="-m32 -Wl,-O1,--sort-common,--as-needed,-z,relro"

и выполните:

    $ linux32 makepkg --config ~/.makepkg.i686.conf

## Решение проблем

### Выбор каталога установки при сборке в QMake

QMake генерирует файл `makefile`, в котором для указания каталога установки используется переменная окружения `INSTALL_ROOT`. Например, вот как будет выглядеть функция package:

    PKGBUILD

    ...
    package() {
    	cd "$srcdir/${pkgname%-git}"
    	make INSTALL_ROOT="$pkgdir" install
    }
    ...

Обратите внимание, что Qmake тоже должен быть соответствующим образом настроен. К примеру, добавьте следующие строки в ваш .pro-файл.

    YourProject.pro

    ...
    target.path = /usr/local/bin
    INSTALLS += target
    ...

### WARNING: Package contains reference to $srcdir

Подобное предупреждение означает, что строковый литерал, указанный в переменных `$srcdir` или `$pkgdir`, каким-то образом оказался в одном или нескольких файлах вашего пакета [6].

Чтобы определить, в каких именно файлах, выполните следующую команду в рабочем каталоге сборки:

    $ grep -R "$PWD/src" pkg/

Одной из причин появления этого предупреждения может быть использование в коде C/C++ макроса `__FILE__`, который содержит полный путь к каталогу `$srcdir`.

### makepkg не может загрузить зависимости через прокси

Когда makepkg проверяет зависимости, он вызывает pacman для установки недостающих пакетов. Для работы pacman требует предоставления прав администратора посредством sudo. Однако команда sudo не передает никакие переменные окружения в привилегированное окружение, в том числе и относящиеся к настройкам прокси переменные `ftp_proxy`, `http_proxy`, `https_proxy` и `no_proxy`.

Чтобы makepkg мог работать через прокси, воспользуйтесь одним из советов ниже.

#### Параметр XferCommand в файле /etc/pacman.conf

Параметр `XferCommand` в файле `/etc/pacman.conf` позволяет настроить использование прокси. В этом параметре нужно указать URL прокси-сервера. Добавьте или раскомментируйте следующую строку:

    /etc/pacman.conf

    ...
    XferCommand = /usr/bin/curl -x http://username:password@proxy.proxyhost.com:80 -L -C - -f -o %o %u
    ...

#### Параметр env_keep в файле /etc/sudoers

Опция `env_keep` в файле `/etc/sudoers` позволяет использовать упомянутые выше прокси-переменные в привилегированном окружении. Подробнее см. Sudo#Переменные окружения.

### makepkg не работает, но make завершается успешно

Если удаётся скомпилировать пакет командой make, но не получается — командой makepkg, причиной могут быть переменные компиляции в файле `/etc/makepkg.conf`. Попробуйте добавить следующие флаги к параметру `options` файла `PKGBUILD`:

`!buildflags`, для отключения значений по умолчанию `CPPFLAGS`, `CFLAGS`, `CXXFLAGS`, и `LDFLAGS`.

`!makeflags`, для отключения `MAKEFLAGS`, если вы меняли `/etc/makepkg.conf`, чтобы разрешить параллельную сборку.

`!debug`, для отключения `DEBUG_CFLAGS` и `DEBUG_CXXFLAGS`, если вы собрали пакет для отладки.

Если что-то из перечисленного выше решило проблему, выясните, какой именно флаг создавал проблему и сообщите о баге разработчикам.

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

- makepkg(8)
- makepkg.conf(5)
- Краткое описание работы makepkg
- Исходный код makepkg

Categories:

- Package development (Русский)
- About Arch (Русский)
- Commands (Русский)