makepkg (Русский)
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#Очистка кэша пакетов).
Проверка цифровых подписей
Файлы цифровых подписей имеют расширение .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-битной системе
Предварительно разблокируйте репозиторий 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
, если вы собрали пакет для отладки.
Если что-то из перечисленного выше решило проблему, выясните, какой именно флаг создавал проблему и сообщите о баге разработчикам.