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 man makepkg.conf
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 you are otherwise distributing your 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 tosrc/
if it points elsewhere) -
SRCPKGDEST
— directory for storing resulting source packages (built withmakepkg -S
)
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 is missing, or if you want to add public keys by other developers, you can import it manually, or you can 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. In addition, the base group is assumed to be installed on all Arch systems.
- 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 ABS tree or the AUR. Once in possession of a PKGBUILD
, change to the directory where it is saved and issue the following command to build the package described by said PKGBUILD
:
$ 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 -s
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. [4]
Once all dependencies are satisfied and the package builds successfully, a package file (pkgname-pkgver.pkg.tar.xz
) will be created in the working directory. To install, use -i
/--install
(same as pacman -U pkgname-pkgver.pkg.tar.xz
):
$ makepkg -i
To clean up leftover files and folders, 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 folder. It prevents obsolete and remnant files from carrying over to the new builds:
$ makepkg -c
For more, see makepkg(8).
Tips and tricks
Creating optimized packages
A performance improvement of the packaged software can be achieved by enabling compiler optimizations for the host machine. The downside is that packages 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 you can verify/benchmark that something is faster, there is a very good chance it is not! The Gentoo Compilation Optimization Guide and Safe CFLAGS wiki article 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. Similarly, the make build system uses MAKEFLAGS
. 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 packages that can be installed on a wide range of machines.
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.As of version 4.3.0, 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,
CFLAGS="-march=native -O2 -pipe -fstack-protector-strong" CXXFLAGS="${CFLAGS}"
To see what flags this enables on your machine, run:
$ gcc -march=native -v -Q --help=target
- If you specify different value than
-march=native
, then-Q --help=target
will not work as expected.[5] You need to go through a compilation phase to find out which options are really enabled. See Find CPU-specific options on Gentoo wiki for instructions. - To find out the optimal options for a 32 bit x86 architecture, you can use the script gcccpuopt.
MAKEFLAGS
The MAKEFLAGS
option can be used to specify additional options for make. 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 your MAKEFLAGS
.
See man make
for a complete list of available options.
Improving compile times
tmpfs
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
tmpfs.
- The tmpfs folder must be mounted without the
noexec
option, else it will prevent build scripts or utilities from being executed. - Keep in mind that any package compiled in tmpfs will not persist across reboot. Consider setting the PKGDEST option appropriately to move the built package automatically to another (persistent) directory.
ccache
The use of ccache can improve build times by caching the results of compilations.
Generate new checksums
Since pacman 4.1, makepkg -g >> PKGBUILD
is no longer required because pacman-contrib was merged into upstream pacman, including the updpkgsums
script that will generate new checksums and/or replace them in the PKGBUILD. In the same directory as the PKGBUILD file, run the following command:
$ updpkgsums
Create uncompressed packages
If you do not mind having larger package files, you can speed up both packaging and installation by having makepkg produce uncompressed packages. Set PKGEXT='.pkg.tar'
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)
Build 32-bit packages on a 64-bit system
First, enable the multilib repository and install multilib-devel. Reply yes when asked about removing the conflicting gcc
and gcc-libs
packages; gcc-multilib is capable of building both 64-bit and 32-bit software.
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 -fstack-protector-strong" CXXFLAGS="${CFLAGS}" LDFLAGS="-m32 -Wl,-O1,--sort-common,--as-needed,-z,relro"
and invoke makepkg as such
$ linux32 makepkg --config ~/.makepkg.i686.conf
Troubleshooting
Makepkg sometimes fails to sign a package without asking for signature passphrase
With gnupg 2.1, gpg-agent no longer has to be started manually and will be started automatically on the first invokation of gpg. Thus if you do not manually start gpg-agent, makepkg will start it. The problem is that makepkg runs gpg inside a fakeroot, so gpg-agent is also started in that same environment. This leads to bad behavior. A possible solution is to manually start the gpg-agent, either on boot or by command (see GnuPG#gpg-agent for ways to do this), before you run makepkg, but this also can be unreliable.
A bug report has been filed on this issue.
In the meantime if you do not wish to experiment with your gpg-agent configuration, simply use makepkg without signing, and sign the packages afterwards with `gpg --detach-sign <package name>`.
CFLAGS/CXXFLAGS/CPPFLAGS in makepkg.conf do not work for QMAKE based packages
Qmake automatically sets the variable CFLAGS
and CXXFLAGS
according to what it thinks should be the right configuration. In order to let qmake use the variables defined in the makepkg configuration file, you must edit the PKGBUILD and pass the variables QMAKE_CFLAGS_RELEASE and QMAKE_CXXFLAGS_RELEASE to qmake. For example:
PKGBUILD
... build() { cd "$srcdir/$_pkgname-$pkgver-src" qmake-qt4 "$srcdir/$_pkgname-$pkgver-src/$_pkgname.pro" \ PREFIX=/usr \ QMAKE_CFLAGS_RELEASE="${CFLAGS}"\ QMAKE_CXXFLAGS_RELEASE="${CXXFLAGS}" make } ...
Alternatively, for a system wide configuration, you can create your own qmake.conf
and set the QMAKESPEC environment variable.
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 your .pro file:
YourProject.pro
... target.path = /usr/local/bin INSTALLS += target ...
WARNING: Package contains reference to $srcdir
Somehow, the literal strings $srcdir
or $pkgdir
ended up in one of the installed files in your package.
To identify which files, run the following from the makepkg build directory:
$ grep -R "$(pwd)/src" pkg/
Link to discussion thread.