makepkg - ArchWiki

Jump to content

# makepkg

6 languages

- Español
- Français
- 日本語
- Português
- Русский
- 中文（简体）

From ArchWiki

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.

Tip: devtools helper scripts for building packages in a clean chroot use the `/usr/share/devtools/makepkg.conf.d/arch.conf` configuration file instead.

See makepkg.conf(5) for more information.

### 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 -unobody 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.

### Performance-related changes

Commit 90bf367e (included in pacman 6.0.2-9 from Feburary 2024) implemented two configuration changes which may have an important impact on local package build performance and are especially recommended to be reviewed by users:

- enabling the `debug` and `lto` flags: see #Disable debug packages and LTO
- setting the default zstd compression algorithm level to `--ultra -20`: see #Changing compression level

  Note: The compression level change has been reverted in commit 319671cc from 2024-08-16[5], and will be rolled out with pacman 7.0 release[6].

See archlinux/packaging/packages/pacman!1 and archlinux/packaging/packages/pacman#23 for more context.

### 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.

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.[7] 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 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

    RUSTFLAGS="... -C link-arg=-fuse-ld=mold"

#### Disable debug packages and LTO

Commit 90bf367e included in pacman 6.0.2-9 from Feburary 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)

plzipAUR 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.

### 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 gnupg-set-passphrase(1)[dead link 2022-06-25] (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-dlagentAUR 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-cgAUR 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 a `src/` and `pkg/` directories a 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. [8]

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`:

    /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

Categories:

- Package development
- About Arch
- Commands
- OpenPGP

Hidden categories:

- Pages or sections flagged with Template:Merge
- Pages with dead links
- Pages or sections flagged with Template:Expansion