Making a static build of sox

This is super-technical. Caveat lector.

Sox, “the Swiss Army knife of sound processing programs”, has a jolly useful feature where it can read an audio file and dump out the contents as data; exactly what you need to create a waveform image of an mp3. I needed to do this for a particualr client project; there are a whole bunch of pages explaining how to create a waveform of an mp3 in PHP, and they pretty much all rely on using lame to convert the mp3 to a wav file and then reading and decoding the wav file with PHP. That seems like a waste to me, since I don’t care about the wav file, and sox does precisely what I want.

However, if you’re writing PHP apps, it’s quite possible that you (as I am, for this project) are hosting the web app in some sort of shared hosting environment, which is fairly sharply limited. So what I wanted was a static build of sox; that is, a single binary with the dependencies I need (mp3-reading, primarily) compiled into it. I managed to put together a static Linux binary by (roughly) following the ggkarman instructions (which are for OS X, but that doesn’t matter here). However, once I had said binary, it didn’t run on the hosting environment; I got the error ./sox: /lib/x86_64-linux-gnu/ version GLIBC_2.14 not found (required by ./sox). What this means is that the binary was built against the version of glibc, the system C library on which basically everything depends, that was on the machine I built it on — my Ubuntu 14.04 desktop. The hosting service has an older version of glibc, and so things didn’t work.

At this point I went to ask questions on #ubuntu-uk, and popey said: can’t you just build it in an older version of Linux — say, a Debian wheezy chroot? I said, dunno, can I? And popey, hero of the revolution that he is, had a wheezy chroot lying around the place and so tried it, and it works.

Below is how we built the static binary. There are probably a bunch of complexities in here that will make it work for you; in particular, the web hosting machine was 64-bit and so was popey’s build environment, and if that’s not the case for you then epic fail lies ahead. But it may help.

# First, create a debian wheezy chroot
sudo debootstrap --arch=amd64 wheezy ./wheezy/ \
# enter it, thus
sudo  mount -o bind /dev wheezy/dev
sudo mount -t proc none wheezy/proc
sudo chroot wheezy
cd /tmp # somewhere to do this

# update our debian system, and install libmad, 
# which is what we need for mp3 support in sox
apt-get update
apt-get install build-essential
apt-get install libmad0-dev
apt-get install realpath

# now grab sox and its dependencies
mkdir -p deps
mkdir -p deps/unpacked
mkdir -p deps/built
mkdir -p deps/built/libmad
mkdir -p deps/built/sox
mkdir -p deps/built/lame
wget -O deps/sox-14.4.1.tar.bz2 ""
wget -O deps/libmad-0.15.1b.tar.gz ""
wget -O deps/lame-3.99.5.tar.gz ""

# unpack the dependencies
pushd deps/unpacked
tar xvfpj ../sox-14.4.1.tar.bz2
tar xvfpz ../libmad-0.15.1b.tar.gz
tar xvfpz ../lame-3.99.5.tar.gz

# build libmad, statically
pushd deps/unpacked/libmad-0.15.1b
./configure --disable-shared --enable-static --prefix=$(realpath ../../built/libmad)
# Patch makefile to remove -fforce-mem
sed s/-fforce-mem//g < Makefile > Makefile.patched
cp Makefile.patched Makefile
make install

# build lame, statically
pushd deps/unpacked/lame-3.99.5
./configure --disable-shared --enable-static --prefix=$(realpath ../../built/lame)
make install

# build sox, statically
pushd deps/unpacked/sox-14.4.1
./configure --disable-shared --enable-static --prefix=$(realpath ../../built/sox) \
    LDFLAGS="-L$(realpath ../../built/libmad/lib) -L$(realpath ../../built/lame/lib)" \
    CPPFLAGS="-I$(realpath ../../built/libmad/include) -I$(realpath ../../built/lame/include)" \
    --with-mad --with-lame --without-oggvorbis --without-oss --without-sndfile --without-flac  --without-gomp
make -s
make install

cp deps/built/sox/bin/sox .
rm -rf deps/built
rm -rf deps/unpacked

And now you have a sox binary, which can be used to convert an mp3 to numeric data with sox whatever.mp3 output.dat, and doesn’t need other libraries so you can just drop it into your web hosting and run it with PHP exec(). Hooray.

I'm currently available for hire, to help you plan, architect, and build new systems, and for technical writing and articles. You can take a look at some projects I've worked on and some of my writing. If you'd like to talk about your upcoming project, do get in touch.

More in the discussion (powered by webmentions)

  • (no mentions, yet.)