- Creating packages
- Contents
- Overview
- Preparation
- Prerequisite software
- Download and test the installation
- Creating a PKGBUILD
- Defining PKGBUILD variables
- PKGBUILD functions
- prepare()
- pkgver()
- build()
- check()
- package()
- Testing the PKGBUILD and package
- Checking package sanity
- Submitting packages to the AUR
- Summary
- Warnings
- More detailed guidelines
- PKGBUILD generators
- makepkg (Русский)
- Contents
- Настройка
- Информация о создателе пакета
- Расположение файлов пакета
- Проверка цифровых подписей
- Использование
- Советы и рекомендации
- Снижение времени загрузки и извлечения исходников
- Оптимизация двоичных пакетов
- Сокращение времени компиляции
- Параллельная компиляция
- Сборка из файлов в памяти
- Использование кэша компиляции
- Вычисление новых контрольных сумм
- Применение других алгоритмов сжатия
- Использование нескольких ядер при сжатии
- Вывод списка пакетов по имени создателя
- Сборка 32-битных пакетов в 64-битной системе
- Решение проблем
- Выбор каталога установки при сборке в QMake
- WARNING: Package contains reference to $srcdir
- makepkg не может загрузить зависимости через прокси
- Параметр XferCommand в файле /etc/pacman.conf
- Параметр env_keep в файле /etc/sudoers
- makepkg не работает, но make завершается успешно
Creating packages
This article aims to assist users creating their own packages using the Arch Linux «ports-like» build system, also for submission in AUR. It covers creation of a PKGBUILD – a package build description file sourced by makepkg to create a binary package from source. If already in possession of a PKGBUILD , see makepkg. For instructions regarding existing rules and ways to improve package quality see Arch packaging standards.
Contents
Overview
Packages in Arch Linux are built using the makepkg utility and the information stored in a PKGBUILD file. When makepkg runs, it searches for a PKGBUILD in the current directory and follows the instructions in it to acquire the required files and/or compile them to be packed within a package file ( pkgname.pkg.tar.zst ). The resulting package contains binary files and installation instructions ready to be installed by pacman.
An Arch package is no more than a tar archive, or ‘tarball’, compressed using zstd(1) , which contains the following files generated by makepkg:
- The binary files to install.
- .PKGINFO : contains all the metadata needed by pacman to deal with packages, dependencies, etc.
- .BUILDINFO : contains information needed for reproducible builds. This file is present only if a package is built with pacman 5.1 or newer. See BUILDINFO(5) .
- .MTREE : contains hashes and timestamps of the files, which are included in the local database so that pacman can verify the integrity of the package.
- .INSTALL : an optional file used to execute commands after the install/upgrade/remove stage. (This file is present only if specified in the PKGBUILD .)
- .Changelog : an optional file kept by the package maintainer documenting the changes of the package. (It is not present in all packages.)
Preparation
Prerequisite software
First, ensure that the necessary tools are installed: the package group base-devel should be sufficient, it includes make and additional tools needed for compiling from source.
The key tool for building packages is makepkg (provided by pacman ), which does the following:
- Checks if package dependencies are installed.
- Downloads the source file(s) from the specified server(s).
- Unpacks the source file(s).
- Compiles the software and installs it under a fakeroot environment.
- Strips symbols from binaries and libraries.
- Generates the package meta file which is included with each package.
- Compresses the fakeroot environment into a package file.
- Stores the package file in the configured destination directory, which is the current working directory by default.
Download and test the installation
Download the source tarball of the software you want to package, extract it, and follow the author’s steps to install the program. Make a note of all commands and/or steps needed to compile and install it. You will be repeating those same commands in the PKGBUILD file.
Most software authors stick to the 3-step build cycle:
This is a good time to make sure the program is working correctly.
Creating a PKGBUILD
When makepkg is run, it looks for a PKGBUILD file in the current working directory. If it finds one, it downloads the software’s source code and compiles it according to the instructions specified in the PKGBUILD file. The instructions must be fully interpretable by the Bash shell. After successful completion, the resulting binaries and metadata of the package, i.e. package version and dependencies, are packed in a pkgname.pkg.tar.zst package file. The newly created package can be installed by simply using makepkg —install which will call pacman in the background, or by directly using pacman -U pkgname.pkg.tar.zst .
To start building a new package, first create a new directory for the package and change current directory into this one. Then, a PKGBUILD file needs to be created: a prototype PKGBUILD found in /usr/share/pacman/ can be used or you can start from a PKGBUILD from another package. The latter may be a good choice if a similar package already exists.
Defining PKGBUILD variables
Example PKGBUILDs are located in /usr/share/pacman/ . An explanation of possible PKGBUILD variables can be found in the PKGBUILD article.
makepkg defines two variables that you should use as part of the build and install process:
srcdir This points to the directory where makepkg extracts or symlinks all files in the source array. pkgdir This points to the directory where makepkg bundles the installed package, which becomes the root directory of your built package.
They contain absolute paths, which means you do not have to worry about your working directory if you use these variables properly.
PKGBUILD functions
When building a package, makepkg will invoke the following five functions if they have been defined in the PKGBUILD. Function package() is required in every PKGBUILD and will always be invoked. If any of the other functions is not defined, makepkg will simply skip the invocation of that function.
During the build, the functions are invoked in the order in which they are listed here.
prepare()
With this function, commands that are used to prepare sources for building are run, such as patching. This function runs right after package extraction, before pkgver() and the build function. If extraction is skipped ( makepkg —noextract ), then prepare() is not run.
pkgver()
pkgver() runs after the sources are fetched, extracted and prepare() executed. So you can update the pkgver variable during a makepkg stage.
This is particularly useful if you are making git/svn/hg/etc. packages, where the build process may remain the same, but the source could be updated every day, even every hour. The old way of doing this was to put the date into the pkgver field which, if the software was not updated, makepkg would still rebuild it thinking the version had changed. Some useful commands for this are git describe , hg identify -ni , etc. Please test these before submitting a PKGBUILD, as a failure in the pkgver() function can stop a build in its tracks.
build()
Now you need to implement the build() function in the PKGBUILD file. This function uses common shell commands in Bash syntax to automatically compile software and create a directory called pkg to install the software to. This allows makepkg to package files without having to sift through your file system.
The first step in the build() function is to change into the directory created by uncompressing the source tarball. makepkg will change the current directory to $srcdir before executing the build() function. Therefore, in most cases, like suggested in /usr/share/pacman/PKGBUILD.proto , the first command will look like this:
Now, you need to list the same commands you used when you manually compiled the software. The build() function in essence automates everything you did by hand and compiles the software in the fakeroot build environment. If the software you are packaging uses a configure script, it is good practice to use —prefix=/usr when building packages for pacman. A lot of software installs files relative to the /usr/local directory, which should only be done if you are manually building from source. All Arch Linux packages should use the /usr directory. As seen in the /usr/share/pacman/PKGBUILD.proto file, the next two lines often look like this:
check()
Place for calls to make check and similar testing routines. It is highly recommended to have check() as it helps to make sure software has been built correctly and works fine with its dependencies.
Users who do not need it (and occasionally maintainers who can not fix a package for this to pass) can disable it using BUILDENV+=(‘!check’) in PKGBUILD/makepkg.conf or call makepkg with —nocheck flag.
package()
The final step is to put the compiled files in a directory where makepkg can retrieve them to create a package. This by default is the pkg directory—a simple fakeroot environment. The pkg directory replicates the hierarchy of the root file system of the software’s installation paths. If you have to manually place files under the root of your filesystem, you should install them in the pkg directory under the same directory structure. For example, if you want to install a file to /usr/bin , it should instead be placed under $pkgdir/usr/bin . Very few install procedures require the user to copy dozens of files manually. Instead, for most software, calling make install will do so. The final line should look like the following in order to correctly install the software in the pkg directory:
makepkg —repackage runs only the package() function, so it creates a package without building. This may save time e.g. if you have changed just the depends variable of the package.
Testing the PKGBUILD and package
As you are writing the build() function, you will want to test your changes frequently to ensure there are no bugs. You can do this using the makepkg command in the directory containing the PKGBUILD file. With a properly formatted PKGBUILD , makepkg will create a package; with a broken or unfinished PKGBUILD , it will raise an error.
If makepkg finishes successfully, it will place a file named pkgname-pkgver.pkg.tar.zst in your working directory. This package can be installed with the pacman -U command. However, just because a package file was built does not imply that it is fully functional. It might conceivably contain only the directory and no files whatsoever if, for example, a prefix was specified improperly. You can use pacman’s query functions to display a list of files contained in the package and the dependencies it requires with pacman -Qlp [package file] and pacman -Qip [package file] respectively.
If the package looks sane, then you are done! However, if you plan on releasing the PKGBUILD file, it is imperative that you check and double-check the contents of the depends array.
Also ensure that the package binaries actually run flawlessly! It is annoying to release a package that contains all necessary files, but crashes because of some obscure configuration option that does not quite work well with the rest of the system. If you are only going to compile packages for your own system, though, you do not need to worry too much about this quality assurance step, as you are the only person suffering from mistakes, after all.
Checking package sanity
After testing package functionality check it for errors using namcap:
- Check PKGBUILD contents for common errors and package file hierarchy for unnecessary/misplaced files
- Scan all ELF files in package using ldd , automatically reporting which packages with required shared libraries are missing from depends and which can be omitted as transitive dependencies
- Heuristically search for missing and redundant dependencies
Get into the habit of checking your packages with namcap to avoid having to fix the simplest mistakes after package submission.
Submitting packages to the AUR
Please read AUR submission guidelines for a detailed description of the submission process.
Summary
- Download the source tarball of the software to package.
- Try compiling the package and installing it into an arbitrary directory.
- Copy over the prototype /usr/share/pacman/PKGBUILD.proto and rename it to PKGBUILD in a temporary working directory.
- Edit the PKGBUILD according to the needs of your package.
- Run makepkg and check whether the package builds correctly.
- If not, repeat the previous two steps.
Warnings
- Before you can automate the package building process, you should have done it manually at least once unless you know exactly what you are doing in advance, in which case you would not be reading this in the first place. Unfortunately, although a good bunch of program authors stick to the 3-step build cycle of » ./configure ; make ; make install «, this is not always the case, and things can get real ugly if you have to apply patches to make everything work at all. Rule of thumb: If you cannot get the program to compile from the source tarball, and make it install itself to a defined, temporary subdirectory, you do not even need to try packaging it. There is not any magic pixie dust in makepkg that makes source problems go away.
- In a few cases, the packages are not even available as source and you have to use something like sh installer.run to get it to work. You will have to do quite a bit of research (read READMEs, INSTALL instructions, man pages, perhaps ebuilds from Gentoo or other package installers, possibly even the MAKEFILEs or source code) to get it working. In some really bad cases, you have to edit the source files to get it to work at all. However, makepkg needs to be completely autonomous, with no user input. Therefore if you need to edit the makefiles, you may have to bundle a custom patch with the PKGBUILD and install it from inside the prepare() function, or you might have to issue some sed commands from inside the prepare() function.
More detailed guidelines
PKGBUILD generators
PKGBUILDs for some packages can be generated automatically.
Источник
makepkg (Русский)
makepkg — скрипт для автоматизации сборки пакетов. Требования для работы — Unix-платформа с системой сборки и файл PKGBUILD.
makepkg входит в состав пакета pacman .
Contents
Настройка
Параметры настройки makepkg подробно описаны в руководстве makepkg.conf(5) .
Общесистемные настройки хранятся в файле /etc/makepkg.conf , пользовательские — в $XDG_CONFIG_HOME/pacman/makepkg.conf или
/.makepkg.conf . Рекомендуется проверять настройки перед сборкой пакетов.
Информация о создателе пакета
Каждый пакет содержит метаданные, в том числе информацию о создателе пакета (packager). По умолчанию скомпилированный пакет создаётся с пометкой Unknown Packager . Однако если на одной системе компиляцией занимаются несколько пользователей или вы планируете распространять пакет среди других пользователей, то имеет смысл указать настоящие контактные данные, задав переменную PACKAGER в файле makepkg.conf .
Создателя установленного пакета можно узнать командой:
Кроме того, если указать цифровую подпись создателя в параметре GPGKEY , то она тоже будет автоматически добавляться к пакету.
Расположение файлов пакета
makepkg создаёт пакет в рабочем каталоге в формате tar-архива, а исходный код загружает в подкаталог src/ . Целевые каталоги можно переназначить, например, чтобы все собранные пакеты хранились в
/build/packages/ , а все исходные данные — в
Можно задать следующие значения в makepkg.conf :
- PKGDEST — каталог для собранных пакетов (расширение .pkg.tar.xz );
- SRCDEST — каталог для исходных файлов (расширение .tar.gz ; в каталог src/ будут помещаться символические ссылки на новое местоположение);
- SRCPKGDEST — каталог для пакетов исходных данных (расширение .src.tar.gz , создаются командой makepkg -S ).
Проверка цифровых подписей
Файлы цифровых подписей имеют расширение .sig или .asc и указываются в параметре source файла PKGBUILD. Если makepkg встречает такой файл, то автоматически пытается проверить подпись пакета. Если пользовательская связка ключей не содержит нужный открытый ключ, то makepkg выведет сообщение о невозможности осуществить проверку PGP-ключа и прервёт установку.
Если нужный открытый ключ отсутствует, то файл PKGBUILD, скорее всего, содержит пункт validpgpkeys с идентификаторами ключей. Ключи можно импортировать вручную или же найти их на сервере ключей и импортировать оттуда.
Использование
Для корректной работы makepkg нужно установить группу пакетов base-devel . Пакеты из этой группы можно не указывать в качестве зависимостей для сборки (makedepends) в файле PKGBUILD.
Чтобы собрать пакет, первым делом необходимо создать файл PKGBUILD, который представляет собой скрипт сборки. Написание скрипта описано в статье Создание пакетов. Скрипты для существующих пакетов можно найти в дереве каталогов Системы сборки Arch, а также в AUR. После того, как PKGBUILD получен, переместитесь в каталог с ним и выполните команду сборки пакета:
Если в системе не установлены необходимые зависимости, makepkg предупредит вас об этом и отменит сборку. Если задать флаг -s / —syncdeps , то makepkg самостоятельно установит недостающие зависимости и соберёт пакет.
С флагом -r / —rmdeps makepkg после сборки удалит те зависимости, которые будут больше не нужны. Если вы постоянно занимаетесь сборкой пакетов и не хотите загрязнять систему пакетами-сиротами, то стоит также ознакомиться со статьёй pacman/Tips and tricks#Удаление неиспользуемых пакетов.
Когда все зависимости установлены и сборка пакета завершилась успешно, в рабочем каталоге появится файл пакета ( имя-пакета—версия-пакета.pkg.tar.zst ). Чтобы установить его в систему, используйте флаг -i / —install (работает аналогично команде pacman -U имя-пакета—версия-пакета.pkg.tar.zst ):
С флагом -c / —clean makepkg удалит оставшиеся после сборки промежуточные файлы и каталоги (например, распакованные в $srcdir файлы). Это полезно при многократных сборках одного и того же пакета или его обновления в одном рабочем каталоге. Это предотвратит добавление устаревших файлов в новые сборки:
Советы и рекомендации
Снижение времени загрузки и извлечения исходников
При многократной пересборке одного и того же пакета, особенно в случае VCS, используйте SRCDEST , чтобы сэкономить время на скачивание и распаковку файлов с исходным кодом.
Оптимизация двоичных пакетов
Повысить производительность программ можно на этапе сборки пакета за счет возможностей компилятора по оптимизации кода. Однако нужно иметь в виду, что двоичные файлы, скомпилированные под специфическую архитектуру процессора, не будут правильно работать на других машинах. Если говорить об архитектуре x86_64, то редко когда достигнутый эффект повышения производительности стоит затраченного на пересборку официальных пакетов времени.
С другой стороны, снизить производительность, задав «нестандартные» флаги компилятора — проще простого. Чаще всего тонкая настройка компилятора приносит пользу лишь в определённой ситуации и не стоит применять её ко всем пакетам без разбора. Если вы не можете доказать повышение производительности путем тестов, то скорее всего, его просто нет! Статьи из Gentoo-wiki Оптимизации GCC и Safe CFLAGS содержат больше информации по оптимизации компилятора.
Опции, переданные компилятору C/C++ (например, gcc или clang ) зависят от переменных окружения CFLAGS , CXXFLAGS и CPPFLAGS . В системе сборки Arch makepkg извлекает значения переменных окружения из файла настроек makepkg.conf и использует их в качестве опций. Значения по умолчанию выбраны таким образом, чтобы создаваемые двоичные программы работали на широком диапазоне машин.
Компилятор GCC может автоматически обнаруживать и включать безопасные оптимизации, доступные для конкретной архитектуры. Чтобы использовать эту особенность, сначала удалите любые -march и -mtune флаги, а затем добавьте опцию -march=native . Например:
Чтобы узнать, какие флаги эта команда разблокирует на вашей машине, выполните:
Начиная с pacman версии 5.2.2 файл makepkg.conf также содержит переменную окружения RUSTFLAGS , в которой можно указать флаги, передаваемые компилятору языка Rust. Если указать в переменной RUSTFLAGS значение -C target-cpu=native , компилятор включит возможные для архитектуры вашего процессора алгоритмы оптимизации.
Чтобы узнать, какие возможности процессора можно включить этой настройкой, выполните:
Если в команде выше указать —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 файла настроек /etc/makepkg.conf . Если, к примеру, установить это значение BUILDDIR=/tmp/makepkg , то будет использоваться обычная временная файловая система Arch /tmp .
Использование кэша компиляции
Применение ccache сокращает время сборки за счет многократного использования кэша компиляции.
Вычисление новых контрольных сумм
Установите пакет pacman-contrib и выполните следующую команду в каталоге с файлом PKGBUILD , чтобы сгенерировать новые контрольные суммы:
updpkgsums использует makepkg —geninteg для вычисления контрольных сумм. Подробнее см. обсуждение на форуме.
Контрольные суммы также можно получить посредством команды sha256sum , после чего полученные значения следует вручную добавить к массиву sha256sums в файле PKGBUILD .
Применение других алгоритмов сжатия
Создание и установку пакета можно ускорить, заплатив за это увеличением размера. Для этого нужно изменить переменную PKGEXT . Например, следующая команда создаст пакет в виде несжатого архива, вследствие чего не нужно будет выполнять его декомпрессию при установке:
Другой пример, с использованием алгоритма сжатия lzop (необходим пакет lzop ):
Чтобы сделать одну из этих настроек постоянной, нужно установить соответствующее значение PKGEXT в /etc/makepkg.conf .
Использование нескольких ядер при сжатии
xz поддерживает симметричную многопроцессорность (SMP) посредством флага —threads для ускорения сжатия. Например, чтобы разрешить makepkg использовать все имеющиеся в наличии ядра CPU, отредактируйте массив COMPRESSXZ в /etc/makepkg.conf :
pigz — параллельная реализация gzip , по умолчанию использует все доступные ядра CPU. Если необходимо задействовать меньшее количество ядер, то используется флаг -p/—processes :
pbzip2 — параллельная реализация bzip2 , также использует максимально возможное количество ядер по умолчанию. Флаг -p# используется для выбора меньшего количества ядер (примечание: между -p и числом ядер не должно быть пробелов):
zstd поддерживает симметричную многопроцессорность (SMP) посредством флага —threads для ускорения сжатия. Например, чтобы разрешить makepkg использовать все имеющиеся в наличии ядра CPU, отредактируйте массив COMPRESSZST в /etc/makepkg.conf :
Вывод списка пакетов по имени создателя
expac — программа для работы с базой данных pacman. Если необходимо вывести список всех установленных пакетов, создателем которых является создатель-пакета, выполните:
Команда для вывода списка пакетов, создатель которых указан в переменной PACKAGER файла /etc/makepkg.conf (покажет только пакеты из репозиториев, определенных в /etc/pacman.conf ):
Сборка 32-битных пакетов в 64-битной системе
Предварительно разблокируйте репозиторий multilib и установите группу пакетов multilib-devel .
Затем создайте 32-битный файл настроек
Решение проблем
Выбор каталога установки при сборке в QMake
QMake генерирует файл makefile , в котором для указания каталога установки используется переменная окружения INSTALL_ROOT . Например, вот как будет выглядеть функция package:
Обратите внимание, что Qmake тоже должен быть соответствующим образом настроен. К примеру, добавьте следующие строки в ваш .pro-файл.
WARNING: Package contains reference to $srcdir
Подобное предупреждение означает, что строковый литерал, указанный в переменных $srcdir или $pkgdir , каким-то образом оказался в одном или нескольких файлах вашего пакета [6].
Чтобы определить, в каких именно файлах, выполните следующую команду в рабочем каталоге сборки:
Одной из причин появления этого предупреждения может быть использование в коде 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 прокси-сервера. Добавьте или раскомментируйте следующую строку:
Параметр 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 , если вы собрали пакет для отладки.
Если что-то из перечисленного выше решило проблему, выясните, какой именно флаг создавал проблему и сообщите о баге разработчикам.
Источник