Ever want to customize packages in the AUR Repo, but don’t want to keep a separate PKGBUILD? Not to mention having to keep it updated when there’s a package that’s almost the same on AUR?
Enter Customizepkg, an Arch AUR package that will automatically modify the PKGBUILD of a package when that package installs or updates via Yaourt (and possibly others), doing so according to whatever you tell it to do.
I’m going to show how set it up and use it. I will also give examples of how to use it to build the h2o webserver with different arguments, such as using the system’s OpenSSL over the bundled LibreSSL, using the latest version of LibreSSL, or even modifying to source code to change the program’s internal name!
Install
First, you will need to install and setup Yaourt, or any other AUR package manager (though you may have to modify it to use Customizepkg). This guide will give instructions on how to integrate with Yaourt.
So, first install it with yaourt:
yaourt -Sy customizepkg-git
Setup
It works by reading your package configurations in your /etc/customizepkg/
folder. So make that folder:
mkdir /etc/customizepkg/
When you want to change a package, you put your desired changes into a file with the same name. If this file does not have executable permissions, it is read for actions. If it is executable, it is run instead.
/etc/customizepkg/$PACKAGENAME
These files can contain:
- Actions (addline, remove, removeline, add, addline or replace )
- Patches
- Executables to download, fix, or do other things with the build.
Using Actions
An action is simply a line that tells customizepkg how to customize the desired package. They are in the format:
ACTION#CONTEXT#PATTERN#VALUE
Where
- Action can be: remove, removeline, add, addline or replace
- Context can be: depends, conflicts, makedepends etc.. or global for matching regexp in the whole PKGBUILD
- Pattern can be any rexgexp
- Value (only needed for replace) can be any string
- Comments start with #
Example: Replace/Removeline to enable OpenSSL
To enable OpenSSL on h2o, we can change or remove the -DWITH_BUNDLED_SSL=
option.
We can use either replace:
replace#build#-DWITH_BUNDLED_SSL=on#-DWITH_BUNDLED_SSL=off
Which shows in yaourt:
=> replaces '-DWITH_BUNDLED_SSL=on' with '-DWITH_BUNDLED_SSL=off' in build
--- ./PKGBUILD
+++ ./PKGBUILD.custom
@@ -26,7 +26,7 @@
msg2 'Building...'
cmake \
-DCMAKE_INSTALL_PREFIX=/usr \
- -DWITH_BUNDLED_SSL=on \
+ -DWITH_BUNDLED_SSL=off \
-DWITH_MRUBY=on \
.
make
or removeline:
removeline#build#-DWITH_BUNDLED_SSL=on \\
Which shows something like:
=> remove whole line containing '-DWITH_BUNDLED_SSL=on \\' in build
--- ./PKGBUILD
+++ ./PKGBUILD.custom
@@ -26,7 +26,6 @@
msg2 'Building...'
cmake \
-DCMAKE_INSTALL_PREFIX=/usr \
- -DWITH_BUNDLED_SSL=on \
-DWITH_MRUBY=on \
.
make
Using either of these (don’t use both!) will find OpenSSL:
-- Found OpenSSL: /usr/lib64/libssl.so;/usr/lib64/libcrypto.so (found version "1.0.2h")
Example: Use latest LibreSSL
In this example, we will build h2o with a statically linked LibreSSL, same as it is by default, but we want it to be the latest version (2.4.2 at this writing). h2o by default uses an older (but more stable) version, which is 2.2.7.
Why? Say for example the latest LibreSSL version has support for some feature we need. This will allow it. Now we could get the package and modify it, keep it updated, and all that fun (not!). Instead, we will tell customizepkg to change PKGBUILD to fit our needs (well, wants).
First, get the h20 PKGBUILD and h2o archive:
curl 'https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=h2o' -o PKGBUILD
curl 'https://codeload.github.com/h2o/h2o/tar.gz/v2.0.1' -o h2o-2.0.1.tar.gz
Inspecting the h2o archive we find that the libressl-2.2.7.tar.gz file is stored in the misc
folder, and there’s a libressl.mk
file that controls the version that the h2o compiler/configuration scripts look for:
[user]$ ls ./misc/libressl*
./misc/libressl.mk
./misc/libressl-2.2.7.tar.gz
[user]$ grep VERSION ./misc/libressl.mk
VERSION=2.2.7
So we need to change those, adding the libressl-2.4.2.tar.gz to the misc folder, and replacing the VERSION with 2.4.2
In short, we need a PKGBUILD that specifies the archive url (and save location), and a sed to replace the VERSION.
# PKGBUILD for h2o
...
arch=('i686' 'x86_64')
libressl_ver=2.4.2
libressl_hash='5f87d778e5d62822d60e38fa9621c1c5648fc559d198ba314bd9d89cbf67d9e3'
...
source=(....
$srcdir/misc/libressl-${libressl_ver}.tar.gz::http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-${libressl_ver}.tar.gz
...
sha256sums=(...
${libressl_hash} # <-- I put up as a variable as I kept on forgetting to update it.
...
build() {
cd "$srcdir/$pkgname-$pkgver"
sed -i 's/VERSION=.*/VERSION='${libressl_ver}'/' ./misc/libressl.mk
mv ../libressl-${libressl_ver}.tar.gz ./misc/
...
Now back to our /etc/customizepkg/h2o
file. Let’s get the version and hash in it:
addline#global#arch\s*=\s*(#libressl_ver=2.4.2
addline#global#arch\s*=\s*(#libressl_hash='5f87d778e5d62822d60e38fa9621c1c5648fc559d198ba314bd9d89cbf67d9e3'
We need the sed/mv after the cd "$srcdir/$pkgname-$pkgver"
in the build section, so that’s:
addline#build#cd "*$srcdir/$pkgname-$pkgver"*#sed -i 's/VERSION=.*/VERSION='${libressl_ver}'/' ./misc/libressl.mk\nmv ../libressl-${libressl_ver}.tar.gz ./misc/
And then we need the source and sha256sum:
addline#global#source\s*=\s*(#http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-${libressl_ver}.tar.gz
addline#global#sha256sums\s*=\s*(.*#${libressl_hash}
Remember that’s ACTION # CONTEXT # PATTERN # VALUE
. We are adding lines here, in the global and build contexts. It’s looking for source or sha256sum and placing a line under the found items. And I chose source
and sha256sums` because they will always show, and adding a line under then will always match.
We could have also just used replace
to put them as the first source. It’s all the same.
replace#global#source\s*=\s*(#source=(http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-${libressl_ver}.tar.gz\n
replace#global#sha256sums\s*=\s*(#sha256sums=(${libressl_hash}\n
And yes, the source\s*=\s*(
is in case the package maintainer decides to put spaces in.
Once run, you will get
[user]$ h2o --version
h2o version 2.0.1
OpenSSL: LibreSSL 2.4.1
mruby: YES
Example: Enable OpenSSL via an Executable Script
Now we talked about how you could make your /etc/customizepkg/$PACKAGENAME
script executable, and it would run it, right? Well let’s do that here (even though it’s not needed. It just helps to see it work).
Set your etc/customizepkg/h2o
to:
#!/bin/bash
sed 's/-DWITH_BUNDLED_SSL=on/-DWITH_BUNDLED_SSL=off/g' < $1 > $2
As you can see, we are using sed again to disable the bundled ssl.
- $1 is the original PKGBUILD
- $2 is the custom PKGBUILD
Be sure to remove any files in /etc/customizepkg/h2o.files
. They seemed to want to run rather than be included. But your mileage may vary.
Set the script to execute:
chmod +x /etc/customizepkg.d/h2o
Install it and it will change the options so it uses OpenSSL.
yaourt -Sy h2o
Adding Files
You can also add files to the /etc/customizepkg/$PACKAGENAME.files/
and then call then from your config file. For example, to add the patch file file.patch
, add this to your /etc/customizepkg/$PACKAGENAME
file
patch#pkgbuild#file.patch
and then save your patch file as /etc/customizepkg/$PACKAGENAME.files/file.patch
This can be useful in adding patches, or extra files.
Example: Patching the Source Code
Yes, that’s right, we can patch the source code before building the source code. This is really useful if the source code is failing to build and there’s a patch for it, or if there’s a security issue that hasn’t been fixed yet, or you just really want to do some awesome thing to make the program even better.
In this case, let’s change the h2o name and it’s version number to something awesome, like ‘h2o, the blazing web server on a surf board, version 5000’!
Warning
Don’t modify the source code of a program on a production machine unless you know what you’re doing! I’m just having some fun while showing you how to use customizepkg to do so. You have been warned!
So make your patch file as /etc/customizepkg/h2o.files/blazing-h2o.patch
with the following. Note that this patch may not work, as code does change. Especially the second part where we add to the software name. It would be better to run and executable or replace
option. But it’s just an example.
--- old/version.h.in 2016-06-23 17:04:34.000000000 -0600
+++ new/version.h.in 2016-08-01 20:20:40.523633395 -0600
@@ -22,7 +22,7 @@
#ifndef h2o__version_h
#define h2o__version_h
-#define H2O_VERSION "@VERSION@"
+#define H2O_VERSION "5000"
#define H2O_VERSION_MAJOR @VERSION_MAJOR@
#define H2O_VERSION_MINOR @VERSION_MINOR@
--- old/src/main.c 2016-06-23 17:04:34.000000000 -0600
+++ new/src/main.c 2016-08-01 20:20:40.523633395 -0600
@@ -1597,7 +1597,7 @@
conf.run_mode = RUN_MODE_TEST;
break;
case 'v':
- printf("h2o version " H2O_VERSION "\n");
+ printf("h2o, the blazing web server on a surf board, version " H2O_VERSION "\n");
printf("OpenSSL: %s\n", SSLeay_version(SSLEAY_VERSION));
#if H2O_USE_MRUBY
printf(
@@ -1605,7 +1605,7 @@
#endif
exit(0);
case 'h':
- printf("h2o version " H2O_VERSION "\n"
+ printf("h2o, the blazing web server on a surf board, version " H2O_VERSION "\n"
"\n"
"Usage:\n"
" h2o [options]\n"
And add this to your config file /etc/customizepkg/h2o
patch#1#blazing-h2o.patch
When you run it will show:
-source=($pkgname-$pkgver.tar.gz::https://codeload.github.com/h2o/$pkgname/tar.gz/v$pkgver
+source=('blazing-h2o.patch' $pkgname-$pkgver.tar.gz::https://codeload.github.com/h2o/$pkgname/tar.gz/v$pkgver
-sha256sums=('c53d11589c8c76491cf3a940b649d0a9cb27c36eb276963811ac1bc16cd2bf2c'
+sha256sums=('edb73a2d5797a707a28c54f1147c3805bcb40e5683a370b4d4f1998aba2275ed'
'c53d11589c8c76491cf3a940b649d0a9cb27c36eb276963811ac1bc16cd2bf2c'
+patch -Np1 -i blazing-h2o.patch
as it’s adding the patch file to the PKGBUILD sources, sha256sums, and the build where it will run.
So now run it:
yaourt -Sy h2o
And it will error out (Now you’re thinking “Hey, you broke it!” but I’m going to show you how to fix it.)
==> Starting build()...
patch: **** Can't open patch file blazing-h2o.patch : No such file or directory
==> ERROR: A failure occurred in build().
Aborting...
What is happening is it’s inputting the patching after it changes to the h2o source directory. But the patch is above the directory.
# from the PKGBUILD:
cd "$srcdir/$pkgname-$pkgver"
patch -Np1 -i blazing-h2o.patch
# but the path to the patch is ../blazing-h2o.patch
So to fix it, we’ll just add a little replace
to /etc/customizepkg/h2o
under our patch line:
patch#1#blazing-h2o.patch
replace#build#blazing-h2o.patch#../blazing-h2o.patch
See, not too hard. And this won’t always be needed. That’s why I showed you how I fixed it.
And now it should build just fine. If you take a look at the output, you’ll see:
--- ./PKGBUILD
+++ ./PKGBUILD.custom
@@ -12,9 +12,9 @@
makedepends=('cmake' 'libtool' 'make' 'pkg-config' 'ruby')
url="https://github.com/h2o/h2o"
license=('MIT')
-source=($pkgname-$pkgver.tar.gz::https://codeload.github.com/h2o/$pkgname/tar.gz/v$pkgver
+source=('blazing-h2o.patch' $pkgname-$pkgver.tar.gz::https://codeload.github.com/h2o/$pkgname/tar.gz/v$pkgver
h2o.service)
-sha256sums=('c53d11589c8c76491cf3a940b649d0a9cb27c36eb276963811ac1bc16cd2bf2c'
+sha256sums=('99c0ce5c6b62becac6dc0584c9c2b81b598242eacd1b93385ceeab7c16904811'
'c53d11589c8c76491cf3a940b649d0a9cb27c36eb276963811ac1bc16cd2bf2c'
'8a85462b6798deaaab343b5dae73437e251c5018d70d260a4a4440b9bbb053e6')
backup=('etc/h2o.conf')
provides=('h2o' 'libh2o')
@@ -22,6 +22,7 @@
build() {
cd "$srcdir/$pkgname-pkgver"
+patch -Np1 -i ../blazing-h2o.patch
...
==> Starting build()...
patching file version.h.in
patching file src/main.c
-> Building...
So you know it’s doing its job.
And now, it should show:
[user]$ h2o --version
h2o, the blazing web server on a surf board, version 5000
...
Example: Enable OpenSSL via a patch to PKGBUILD
Say we just want to have apply a simple patch to the PKGBUILD. You probably shouldn’t do this, but I put it here for completeness.
Patches are specified in the file:
patch#pkgbuild#file.patch
We can use our patch earlier:
--- ./PKGBUILD
+++ ./PKGBUILD.custom
@@ -26,7 +26,6 @@
msg2 'Building...'
cmake \
-DCMAKE_INSTALL_PREFIX=/usr \
- -DWITH_BUNDLED_SSL=on \
-DWITH_MRUBY=on \
.
make
Place that in our /etc/customizepkg/h2o.files
directory:
/etc/customizepkg.d/h2o.files/openssl-enable.patch
Then add this to /etc/customizepkg/h2o
:
patch#pkgbuild#openssl-enable.patch
When you run it you’ll see:
--- ./PKGBUILD
+++ ./PKGBUILD.custom
@@ -12,9 +12,9 @@
makedepends=('cmake' 'libtool' 'make' 'pkg-config' 'ruby')
url="https://github.com/h2o/h2o"
license=('MIT')
-source=($pkgname-$pkgver.tar.gz::https://codeload.github.com/h2o/$pkgname/tar.gz/v$pkgver
+source=('openssl.patch' $pkgname-$pkgver.tar.gz::https://codeload.github.com/h2o/$pkgname/tar.gz/v$pkgver
h2o.service)
-sha256sums=('c53d11589c8c76491cf3a940b649d0a9cb27c36eb276963811ac1bc16cd2bf2c'
+sha256sums=('99c0ce5c6b62becac6dc0584c9c2b81b598242eacd1b93385ceeab7c16904811'
'c53d11589c8c76491cf3a940b649d0a9cb27c36eb276963811ac1bc16cd2bf2c'
'8a85462b6798deaaab343b5dae73437e251c5018d70d260a4a4440b9bbb053e6')
And once again OpenSSL will be found and used.
Make sure you chmod -x after you are done with this example, unless you plan to keep it.
Click here to visit the author’s site for more examples.
Conclusion
This program is a fantastic find! While browsing the AUR sometimes I see people posting comments about how they want some package to support this or do that. If only they knew what they could already do! I mean, yes, you can do this already with a PKGBUILD and makepkg
, but with this you can build off of what someone else has already done, and make your customizations. It really allows you to customize your installs in a really great way, like Gentoo but without the need to do so with the whole system. (Gentoo, you guys are awesome too!)