The ABS or Arch Build System is a package building system native to the Arch Linux distribution: with it, we can easily build packages which can be installed with pacman, the distribution package manager, starting from source code. All we have to do is to specify instruction inside a PKGBUILD file and then build the package using the makepkg tool. In this tutorial we will see how to customize and re-build an already existing package.
In this tutorial you will learn:
- What is the Arch Build System
- How to download an existing package source files
- How to modify a PKGBUILD
- How to build a package using the makepkg utility
Software requirements and conventions used
|Category||Requirements, Conventions or Software Version Used|
|Software||asp, makepkg, base-devel|
|Other||Root permissions to install build and runtime dependencies|
|Conventions|| # - requires given linux commands to be executed with root privileges either directly as a root user or by use of |
Rebuilding a package
As an example for this tutorial we will rebuild the hplip package. This package contains the open source software needed to use some HP printers on Linux. On distributions like Debian and Fedora, we have the choice to install the hplip package which contains only command line utilities and drivers, and optionally hplip-gui, which includes also graphical tools that can be used to setup and control the printer. Since I use the system-config-printer tool to control existing printers and I don’t want to have unnecessary and overlapping tools on my system, I need to change how the software is built and packaged on Arch Linux: this is what we will do in this tutorial.
As a first step we need to install some packages: base-devel and asp. The first is a package group which contains many essential utilities to compile software like fakeroot, gcc and make. The second is a tool to retrieve source files for existing Arch Linux packages. To install them we use pacman:
$ sudo pacman -S base-devel asp
As already mentioned, we will also need the makepkg which is already installed since it comes with pacman itself. Once we installed all the needed packages we can proceed to the makepkg configuration.
The default, system-wide makepkg configuration file is
/etc/makepkg.conf; we will copy this to
~/.makepkg.conf, to create a user-specific configuration we can tweak without the need to use administrative privileges (
~/.config/pacman/makepkg.conf could also be used). Some noticeable variables one may want to tweak in the file are the following:
|CPPFLAGS||The flags to use for the C preprocessors||-D_FORTIFY_SOURCE=2|
|CFLAGS||The flags to use for the C compiler||-march=x86-64 -mtune=generic -O2 -pipe -fno-plt|
|CXXFLAGS||The flags to use for the C++ compiler||-march=x86-64 -mtune=generic -02 -pipe -fno-plt|
|BUILDDIR||The directory to use for package building||/tmp/makepkg|
|INTEGRITY_CHECK||The integrity check to use||md5|
|PKGDEST||The directory where all packages will be placed||. (working directory)|
|SRCDEST||The directory where source data will be stored||./src|
Once we tweaked our configuration to better suite our needs, we can proceed and download the source files for the Arch Linux package we want to modify, in this case, as we said before, hplip.
Downloading the package source files
To download the source files for the package we want to modify, we must use the
asp tool we installed before. In this case we run:
$ asp checkout hplip
After few seconds the
hplip directory should be created in our working directory. Inside of it, we will find two subdirectories:
repos which contains subdirectories of its own, named after repository name and system architecture, and
trunk, which contains the main line of development of the SVN repository.
hplip/ ├── repos │ └── extra-x86_64 │ ├── 0022-Add-include-cups-ppd.h-in-various-places-as-CUPS-2.2.patch │ ├── 0023-Fix-handling-of-unicode-filenames-in-sixext.py.patch │ ├── 0025-Remove-all-ImageProcessor-functionality-which-is-clo.patch │ ├── disable_upgrade.patch │ ├── hplip-revert-plugins.patch │ ├── PKGBUILD │ ├── python3.diff │ └── reproducible-gzip.patch └── trunk ├── 0022-Add-include-cups-ppd.h-in-various-places-as-CUPS-2.2.patch ├── 0023-Fix-handling-of-unicode-filenames-in-sixext.py.patch ├── 0025-Remove-all-ImageProcessor-functionality-which-is-clo.patch ├── disable_upgrade.patch ├── hplip-revert-plugins.patch ├── PKGBUILD ├── python3.diff └── reproducible-gzip.patch
We can modify the
Modifying the PKGBUILD file
PKGBUILD file is a Bash script containing the building instruction for the Arch Linux package. In this case, what we need to modify in the file is the content of the build function which contains the commands use to configure and compile the source files, in this case hplip. In the function we can see that the
./configure script is launched with the following flags:
[...] ./configure --prefix=/usr \ --enable-qt5 \ --disable-qt4 \ --enable-hpcups-install \ --enable-cups-drv-install \ --enable-pp-build [...]
Since I don’t want graphical applications to be built, and I want to install the minimum necessary for my printer to work correctly, I don’t need support for qt5, so I can remove the
--enable-qt5 option (I could use
--enable-qt5=no instead, but this would be redundant since the flag is disabled by default, as we can read by launching
./configure --help in the hplip source directory). I then need to use the
--disable-gui-build flag to disable gui build and use the
--enable-lite-build flag to obtain a lite build with only the necessary components to build and scan (the printer includes also a scanner). The final result would be something like:
[...] ./configure --prefix=/usr \ --disable-qt4 \ --enable-hpcups-install \ --enable-cups-drv-install \ --enable-pp-build \ --disable-gui-build \ --enable-lite-build [...]
Since we disabled qt5 support, we can also remove
python-pyqt5 from the list of dependencies needed to build the software, listed in the makedepends Bash array on line
15 of the file:
makedepends=('python-pyqt5' 'sane' 'rpcbind' 'cups' 'libusb')
Now that we modified the
PKGBUILD, we can proceed to the next step and build our package using makepkg.
Build the package
PKGBUILD file is ready, we can build our modified package using the makepkg utility. Before we do it, we need to another thing: since the signature of the downloaded source files for the software we want to build is checked automatically against a gpg key, we need to said key to our gpg keyring, otherwise the build process will fail. In this case to import the key we would run:
$ gpg --keyserver keyserver.ubuntu.com --recv 73D770CDA59047B9
We should be notified that the key was successfully imported:
gpg: key 73D770CDA59047B9: public key "HPLIP (HP Linux Imaging and Printing) <email@example.com>" imported gpg: Total number processed: 1 gpg: imported: 1
The key identified by
73D770CDA59047B9 is the key used to sign the hplip source tarball. If you want to know more about verifying a gpg signature you can take a look at our How to verify the integrity of a Linux distribution iso image article I wrote on the subject.
Once ready, we move inside the directory where the
PKGBUILD is stored and run the following command:
$ makepkg --clean --syncdeps --rmdeps
Let’s take a quick look at the options we use used when invoking the makepkg tool. With the
--clean option (
-c) we can make so that leftover files and directories are removed after a successful package build. We also used
-s): when this option is used the missing runtime and build dependency of the package are installed using pacman. Finally, we used the
--rmdeps option (
-r): this will cause the previously installed dependencies to be uninstalled after the build is complete.
If we have already performed a build of the package, and we want to re-run the process we also need to use the
-f) option, since makepkg normally refuses to build a package that already exists in the same directory).
Once we launch the command above, the compilation of the source files and the creation of the package will begin. We will be asked to confirm we want to install the missing dependencies:
==> Making package: hplip 1:3.20.6-2 (Tue 18 Aug 2020 10:29:43 AM CEST) ==> Checking runtime dependencies... ==> Installing missing dependencies... [sudo] password for egdoc: resolving dependencies... looking for conflicting packages... Packages (18) jbig2dec-0.18-1 libidn-1.36-1 perl-alien-build-2.29-1 perl-alien-libxml2-0.16-2 perl-capture-tiny-0.48-4 perl-clone-0.45-2 perl-dbi-1.643-2 perl-ffi-checklib-0.27-2 perl-file-chdir-0.1011-4 perl-file-which-1.23-4 perl-path-tiny-0.112-2 perl-xml-libxml-2.0205-2 perl-xml-namespacesupport-1.12-4 perl-xml-sax-1.02-1 perl-xml-sax-base-1.09-4 foomatic-db-engine-4:20200206-1 ghostscript-9.52-1 net-snmp-5.8-6 Total Installed Size: 61.76 MiB :: Proceed with installation? [Y/n] y [...] ==> Checking buildtime dependencies... ==> Installing missing dependencies... resolving dependencies... looking for conflicting packages... Packages (6) gd-2.3.0-1 libgphoto2-2.5.25-1 libieee1284-0.2.11-9 libxpm-3.5.13-2 rpcbind-1.2.5-3 sane-1.0.30-1 Total Installed Size: 26.50 MiB :: Proceed with installation? [Y/n] y [...]
Once the build is complete, we will be asked to confirm that we want to remove the previously installed packages. At this point, if everything went as expected, we should find the package created in the directory we specified with in the makepkg configuration file (the
PKGDEST directory). By default the package is created in the working directory. In this case, the
hplip-1:3.20.6-2-x86_64.pkg.tar.zst package was generated; we can install it using pacman:
$ sudo pacman -U hplip-1:3.20.6-2-x86_64.pkg.tar.zst
Handle conflicts on system upgrades
Since we generated a custom package based on the modification we made inside the
PKGBUILD file, a problem arises: when the system will be updated, a new version of the standard package may be installed, thus overwriting the modifications we made. How we can avoid this? The simpler solution is to make the packages we modify member of a specific group (say we want to call it “modified”), and then instruct pacman to avoid upgrading its members. To do this we must modify the
PKGBUILD again and add this line:
At this point we must rebuild the package. Once done we must modify the
/etc/pacman.conf file and add the group to the list of the ignored ones. The line to modify is
IgnoreGroup = modified
The pacman package manager will skip the upgrade of the package, so we must do it manually when needed.
In this article we saw how we can use ABS, the Arch Build System to modify and re-build an existing package in order to tailor it to our specific needs. We saw how to download a package source files, how to modify a
PKGBUILD, and how to re-build the package using the makepkg utility. To better explore the subject you can take a look at the makepkg manpage and consult the Arch Build System wiki page.