A Brief Tour of the Makepkg Process: What Makes a Pacman Package
Introduction
This is a terse document covering the anatomy of a package built for the pacman package manager.
The following example commands can mostly run verbatim to manually create a package without makepkg.
Building
- build()
This is used for the creation and generation of needful resources and files. This function will create the
src
directory which is referred to via the$srcdir
variable.A typical procedure for most projects might look like this:
mkdir src
# Extract the source into srccd src
./configure --prefix=/usr
make
Installation
- package()
- The separation of build and installation happens here. Fakeroot is used to maintain appropriate permissions while not actually running as root. That is, the facade of root permission is maintained so long real root privilege is not needed.
mkdir pkg
cd src/program
fakeroot -- make DESTDIR=../../pkg install
Metadata
The meat of the data pacman depends on is now generated, this includes a simple
key value pair file called .PKGINFO
and an "mtree", the .MTREE
.
A .PKGINFO
is just a simple collection of what one would express in the
PKGBUILD, almost exactly. Keys with multiple entries are simply repeated.
cd pkg
cat <<EOF> .PKGINFOpkgname = $pkgnamepkgver = $pkgver-$pkgrelpkgdesc = $pkgdescurl = $urllicense = $licensebuilddate = $(date -u '+%s')size = $(du -sb --apparent-size | awk '{print $1}')arch = $(uname -m)depend = libfoodepend = libbardepend = libbazmakedepend = buildlibfoomakedepend = buildlibbarmakedepend = buildlibbazEOF
An mtree is essentially a way to generate a map of a directory structure with
all kinds of attributes included, such as permissions, uids, etc. This allows
pacman to easily know what the attributes should be so that any issues can be
cross-checked when using the -Qk
option.
Bsdtar is then used to generate the .MTREE
file. This disables !all of the
attributes and then enables a selected few.
When creating the mtree, the .PKGINFO
file needs to be first in the
archive.
cd pkg
fakeroot -- env LANG=C bsdtar -czf .MTREE --format=mtree --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' .PKGINFO *
Package
All that remains is to generate a tarball of our package. We use fakeroot again as with everything during the package phase.
cd pkg
fakeroot -- env LANG=C bsdtar -cf - .MTREE .PKGINFO *| xz -c -z - >$pkgname-$pkgver-$pkgrel-$arch.tar.xz
Example
#!/bin/sh --# Basic makepkg which just creates a package for antimicro, built from git.# Because I don't do any error handling, just bail if any command fails for# any reason.set -o errexit
startdir=$PWD
srcdir=$startdir/src
pkgdir=$startdir/pkg
# The pkgrel just indicates the version of the build itself, independent of# the pkgver, although a pkgver bump resets the pkgrel to 1.
pkgrel=1
arch=$(uname -m)# Check for all dependencies. This command will return any which are# missing, each one on a newline.
pacman -T cmake qt5-tools libxtst qt5-base sdl2 libxkbcommon-x11
# Build.
mkdir -p "$srcdir"cd"$srcdir"
git clone https://github.com/AntiMicro/antimicro
cd antimicro
# No hyphens allowed in the version.
pkgver=$(git describe --long --tags | sed 's/^v//; s/\([^-]*-g\)/r\1/; s/-/./g')
cmake -DMAKE_INSTALL_PREFIX=/usr -DUSE_SDL2=ON
make
# Installation.
mkdir -p "$pkgdir"
fakeroot -- make DESTDIR="$pkgdir" install
# Package.cd"$pkgdir"
cat <<!> .PKGINFOpkgname = antimicro-gitpkgver = $pkgver-$pkgrelpkgdesc = map keyboard and mouse actions to gamepad buttons, inspired by qjoypadurl = https://github.com/AntiMicro/antimicrobuilddate = $(date -u +%s)packager = Unknown Packagersize = $(du -sb --apparent-size "$pkgdir"| awk '{print $1}')arch = $archlicense = GPLconflict = antimicroprovides = antimicrodepend = libxtstdepend = qt5-basedepend = sdl2depend = libxkbcommon-x11makedepend = cmakemakedepend = qt5-tools!
fakeroot -- env LANG=C bsdtar -czf .MTREE --format=mtree --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' .PKGINFO *
fakeroot -- env LANG=C bsdtar -cf - .MTREE .PKGINFO *| xz -c -z - >"$startdir"/antimicro-git-"$pkgver"-"$pkgrel"-"$arch".pkg.tar.xz
# Test.cd"$startdir"
namcap -m antimicro-git-"$pkgver"-"$pkgrel"-"$arch".pkg.tar.xz