makepkg
makepkg is a script to automate the building of packages. The requirements for using the script are a build-capable Unix platform and a PKGBUILD.
makepkg is provided by the pacman package.
Configuration
See makepkg.conf(5) for details on configuration options for makepkg.
The system configuration is available in /etc/makepkg.conf
, but user-specific changes can be made in $XDG_CONFIG_HOME/pacman/makepkg.conf
or ~/.makepkg.conf
. It is recommended to review the configuration prior to building packages.
Packager information
Each package is tagged with metadata identifying amongst others also the packager. By default, user-compiled packages are marked with Unknown Packager
. If multiple users will be compiling packages on a system, or if one is otherwise distributing packages to other users, it is convenient to provide real contact. This can be done by setting the PACKAGER
variable in makepkg.conf
.
To check this on an installed package:
$ pacman -Qi package
... Packager : John Doe <[email protected]> ...
To automatically produce signed packages, also set the GPGKEY
variable in makepkg.conf
.
Package output
By default, makepkg creates the package tarballs in the working directory and downloads source data directly to the src/
directory. Custom paths can be configured, for example to keep all built packages in ~/build/packages/
and all sources in ~/build/sources/
.
Configure the following makepkg.conf
variables if needed:
-
PKGDEST
— directory for storing resulting packages -
SRCDEST
— directory for storing source data (symbolic links will be placed tosrc/
if it points elsewhere) -
SRCPKGDEST
— directory for storing resulting source packages (built withmakepkg -S
)
PKGDEST
directory can be cleaned up with e.g. paccache -c ~/build/packages/
as described in pacman#Cleaning the package cache.Signature checking
If a signature file in the form of .sig or .asc is part of the PKGBUILD source array, makepkg automatically attempts to verify it. In case the user's keyring does not contain the needed public key for signature verification, makepkg will abort the installation with a message that the PGP key could not be verified.
If a needed public key for a package is missing, the PKGBUILD will most likely contain a validpgpkeys entry with the required key IDs. Import it manually, or find it on a keyserver and import it from there.
Usage
Before continuing, install the base-devel group. Packages belonging to this group are not required to be listed as build-time dependencies (makedepends) in PKGBUILD files.
- Make sure sudo is configured properly for commands passed to pacman.
- Running makepkg itself as root is disallowed.[2] Besides how a
PKGBUILD
may contain arbitrary commands, building as root is generally considered unsafe.[3] Users who have no access to a regular user account should run makepkg as the nobody user.
To build a package, one must first create a PKGBUILD, or build script, as described in Creating packages. Existing scripts are available from the Arch Build System (ABS) tree or the AUR. Once in possession of a PKGBUILD
, change to the directory where it is saved and run the following command to build the package:
$ makepkg
If required dependencies are missing, makepkg will issue a warning before failing. To build the package and install needed dependencies, add the flag -s
/--syncdeps
:
$ makepkg --syncdeps
Adding the -r
/--rmdeps
flag causes makepkg to remove the make dependencies later, which are no longer needed. If constantly building packages, consider using Pacman/Tips and tricks#Removing unused packages (orphans) once in a while instead.
- These dependencies must be available in the configured repositories; see pacman#Repositories and mirrors for details. Alternatively, one can manually install dependencies prior to building (
pacman -S --asdeps dep1 dep2
). - Only global values are used when installing dependencies, i.e any override done in a split package's packaging function will not be used.
Once all dependencies are satisfied and the package builds successfully, a package file (pkgname-pkgver.pkg.tar.zst
) will be created in the working directory. To install, use -i
/--install
(same as pacman -U pkgname-pkgver.pkg.tar.zst
):
$ makepkg --install
To clean up leftover files and directories, such as files extracted to the $srcdir
, add the option -c
/--clean
. This is useful for multiple builds of the same package or updating the package version, while using the same build directory. It prevents obsolete and remnant files from carrying over to the new builds:
$ makepkg --clean
For more, see makepkg(8).
Tips and tricks
Reduce source download and extraction times
Make use of SRCDEST
, especially when building VCS packages, to save time acquiring and unpacking sources in subsequent rebuilds.
Building optimized binaries
A performance improvement of the packaged software can be achieved by enabling compiler optimizations for the host machine. The downside is that binaries compiled for a specific processor architecture will not run correctly on other machines. On x86_64 machines, there are rarely significant enough real world performance gains that would warrant investing the time to rebuild official packages.
However, it is very easy to reduce performance by using "nonstandard" compiler flags. Many compiler optimizations are only useful in certain situations and should not be indiscriminately applied to every package. Unless benchmark data are available to prove that something is faster, there is a very good chance it is not! The Gentoo GCC optimization and Safe CFLAGS wiki articles provide more in-depth information about compiler optimization.
The options passed to a C/C++ compiler (e.g. gcc or clang) are controlled by the CFLAGS
, CXXFLAGS
, and CPPFLAGS
environment variables. For use in the Arch build system, makepkg exposes these environment variables as configuration options in makepkg.conf
. The default values are configured to produce generic binaries that can be installed on a wide range of machines.
- Keep in mind that not all build systems use the variables configured in
makepkg.conf
. For example, cmake disregards the preprocessor options environment variable,CPPFLAGS
. Consequently, many PKGBUILDs contain workarounds with options specific to the build system used by the packaged software. - The configuration provided with the source code in the
Makefile
or a specific argument in the compilation command line takes precedence and can potentially override the one inmakepkg.conf
.
GCC can automatically detect and enable safe architecture-specific optimizations. To use this feature, first remove any -march
and -mtune
flags, then add -march=native
. For example:
/etc/makepkg.conf
CFLAGS="-march=native -O2 -pipe -fno-plt" CXXFLAGS="${CFLAGS}"
To see what flags this enables, run:
$ gcc -march=native -v -Q --help=target
-march=native
, then -Q --help=target
will not work as expected.[4] To find out which options are really enabled, go through a compilation. See Gentoo:Safe CFLAGS#Manual for instructions.Starting in pacman
version 5.2.2, makepkg.conf
also includes overrides for the RUSTFLAGS
environment variable, for flags given to the Rust compiler. The Rust compiler can also detect and enable architecture-specific optimizations by adding -C target-cpu=native
to the given RUSTFLAGS
value:
/etc/makepkg.conf
RUSTFLAGS="-C opt-level=2 -C target-cpu=native"
To see which CPU features this will enable, run:
$ rustc -C target-cpu=native --print cfg
Running --print cfg
without -C target-cpu=native
will print the default configuration. The opt-level
parameter can be changed to 3
, s
, or z
as desired. See The Rust compiler's documentation for details.
Improving compile times
Parallel compilation
The make build system uses the MAKEFLAGS
environment variable to specify additional options for make. The variable can also be set in the makepkg.conf
file.
Users with multi-core/multi-processor systems can specify the number of jobs to run simultaneously. This can be accomplished with the use of nproc to determine the number of available processors, e.g. MAKEFLAGS="-j$(nproc)"
. Some PKGBUILDs specifically override this with -j1
, because of race conditions in certain versions or simply because it is not supported in the first place. Packages that fail to build because of this should be reported on the bug tracker (or in the case of AUR packages, to the package maintainer) after making sure that the error is indeed being caused by MAKEFLAGS
.
See make(1) for a complete list of available options.
Building from files in memory
As compiling requires many I/O operations and handling of small files, moving the working directory to a tmpfs may bring improvements in build times.
The BUILDDIR
variable can be temporarily exported to makepkg to set the build directory to an existing tmpfs. For example:
$ BUILDDIR=/tmp/makepkg makepkg
Persistent configuration can be done in makepkg.conf
by uncommenting the BUILDDIR
option, which is found at the end of the BUILD ENVIRONMENT
section in the default /etc/makepkg.conf
file. Setting its value to e.g. BUILDDIR=/tmp/makepkg
will make use of the Arch's default /tmp
temporary file system.
- Avoid compiling larger packages in tmpfs to prevent running out of memory.
- The tmpfs directory must be mounted without the
noexec
option, otherwise it will prevent built binaries from being executed. - Keep in mind that packages compiled in tmpfs will not persist across reboot. Consider setting the PKGDEST option appropriately to move the built package automatically to a persistent directory.
Using a compilation cache
The use of ccache can improve build times by caching the results of compilations for successive use.
Generate new checksums
Install pacman-contrib and run the following command in the same directory as the PKGBUILD file to generate new checksums:
$ updpkgsums
updpkgsums
uses makepkg --geninteg
to generate the checksums. See this forum discussion for more details.
The checksums can also be obtained with e.g sha256sum
and added to the sha256sums
array by hand.
Use other compression algorithms
To speed up both packaging and installation, with the tradeoff of having larger package archives, change PKGEXT
.
For example, the following skips compression of the package file, which will in turn have no need to be decompressed on install:
$ PKGEXT='.pkg.tar' makepkg
As another example, the following uses the lzop algorithm, with the lzop package required:
$ PKGEXT='.pkg.tar.lzo' makepkg
To make one of these settings permanent, set PKGEXT
in /etc/makepkg.conf
.
Utilizing multiple cores on compression
xz supports symmetric multiprocessing (SMP) via the --threads
flag to speed up compression. For example, to let makepkg use as many CPU cores as possible to compress packages, edit COMPRESSXZ
array in /etc/makepkg.conf
:
COMPRESSXZ=(xz -c -z --threads=0 -)
pigz is a drop-in, parallel implementation for gzip which by default uses all available CPU cores (the -p/--processes
flag can be used to employ less cores):
COMPRESSGZ=(pigz -c -f -n)
pbzip2 is a drop-in, parallel implementation for bzip2 which also uses all available CPU cores by default. The -p#
flag can be used to employ less cores (note: no space between the -p
and number of cores).
COMPRESSBZ2=(pbzip2 -c -f)
zstd supports symmetric multiprocessing (SMP) via the --threads
flag to speed up compression. For example, to let makepkg use as many CPU cores as possible to compress packages, edit COMPRESSZST
array in /etc/makepkg.conf
:
COMPRESSZST=(zstd -c -z -q --threads=0 -)
Show packages with specific packager
expac is a pacman database extraction utility. This command shows all packages installed on the system with the packager named packagername:
$ expac "%n %p" | grep "packagername" | column -t
This shows all packages installed on the system with the packager set in the /etc/makepkg
variable PACKAGER
. This shows only packages that are in a repository defined in /etc/pacman.conf
.
$ . /etc/makepkg.conf; grep -xvFf <(pacman -Qqm) <(expac "%n\t%p" | grep "$PACKAGER$" | cut -f1)
Build 32-bit packages on a 64-bit system
First, enable the multilib repository and install multilib-devel.
Then create a 32-bit configuration file
~/.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"
and invoke makepkg as such
$ linux32 makepkg --config ~/.makepkg.i686.conf
Unattended package signing
A person may not be available to provide the passphrase for the gpg private key used to sign with in automated build environments such as Jenkins. It is ill-advised to store a private gpg key on a system without a passphrase.
A resulting zst package made with makepkg can still be be signed after creation:
$ gpg --detach-sign --pinentry-mode loopback --passphrase --passphrase-fd 0 --output NewlyBuilt.pkg.tar.zst.sig --sign NewlyBuilt.pkg.tar.zst
where the GPG passphrase is securely provided and obscured by your automation suite of choice.
The resulting zst
and sig
file can be referenced by pacman clients expecting a valid signature and repositories created with repo-add --sign
when hosting your own repo.
Troubleshooting
Specifying install directory for QMAKE based packages
The makefile generated by qmake uses the environment variable INSTALL_ROOT
to specify where the program should be installed. Thus this package function should work:
PKGBUILD
... package() { cd "$srcdir/${pkgname%-git}" make INSTALL_ROOT="$pkgdir" install } ...
Note, that qmake also has to be configured appropriately. For example put this in the corresponding .pro file:
YourProject.pro
... target.path = /usr/local/bin INSTALLS += target ...
WARNING: Package contains reference to $srcdir
Somehow, the literal strings contained in the variables $srcdir
or $pkgdir
ended up in one of the installed files in the package.
To identify which files, run the following from the makepkg build directory:
$ grep -R "$PWD/src" pkg/
One possible cause would be from the usage of __FILE__
macro in C/C++ code with full path passed to compiler.
Makepkg fails to download dependencies when behind proxy
When makepkg calls dependencies, it calls pacman to install the packages, which requires administrative privileges via sudo. However, sudo does not pass any environment variables to the privileged environment, and includes the proxy-related variables ftp_proxy
, http_proxy
, https_proxy
, and no_proxy
.
In order to have makepkg working behind a proxy, invoke one of the following methods.
Enable proxy by setting its URL in XferCommand
The XferCommand can be set to use the desired proxy URL in /etc/pacman.conf
. Add or uncomment the following line in pacman.conf
[5]:
/etc/pacman.conf
... XferCommand = /usr/bin/curl -x http://username:[email protected]:80 -L -C - -f -o %o %u ...
Enable proxy via sudoer's env_keep
Alternatively, one may want to use sudoer's env_keep
option, which enables preserving given variables the privileged environment. See Sudo#Environment variables for more information.
Makepkg fails, but make succeeds
If something successfully compiles using make, but fails through makepkg, it is almost certainly because /etc/makepkg.conf
sets an incompatible compilation variable. Try adding these flags to the PKGBUILD options
array:
!buildflags
, to prevent its default CPPFLAGS
, CFLAGS
, CXXFLAGS
, and LDFLAGS
.
!makeflags
, to prevent its default MAKEFLAGS
.
!debug
, to prevent its default DEBUG_CFLAGS
, and DEBUG_CXXFLAGS
, in case the PKGBUILD is a debug build.
If any of these fix the problem, this could warrant an upstream bug report assuming the offending flag has been identified.