makepkg

Related articles
Arch build system
Arch User Repository
Creating packages
GnuPG
Official repositories
OpenPGP
pacman
.SRCINFO
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
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
. Also, system wide changes can be made with a drop-in file
/etc/makepkg.conf.d/makepkg.conf
. It is recommended to review the configuration prior to building packages.
See
makepkg.conf(5)
for more information.
Note
devtools
helper scripts for building packages in a
clean chroot
use the
/usr/share/devtools/makepkg.conf.d/
arch
.conf
configuration file instead.
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 <john@doe.com>
...
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 to
src/
if it points elsewhere)
SRCPKGDEST
— directory for storing resulting source packages (built with
makepkg -S
)
Tip
The
PKGDEST
directory can be cleaned up with e.g.
paccache -c ~/build/packages/
as described in
pacman#Cleaning the package cache
.
You can also use
relative paths inside each package directory
.
Signature checking
Note
The signature checking implemented in
makepkg
does not use pacman's keyring, instead relying on the user's keyring.
[1]
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. To temporarily disable signature checking, run
makepkg
with the
--skippgpcheck
option.
Usage
Before continuing,
install
the
base-devel
meta package
. Dependencies of this package are
not
required to be listed as build-time dependencies (
makedepends
) in
PKGBUILD
files.
Note
Make sure
sudo
is configured properly for commands passed to
pacman
. Alternatively a different authorization command can be specified with
PACMAN_AUTH
in the
makepkg.conf(5)
configuration file.
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
, e.g. using the command
runuser -u nobody makepkg
.
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.
Note
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)
.
Optimization
The default options match the options
devtools
uses to build packages for the
official repositories
.
[4]
As such, end users may realize more or less significant gains by tweaking the following options to match their local environment.
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.
C and C++
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.
Note
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 in
makepkg.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 ..."
CXXFLAGS="${CFLAGS} ..."
To see what flags this enables, run:
$ gcc -march=native -v -Q --help=target
Note
Specifying different values instead of
-march=native
, then
-Q --help=target
will not
work as expected.
[5]
To find out which options are really enabled, go through a compilation. See
Gentoo:Safe CFLAGS#Manual
for instructions.
Further optimization of binaries can be achieved by enabling optimizations that are considered expensive in terms of memory usage and compile time. This can be achieved by changing the optimization level flag from
-O2
to
-O3
. Using this flag will in most cases improve performance of the binary, although this is not guaranteed and in some cases
can prove counter-productive
. See
Gentoo:GCC optimization#-O
and
GCC optimization options page
for details.
Rust
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.d/rust.conf
RUSTFLAGS="-C force-frame-pointers=yes
-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.
Additional optimization-related options that may be added to
RUSTFLAGS
:
-C opt-level=3
: The value can be changed to
3
,
s
, or
z
as desired.
opt-level=3
is default of release build.
-C codegen-units=
n
: Choosing
n
less than
16
also optimizes binary, but it increases build time.
-C link-arg=-z -C link-arg=pack-relative-relocs
reduces size of the binary.
See the
Rust compiler's documentation
for details.
Improving build 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(1)
to determine the number of available processors, e.g.
MAKEFLAGS="--jobs=$(nproc)"
.
Some
PKGBUILD
s 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.
Note
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.
Using mold linker
mold
is a drop-in replacement for
ld
/
lld
linkers, which claims to be significantly faster.
To use
mold
, append
-fuse-ld=mold
to
LDFLAGS
. For example:
/etc/makepkg.conf
LDFLAGS="... -fuse-ld=mold"
To pass extra options to
mold
, additionally add those to
LDFLAGS
. For example:
/etc/makepkg.conf
LDFLAGS="... -fuse-ld=mold -Wl,--separate-debug-file"
To use
mold
for Rust packages, append
-C link-arg=-fuse-ld=mold
to
RUSTFLAGS
. For example:
/etc/makepkg.conf.d/rust.conf
RUSTFLAGS="... -C link-arg=-fuse-ld=mold"
Disable debug packages and LTO
Commit 90bf367e
included in
pacman 6.0.2-9 from February 2024
enabled the
debug
and
lto
options by default.
Building debug packages enables the official repositories to provide more tools to troubleshoot issues for users (
archlinux/packaging/packages/pacman#23#note_173528
), but it is not required when building packages on your own and slows down the build process. See
archlinux/packaging/packages/pacman#23#note_173782
.
Link-time optimization
produces more optimized binaries but greatly lengthens the build process (
archlinux/packaging/packages/pacman#23#note_173678
), which might not be a desired tradeoff.
To disable those options, add a
!
character directly in front of them in the
OPTIONS=()
array,
e.g.
OPTIONS=(...!debug !lto...)
.
Compression
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 LZ4 algorithm, which is focused on speed:
$ PKGEXT='.pkg.tar.lz4' makepkg
To make one of these settings permanent, set
PKGEXT
in
/etc/makepkg.conf
.
Utilizing multiple cores on compression
zstd
supports
symmetric multiprocessing (SMP)
via the
-T
/
--threads
flag to speed up compression. The
-T0
flag is included by default in the
COMPRESSZST
array in
/etc/makepkg.conf
, which lets
zstd
use as many threads as there are physical CPU cores to compress packages. The number of used threads can be further increased by instructing
zstd
to base it on the logical CPU count using the
--auto-threads=logical
flag:
COMPRESSZST=(zstd -c -T0
--auto-threads=logical
-)
lz4
and
xz
are multithreaded by default, so nothing needs to be changed in
/etc/makepkg.conf
.
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)
lbzip2
is another drop-in, parallel implementation for
bzip2
which also uses all available CPU cores by default. The
-n
flag can be used to employ less cores.
COMPRESSBZ2=(
lbzip2
-c -f)
plzip
AUR
is a multithreaded implementation for
lzip
which also uses all available CPU cores by default. The
-n
/
--threads
flag can be used to employ less cores.
COMPRESSLZ=(
plzip
-c -f)
Changing compression level
Several compression algorithms (including zstd and xz) support setting a compression level which defines a tradeoff between speed, memory and compression efficiency.
Tips and tricks
Reduce source download and extraction times
Defining the sources location
Make use of
SRCDEST
, especially when building
VCS packages
, to save time acquiring and unpacking sources in subsequent rebuilds.
Custom DLAGENTS
You can use a downloader supporting parallel downloading, e.g.
axel
:
/etc/makepkg.conf
DLAGENTS=('file::/bin/curl -gqC - -o %o %u'
          'ftp::/bin/axel -n 2 -o %o %u'
          'http::/bin/axel -n 2 -o %o %u'
          'https::/bin/axel -n 2 -o %o %u')
See also
Nonfree applications package guidelines#Custom DLAGENTS
.
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.
Build from local source files
If you want to make changes to the source code you can download the source code without building the package by using the
-o, --nobuild    Download and extract files only
option.
$ makepkg -o
You can now make changes to the sources and then build the package by using the
-e, --noextract  Do not extract source files (use existing $srcdir/ dir)
option. Use the
-f
option to overwrite already built and existing packages.
$ makepkg -ef
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
See
32-bit package guidelines
.
Unattended package signing
This article or section is a candidate for merging with
GnuPG#Unattended_passphrase
.
Notes:
This is not specific to
makepkg
. (Discuss in
Talk:Makepkg
)
This article or section needs expansion.
Reason:
Another option is
gpg-preset-passphrase(1)
(Discuss in
Talk:Makepkg
)
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 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.
Magnet URIs
Support for magnet URIs resources (with
magnet://
prefix) in the
source
field can be added using the
transmission-dlagent
AUR
download agent.
Running makepkg in a systemd control group
If the package you are building takes too many resources to build with your default
make
flags, which are otherwise set properly for most packages, you can try running it in its own
control group
.
makepkg-cg
AUR
is a wrapper for
makepkg
that achieved this via systemd control groups (see
systemd.resource-control(5)
).
Running with idle scheduling policy
Package build process can lead to high CPU utilization, especially in case of
#Parallel compilation
. Under heavy CPU load, the system can issue a significant slowdown up to becoming unusable, even with the highest
nice(1)
value. User interface and foreground applications may stutter or even became unresponsive.
This can be worked around by changing the scheduling policy to
SCHED_IDLE
before running
makepkg
. It ensures that package building process does not interfere with regular tasks and only utilizes remaining unused CPU time.
From
sched(7) § SCHED_IDLE: Scheduling very low priority jobs
:
This policy is intended for running jobs at extremely low priority (lower even than a +19 nice value with the
SCHED_OTHER
or
SCHED_BATCH
policies).
The
SCHED_IDLE
policy can be set by running
chrt(1)
command with the
-i
flag, specifying priority 0 (the only valid option for
SCHED_IDLE
) and specifying the PID of the current shell.
For most shells:
$ chrt -iap 0 $$
Tip
You can apply this command for every build by placing it into
makepkg.conf
.
For the
fish
shell, where
$$
is not set:
$ chrt -iap 0 %self
Relative paths inside each package directory
Instead of using absolute paths for the
package output options
, you can also configure relative paths inside each package directory.
Note
The following options might cause problems with some
AUR helpers
, as they might use
makepkg.conf
in a context where
$startdir
is not defined. So be careful.
For example, you can define target paths in your
makepkg.conf
file as follows. The
$startdir
variable refers to the directory where a
PKGBUILD
is located when you build a package.
PKGDEST="$startdir/build/packages/"
SRCDEST="$startdir/build/sources/"
SRCPKGDEST="$startdir/build/srcpackages/"
LOGDEST="$startdir/logs/"
This will result in:
Built packages will be stored in:
"package directory"/build/packages/
All downloaded source files will be stored in:
"package directory"/build/sources/
Built source packages will be stored in:
"package directory"/build/srcpackages/
All logs will be stored in:
"package directory"/logs/
makepkg
will still create
src/
and
pkg/
directories as usual, so this is expected behaviour.
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.
[6]
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.
Dotnet binaries also sometimes contain full paths to the
.pdb
files in the default config.
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
:
/etc/pacman.conf
...
XferCommand = /usr/bin/curl --proxy http://username:password@proxy.proxyhost.com:80 --location --continue-at - --fail --output %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
Pacman#pacman does not honor proxy settings
for more details.
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.
See also
makepkg(8)
makepkg.conf(5)
A Brief Tour of the Makepkg Process
makepkg source code