Building static binaries on Linux

Windows experience

Most people using Windows knows nothing about dependency hell.

It is because Windows comes with a lot of standard dynamic link libraries (dll files) out of the box. It also seems that they don’t change as much from version to version so there are less (just a guess) compatibility issues on different Windows versions. Or maybe they all are outdated and full of bugs. In any case, it is usually easy to move binaries around from computer to computer without any problems.

Linux experience

It is a whole different picture on Linux.

Even though there are some libraries that will most likely be on most Linux systems, lots of applications require additional libraries that are probably not installed by default. And even if it seems that you have all the necessary libraries there is a big chance that they won’t be compatible with your binary because those libraries tend to change a lot between different versions.

Most of the time it won’t be a problem because maintainers of each distribution solve this by giving users tools to install necessary dependencies built for each specific program.

But what should you do when you don’t have that much time to compile hundreds of libraries for each distribution, version and architecture you are targeting? Or you simply don’t have the necessary permissions to install required packages using your distribution’s package manager and you don’t want to go through dependency hell on a limited user.

Build it statically!

It of course has it’s pros and cons but depending on what you are trying to achieve this could ease your life.

“Static hell”

Unless you have a trivial application it won’t be as easy as adding “-static” to your compiler’s argument list.

You will probably have to specify some libraries that it should statically link against at compile time. And those libraries probably also require other static libraries. You get a whole different dependency hell.

And when you finally track down every library needed you find out that glibc is huge and will not play nice. 🙂 Yay!

Bifrost uClibc build environment

One way of solving this would be using uClibc chroot environment for architecture that works on most desktops, server and laptops out there.

I did try some other light glibc  alternatives and build environments but came to conclusion that uClibc is great and works. I found that there is a Linux distribution named “Bifrost” that uses uClibc. The creators of it provide build scripts and instructions to set up your own bifrost build i586 and x86_64 environment. I also made a fork of it on Github and use it from time to time.

Building almost anything using this environment makes building static binaries a piece of cake. And building it for i586 makes those binaries quite portable.

I haven’t tried building any GUI tools (why would I?) but I’ve successfully built applications like git, tmux, lighttpd, php, rtorrent, perl, python, etc.

Also at the time of writing this post, Bifrost doesn’t support ARM (I guess it is not the purpose of it) but that shouldn’t be a problem because there are lots of articles and info on making uClibc build environments for ARM.

Jailkit, mini_sendmail and custom HELO

To be sure that a server stays safe in case when one site is compromised, I try to lock every single site in its own chroot jail. To make it a bit easier I use Jailkit.

Since you probably don’t want to set up sendmail for each chroot, you could use mini_sendmail. It will work as relay and will pass messages to actual sendmail.

The problem is that there is no way to specify a custom username or hostname and this could be quite important in some cases.

In order to solve this problem I did some quick and dirty modifications and here is the patch in case you need it:

Save it as some.patch. Move it inside mini_sendmail source directory and run:

You can specify username with -u and hostname (and HELO message) with -h parameter.

If you are going to use it with PHP, change sendmail_path in php.ini to something like this:

This should make php connect to sendmail running on port 5555 and send as HELO and noreply as username.

Patch was made for version 1.3.6.