Once every week or so, you have a problem that you know is solvable but it’s taking time and it’s frustrating.

Building PHP5

A while ago I tried my hands on porting the Debian packages for PHP 5.3.2 to lenny and squeeze. I shouldn’t have been doing that, because there are more important things to do, but hey, it’s was friday and believe it or not, it’s a relaxing process 🙂 And we had to figure out a way to start the migration for 22k websites from PHP 5.2 to PHP5.3 without hundreds of sites suddenly stopping. So we’ll need that package at some point!

So the building process normally works well, because we keep PHP in a git repository and the Debian toolchain is very easy to use (once you understand all these tools):

  1. PHP5 is kept in git and maintained by git-buildpackage scripts:
    1. git-import-dsc is used to import new Debian packages that are released
    2. git is then used to rebase all byte branches to the new Debian branch. This is where the menial labor is involved 🙂
    3. git-dch is used to keep a changelog of all the changes automatically
    4. git-buildpackage is used to build the package correctly.
    5. The advantage: no more copying around orig.tar.gz files normally needed to build
  2. git-buildpackage is used to build the package correctly.
  3. git-buildpackage calls git-pbuilder, written by open-source veteran Russ Allbery
  4. git-pbuilder calls cowbuilder
  5. cowbuilder maintains a clean build environment for me, installs build dependencies, cleans them up and keeps things efficient 🙂

So this used to work really well for us at Byte. Until the Debian maintainers for PHP5 added a patch. This happens once in a while and every techie in the world knows this: an obscure bug!

Trouble arrives

Everything worked fine until the Debian maintainers for PHP5 added a patch named dont-gitclean-in-build.patch. Suddenly the package wouldn’t build. All builds failed at the point of applying the new patch and the builds wouldn’t continue.

I spent about two hours trying to find the glitch that caused this. To no avail. Until I decided to look deeper into the cluster of shell commands were used to build a Debian package 🙂

  1. git-pbuilder at some point calls pdebuild with options
  2. pdebuild calls cowbuilder with the same options
  3. cowbuilder calls dpkg-buildpackage with abocve options
  4. dpkg-buildpackage calls dpkg-source -b to create a clean source tarball with which to build, passes on options
  5. dpkg-source gets called with -b, and normally with -i\.git -I.git to make it ignore .git directories

Note the slash 🙂

However, in my build log, there is no slash.

Now the hunt starts 🙂

Bash escaping

Anyone who’s coded bash in his/her life will know the hell that is called bash escaping. Every command adds a new layer of escaping until code looks really rediculous 🙂

So looking at the command chain above, the options that git-pbuilder passes on are then passed on two more times. That causes problems:

pdebuild –buildresult .. –pbuilder cowbuilder \
–debbuildopts “-i\.git -I.git $*” — –basepath “$BASE” $OPTIONS

It’s now obvious to me that the slash got lost in translation. This caused the -i argument (which is a regexp) to match dont-gitclean instead of only .git. Changing it to four slashes solved the problem:

pdebuild –buildresult .. –pbuilder cowbuilder \
–debbuildopts “-i\\\\.git -I.git $*” — –basepath “$BASE” $OPTIONS

There. Done, the build is ready 🙂

Maybe this blogpost will save someone a nice, sunny friday afternoon 🙂

Scan je eigen Magento shop op veiligheidslekken