Creating Arch Linux Packages By Hand
08 Dec 2011
One of my favorite things about Arch Linux is pacman
. It’s a simple,
fast, versatile package manager on which Arch is built. I really love
how easy it is to create packages using makepkg
that can be
installed with pacman
and I actually maintain
a few
packages myself over in the AUR. More info on creating your own
packages can be found
here.
That’s all fine and good, but what if (for whatever reason) you don’t
even want to create a PKGBUILD
and run it through makepkg
? Under
certain circumstances it might be easier to simply create the package
install tarball “by hand” (and if not easier, at least it’s an
interesting exercise :) ).
Motivation: Today I needed to install a piece of proprietary software that uses a
GUI installer and decided that rather than cooking up a full
PKGBUILD
for the thing I would just set the install directory to
some temporary location, tar
that up and compress it with xz
, add
the necessary metadata, and then install it with pacman -U
.
So, here we go! You can follow along in a terminal if you want.
First, we create an area where we’ll create the hierarchy of files
that we want pacman
to install to our system:
mkdir /tmp/manualpackage/pkg; cd /tmp/manualpackage/pkg
Now, fill up the pkg directory with some junk (this will be placed on
/
later by pacman
):
Note: at this stage, rather than creating a bunch of files manually,
you could do something like run a GUI installer, setting the install
location to /tmp/manualpackage/pkg
.
Now we have to provide some metadata that pacman
will use to manage
its database. At a bare minimum, we have to include a file named
.PKGINFO
with some basic information about our package:
Paste the following into .PKGINFO
:
Note: This file is sort of touchy! I got the pkgver
variable wrong
the first time (I was simply using the number 1
) and it sort of
corrupted my pacman
database (all I had to do to fix it was remove
the offending directory from /var/lib/pacman/local
and the installed
files manually). There’s not much validation going on because this
file is usually generated by another tool (like makepkg
).
Anyways, here’s what we have so far:
$ tree -a
.
`-- pkg
|-- .PKGINFO
`-- usr
`-- share
`-- manualpackage
`-- pizza.txt
4 directories, 2 files
We’re now ready to create the package
tarball. Since 2010,
Arch Linux has been using the xz
format (also known as lzma2
) to
compress packages. xz
is a little slower than, say, gzip
, but it
achieves much higher compression ratios. Here’s how we compress our
package using tar
and xz
(lifted from /usr/bin/makepkg
):
$ tar -cf - .PKGINFO * | xz -c -z - > ../manualpackage.pkg.tar.xz
That’s it! We now have a package that can be fully managed by pacman
!
Just for fun let’s take one last peek at what we have:
$ tar tf manualpackage.pkg.tar.xz
.PKGINFO
usr/
usr/share/
usr/share/manualpackage/
usr/share/manualpackage/pizza.txt
Now, let’s install it:
$ sudo pacman -U manualpackage.pkg.tar.xz
resolving dependencies...
looking for inter-conflicts...
Targets (1): manualpackage-1.0.0-1
Total Download Size: 0.00 MB
Total Installed Size: 0.01 MB
Proceed with installation? [Y/n] y
(1/1) checking package integrity [######################] 100%
(1/1) checking for file conflicts [######################] 100%
(1/1) installing manualpackage [######################] 100%
Verify that it is indeed installed and manageable by pacman
:
$ pacman -Q | grep manualpackage
manualpackage 1.0.0-1
Verify that our package files were installed to the filesystem:
$ ls -l /usr/share/ | grep manualpackage | wc -l
1
$ cat /usr/share/manualpackage/pizza.txt
all your base are belong to us
Now, let’s remove it:
$ sudo pacman -R manualpackage
checking dependencies...
Remove (1): manualpackage-1.0.0-1
Total Removed Size: 0.01 MB
Do you want to remove these packages? [Y/n] y
(1/1) removing manualpackage [######################] 100%
And verify that it’s gone:
$ pacman -Q | grep manualpackage
# ...no output...
$ ls -l /usr/share/ | grep manualpackage | wc -l
0
Clean as a whistle! Thanks pacman
!