makepkg (Русский)

From ArchWiki

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

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 — каталог для собранных пакетов;
  • SRCDEST — каталог для исходных файлов (в каталог src/ будут помещаться символические ссылки на новое местоположение);
  • SRCPKGDEST — каталог для пакетов исходных файлов, используемых для сборки пакетов (создаются командой makepkg -S).
Совет: Каталог PKGDEST можно очистить, например, командой paccache -c ~/build/packages/ (см. pacman#Очистка кэша пакетов).

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

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

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

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

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

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

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

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

$ makepkg

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

$ makepkg --syncdeps

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

Примечание:
  • Пакеты-зависимости должны быть доступны для установки из подключённых репозиториев; в статье 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, чтобы сэкономить время на скачивание и распаковку файлов с исходным кодом.

Переопределение флагов git

Значительно снизить время загрузки может частичное клонирование. Флаг --filter=tree:0 позволяет обновлять дерево исходных текстов только по требованию. Передать его в makepkg можно с помощью переменной GITFLAGS.

Примечание: В стабильной версии pacman 6.0.2 поддержка GITFLAGS ещё не появилась. Для её использования установите разрабатываемую версию (например, pacman-gitAUR).

Пример:

$ GITFLAGS="--filter=tree:0" makepkg

Чтобы применить для каждой сборки:

/etc/makepkg.conf
GITFLAGS="--filter=tree:0"
Примечание: По состоянию на 2023 год ещё не все git-серверы поддерживают этот флаг.

Также --single-branch в общем случае должен работать без проблем, но экономит не так много времени. Подробнее смотрите git-clone(1).

Важно: Помните, что любое изменение флагов git может что-нибудь сломать. Скрипты PKGBUILD могут использовать git непредсказуемым образом, полагаясь на текущие значения Makepkg по умолчанию. Иногда также предлагают использовать shallow clone (например, --depth=1), но это точно сломает pkgver() в VCS-пакетах и другие вещи. Это уже неоднократно обсуждалось, например, здесь.

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

Повысить производительность программ можно на этапе сборки пакета с помощью возможностей компилятора по оптимизации кода. Однако нужно иметь в виду, что двоичные файлы, скомпилированные под специфическую архитектуру процессора, не будут правильно работать на других машинах. Если говорить об архитектуре 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 ..."
CXXFLAGS="${CFLAGS} ..."

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

$ gcc -march=native -v -Q --help=target
Примечание: Если вы укажете значение, отличное от -march=native, то -Q --help=target не сработает [4]. Вам придётся пройти через фазу компиляции, чтобы узнать, какие опции на самом деле были включены. Подробнее см. 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 может сократить время компиляции.

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

$ BUILDDIR=/tmp/makepkg makepkg

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

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

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

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

Использование компоновщика mold

mold — это прозрачная замена компоновщикам ld/lld, работающая значительно быстрее.

Чтобы использовать mold, добавьте -fuse-ld=mold в LDFLAGS. Например:

/etc/makepkg.conf
LDFLAGS="... -fuse-ld=mold"

Чтобы использовать mold для Rust-программ, добавьте -C link-arg=-fuse-ld=mold в RUSTFLAGS. Например:

/etc/makepkg.conf
RUSTFLAGS="... -C link-arg=-fuse-ld=mold"

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

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

$ updpkgsums

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

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

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

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

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

$ PKGEXT='.pkg.tar' makepkg

Другой пример с использованием алгоритма сжатия LZ4:

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

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

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

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

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

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

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

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

COMPRESSGZ=(pigz -c -f -n)

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

COMPRESSBZ2=(pbzip2 -c -f)

lbzip2 — ещё одна параллельная реализация bzip2, также использует максимально возможное количество ядер по умолчанию. Флаг -n используется для выбора меньшего количества ядер.

COMPRESSBZ2=(lbzip2 -c -f)

plzipAUR — многопоточная реализация lzip, также использует максимально возможное количество ядер по умолчанию. Флаг -n/--threads используется для выбора меньшего количества ядер.

COMPRESSLZ=(plzip -c -f)

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

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-битной системе

Смотрите 32-bit package guidelines.

Magnet-ссылки

Можно добавить поддержку magnet-ссылок (протокол magnet://) в массиве source с помощью transmission-dlagentAUR.

Запуск makepkg в контрольной группе systemd

Если собираемый пакет требует слишком много ресурсов для сборки при использовании стандартных флагов make, которые в остальном работают нормально для большинства пакетов, можно попробовать запустить сборку в отдельной контрольной группе (control group). makepkg-cgAUR — обёртка для makepkg, которая позволяет реализовать это через systemd control groups (смотрите systemd.resource-control(5)).

Запуск с политикой планировщика idle

Процесс сборки пакетов может сильно нагружать процессор, особенно если включена #Параллельная компиляция. При этом работа остальной системы может сильно замедлиться даже с самым высоким значением nice(1) — вплоть до зависания пользовательского интерфейса.

Чтобы до такого не доходило, можно перед запуском makepkg установить политику SCHED_IDLE (крайне низкий приоритет, ниже чем даже nice +19). Такой процесс не будет мешать выполнению обычных задач и будет использовать только свободное процессорное время.

Изменить политику на SCHED_IDLE можно с помощью команды chrt(1), указав флаг -i, приоритет 0 (единственный допустимый приоритет для политики SCHED_IDLE) и PID текущей командной оболочки.

В большинстве командных оболочек команда будет выглядеть так:

$ chrt -iap 0 $$
Совет: Чтобы эта команда применялась при каждой сборке, можно добавить её в файл makepkg.conf (который технически является bash-скриптом).

В fish:

$ chrt -iap 0 %self

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

Выбор каталога установки при сборке в 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, каким-то образом оказался в одном или нескольких файлах пакета [5].

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

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

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

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

Когда makepkg проверяет зависимости, он вызывает 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 --proxy http://username:password@proxy.proxyhost.com:80 --location --continue-at - --fail --output %o %u
...

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

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

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

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

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

!makeflags — для отключения MAKEFLAGS.

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

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

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