ALPM(7)
β¨ ALPM(7) β Arch Linux Package Management β¨
okay bestie, welcome to alpm(7) β the page from the Miscellaneous Information Manual that explains how Arch Linux package management is set up. it's giving very "the whole pipeline from source to your system" energy π
β¨ NAME β¨
alpm β Arch Linux Package Management.
πΈ DESCRIPTION πΈ
So Arch Linux Package Management β ALPM for short β is the whole process of grabbing sources from upstream projects, optionally building them, wrapping them up in a dedicated package format (peep alpm-package), and then getting those package files out to users of the Arch Linux[1] distribution.
The format used to distribute software as prebuilt binary artifacts is openly accessible, and this page documents it at a high level in the sections below. Arch Linux[1] is the main character here, but honestly it may find use in other distributions or on other platforms too π¦
π Disclaimer π
Throughout this doc the word βrepositoryβ / βrepoβ shows up in different contexts, so let's not get it twisted:
alpm-source-repo: a repository (like, e.g., a git repository) that holdsPKGBUILDpackage build scripts, and you build one or severalalpm-packagefiles from it. Besides those package build scripts, analpm-source-repomay also contain aSRCINFOfile β that's a collection of metadata on the data defined in thePKGBUILDfile.alpm-repo: a repository (e.g. a directory served by a webserver) that providesalpm-packagefiles, digital signatures, andalpm-repo-dbfiles that define the state of thealpm-repo. Everyalpm-repo-dbcontains specific package-related metadata (i.e.alpm-repo-descandalpm-repo-files).
Short version: alpm-source-repo is the location from which alpm-package files get built, while alpm-repo is the location where those files get stored later on. periodt π
π¦ Metadata connections π¦
Metadata connections between alpm-source-repo, alpm-package and alpm-repo-db are literally this:
alpm-source-repo
|
PKGBUILD
/ \
SRCINFO \
\
\
,------- alpm-package -----.
/ / | \ \
, BUILDINFO | PKGINFO |
| | | |
| ALPM-MTREE | |
| | |
| alpm-repo-db | |
| / \ | /
alpm-repo-files alpm-repo-desc
Metadata connections between alpm-package and alpm-db (libalpm) are:
alpm-package ----------.-----------------.
/ | \ \ \
BUILDINFO | PKGINFO \ alpm-db \
| | \ \ / \ \
ALPM-MTREE ` `--- alpm-db-files \ \
\ \ \
`------------------------ alpm-db-desc
π§ Building from source π§
Package data files β binary stuff or any other data artifacts β start from an alpm-source-repo. That whole process is abstracted by dedicated package build tools such as makepkg, which rely on bash based PKGBUILD package build scripts.
Those package build scripts define the environment where packages get created and used. They cover source inputs, build, run-time and test dependencies, plus every step needed for the creation of data files, their testing and installation. They also carry metadata about the packages β name, version, description, groups, source or checksums. Build tools automate the steps of downloading and verifying local or upstream source inputs, applying any required modifications (e.g. patches), calling any respective build systems, running tests, and installing the resulting binary or other data artifacts to a location from which a package file is created.
The makepkg tool is able to record relevant metadata of the current system environment in a BUILDINFO file. Based on this file an identical environment can be setup again β which is a prerequisite for reproducible builds[2]. no cap, that matters.
Generally, it is desirable to create an alpm-package file in a secluded environment that can be setup reproducibly (e.g. chroots, containers, or virtual machines) and only contains the various dependencies of a package (see alpm-package-relation). However, on its own makepkg is not able to ensure that a build environment only contains packages that satisfy the various dependencies of a package. This is why Arch Linuxβs canonical packaging tool pkgctl creates clean chroot environments with the help of systemd-nspawn and executes makepkg within them. iconic behavior, honestly π
π₯ Download, verification and authentication π₯
The inputs (i.e. the sources) of a package build script may be local or remote files, or data in version control systems. After download, they are verified using optional locked hash digests (see alpm-package-source-checksum) for the respective files. This is a fundamental building block for reproducible builds[2], and it allows detection of supply chain attack[3] vectors that rely on altering source files. In addition, each input may be authenticated using a cryptographic signature.
β¨ Modification β¨
Package build inputs sometimes need to be modified β either to fix issues with the input files themselves, or to accommodate to the specific behavior of the environment they are supposed to be used in. Applying patches is a common scenario, and it is usually done in a preparation step after the download, verification and authentication of the inputs.
π Building π
The next step after the potential modification of source inputs is to generate data files for the alpm-package file. This may include compilation of binary files, translations, assets, plain data, or any other type of file that might be included in a package. Depending on source input and programming language, a diverse set of tools may be required to build binary artifacts from source code.
π Testing π
After successfully building, any available tests of the respective project are run to ensure that the given project can be integrated with the system that it has been built against.
π Installation π
Finally, any generated package data files are installed into an empty output directory β either using the projectβs build system or manually. During this step, the package build tool also creates required metadata files, such as BUILDINFO, PKGINFO and ALPM-MTREE.
When creating more than one alpm-package from a PKGBUILD, as many output directories as there are packages are created. For information on creating multiple packages from a single PKGBUILD, refer to alpm-split-package.
π Creating packages π
One alpm-package file is created from each output directory after building from source, testing and installation. Package files are optionally compressed tar archives, that contain any files that have been installed into the empty output directory, an optional alpm-install-scriptlet and the ALPM specific metadata files BUILDINFO, PKGINFO and ALPM-MTREE.
Once a package is created, it may be digitally signed. ALPM currently supports detached OpenPGP signatures[4] for this purpose. With the help of digital signatures, the authenticity of a package file can later be verified using the packagerβs OpenPGP certificate[5].
π Maintaining package repositories π
An alpm-repo is a collection of unique alpm-package files in specific versions and an alpm-repo-db which describes this particular state. Each package file is described by an alpm-repo-desc file in the alpm-repo-db. This file is created from a combination of the package filesβ PKGINFO data, the optional digital signature and the metadata of the package file itself.
Package repositories are maintained with the help of dedicated tools such as repo-add. To serve more complex and evolved repository setups, while allowing access to a larger set of package maintainers, Arch Linux relies on dbscripts[6].
β Installing packages β
ALPM based packages are installed using package management software such as pacman. While packages can be installed and upgraded individually, they are mostly used via package repositories. For this, the package management software downloads the alpm-repo-db file of each alpm-repo it is configured to use. Based on their data, it can compare the state of all specified package repositories and their package files with the state of a local system. If newer package versions are detected in the alpm-repo-db, the package management software downloads these new package files and installs them.
The installation of a package file implies several things:
- The removal of all files from the filesystem, that are provided by the previously installed package version.
- The addition of all files to the filesystem, that are provided by the new version of the package.
- The update of the systemβs metadata which tracks what version of a given package is currently installed.
β¨ EXAMPLES β¨
okay so real talk β this next part is the whole glow-up tour where we follow one (1) package file and all its metadata through the entire lifecycle. very basic example, but it's giving main character energy the whole way through. π¦
π± Creating a package file from a source repository
The PKGBUILD below lives in an alpm-source-repo and defines a package that has exactly one data file in it:
pkgname=example
pkgver=0.1.0
pkgrel=1
pkgdesc="An example package"
arch=(any)
url="https://example.org"
license=(CC-BY-SA-4.0)
backup=(etc/example.conf)
package() {
install -vdm 755 "$pkgdir/etc/"
printf "Very important config\n" > "$pkgdir/etc/$pkgname.conf"
install -vdm 755 "$pkgdir/usr/share/$pkgname/"
printf "Hello World\!
" > "$pkgdir/usr/share/$pkgname/example.txt"
}
And it gets represented by this SRCINFO file:
pkgbase = example
pkgdesc = An example package
pkgver = 0.1.0
pkgrel = 1
url = https://example.org
arch = any
license = CC-BY-SA-4.0
pkgname = example
So when you build an alpm-package in a clean environment from that alpm-source-repo up there, you get a package file called example-0.1.0-any.pkg.tar.zst, and it shows up with its bestie the detached OpenPGP signature, example-0.1.0-any.pkg.tar.zst.sig. π
That package file contains the ALPM-MTREE, BUILDINFO and PKGINFO metadata files, plus a single data file and all of its parent directories. yes, the whole family tree.
The ALPM-MTREE file may look similar to the below:
#mtree
/set type=file uid=0 gid=0 mode=644
./.BUILDINFO time=1752836739.0 size=5271 sha256digest=9924a366a4ad02c31b121b22a2b285b2cae3a57873052169deb9d237936bef83
./.PKGINFO time=1752836739.0 size=297 sha256digest=0c8481c16dfc09ffdb0f518f827109795c1e07816ab7205ffffa6837b92fa4fb
./usr time=1752836739.0 mode=755 type=dir
./usr/share time=1752836739.0 mode=755 type=dir
./usr/share/example time=1752836739.0 mode=755 type=dir
./usr/share/example/example.txt time=1752836739.0 size=14 sha256digest=732c1c47a8296f4525307d28469d7ba1f3f5e4796fe55bc5625febc720a09d92
The BUILDINFO may look similar to the below β heads up, it's truncated for brevity, don't come for me:
format = 2
pkgname = example
pkgbase = example
pkgver = 0.1.0-1
pkgarch = any
pkgbuild_sha256sum = c2cdacc7de9ed0cb40a9177255701339f1e53f1014950c1793bb34740bfd64e9
packager = John Doe <john@example.org>
builddate = 1752836739
builddir = /build
startdir = /startdir
buildtool = devtools
buildtoolver = 1:1.3.2-1-any
buildenv = !distcc
buildenv = color
buildenv = !ccache
buildenv = check
buildenv = !sign
options = strip
options = docs
options = !libtool
options = !staticlibs
options = emptydirs
options = zipman
options = purge
options = debug
options = lto
installed = acl-2.3.2-1-x86_64
installed = archlinux-keyring-20250716-1-any
And the PKGINFO of the alpm-package may look similar to the below:
pkgname = example
pkgbase = example
xdata = pkgtype=pkg
pkgver = 0.1.0-1
pkgdesc = An example package
url = https://example.org
builddate = 1752836739
packager = John Doe <john@example.org>
size = 14
arch = any
license = CC-BY-SA-4.0
backup = etc/example.conf
π¦ Adding a package file to a repository
So after you add example-0.1.0-any.pkg.tar.zst and example-0.1.0-any.pkg.tar.zst.sig to an alpm-repo named example-repo, its corresponding alpm-repo-db gets updated. slay.
The dedicated alpm-repo-desc for the package may look similar to this:
%FILENAME%
example-0.1.0-1-any.pkg.tar.zst
%NAME%
example
%BASE%
example
%VERSION%
0.1.0-1
%DESC%
An example package
%CSIZE%
2274
%ISIZE%
14
%SHA256SUM%
640d6a9eaebf312273371eb7589338a3f01eb623cddf9f671ee96501d7c65ae1
%PGPSIG%
iHUEABYKAB0WIQRizHP4hOUpV7L92IObeih9mi7GCAUCaBZuVAAKCRCbeih9mi7GCIlMAP9ws/jU4f580ZRQlTQKvUiLbAZOdcB7mQQj83hD1Nc/GwD/WIHhO1/OQkpMERejUrLo3AgVmY3b4/uGhx9XufWEbgE=
%URL%
https://example.org
%LICENSE%
CC-BY-SA-4.0
%ARCH%
any
%BUILDDATE%
1752836739
%PACKAGER%
John Doe <john@example.org>
The alpm-repo-files for the package file contains:
%FILES%
etc/
etc/example.conf
usr/
usr/share/
usr/share/example/
usr/share/example/example.txt
π» Installation on a client host
Now we hop over to a client host, where the package management software pacman is configured to use the alpm-repo example-repo. Once its alpm-repo-db is synchronized, the system administrator of the host decides to install the example package from the repository. π
After installation, the client host's alpm-db is modified so it contains metadata about the example package.
It contains the below alpm-db-desc file:
%NAME%
example
%VERSION%
0.1.0-1
%BASE%
example
%DESC%
An example package
%URL%
https://example.org
%ARCH%
any
%BUILDDATE%
1752836739
%INSTALLDATE%
1752836973
%PACKAGER%
John Doe <john@example.org>
%SIZE%
14
%LICENSE%
CC-BY-SA-4.0
%VALIDATION%
pgp
%XDATA%
pkgtype=pkg
The alpm-db-files entry in the system database starts from the same list of packaged paths, and it adds backup tracking for files that may be modified locally. π The optional %BACKUP% section records the MD5 checksum of each tracked file as installed on the system:
%FILES%
usr/
etc/
etc/example.conf
usr/share/
usr/share/example/
usr/share/example/example.txt
%BACKUP%
etc/example.conf d41d8cd98f00b204e9800998ecf8427e
And the ALPM-MTREE file also equals the one contained in the alpm-package file. no cap, identical:
#mtree
/set type=file uid=0 gid=0 mode=644
./.BUILDINFO time=1752836739.0 size=5271 sha256digest=9924a366a4ad02c31b121b22a2b285b2cae3a57873052169deb9d237936bef83
./.PKGINFO time=1752836739.0 size=297 sha256digest=0c8481c16dfc09ffdb0f518f827109795c1e07816ab7205ffffa6837b92fa4fb
./usr time=1752836739.0 mode=755 type=dir
./usr/share time=1752836739.0 mode=755 type=dir
./usr/share/example time=1752836739.0 mode=755 type=dir
./usr/share/example/example.txt time=1752836739.0 size=14 sha256digest=732c1c47a8296f4525307d28469d7ba1f3f5e4796fe55bc5625febc720a09d92
π SEE ALSO π
the whole friend group, one link at a time. go read these next, bestie π«Ά
bash(1)git(1)pkgctl(1)systemd-nspawn(1)tar(1)libalpm(3)ALPM-MTREE(5)BUILDINFO(5)PKGBUILD(5)PKGINFO(5)SRCINFO(5)alpm-db(7)alpm-db-desc(7)alpm-db-files(5)alpm-install-scriptlet(5)alpm-package(7)alpm-package-relation(7)alpm-package-source-checksum(7)alpm-repo(7)alpm-repo-db(7)alpm-repo-desc(7)alpm-repo-files(5)alpm-source-repo(7)alpm-split-package(7)makepkg(8)pacman(8)repo-add(8)
π NOTES π
the receipts, in order π§Ύ
- Arch Linux β
https://archlinux.org - reproducible builds β
https://reproducible-builds.org - supply chain attack β
https://en.wikipedia.org/wiki/Supply_chain_attack - OpenPGP signatures β
https://openpgp.dev/book/signing_data.html#detached-signatures - OpenPGP certificate β
https://openpgp.dev/book/certificates.html - dbscripts β
https://gitlab.archlinux.org/archlinux/dbscripts
and that's the whole page, bestie β you ate that. π this is the ALPM manual, section 7 of the manual set, and yes the footer is literally just that tiny (7), so consider this your cute little sign-off instead: go forth, read your metadata files, verify your signatures, and stay iconic. πβ¨π
π¦ where this page comes from
- arch rolling: alpm-docs 0.13.0-1 Β· CC-BY-SA-4.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms