Clone wiki

speedcrunch / BuildingLinuxPackages

Building Generic Linux Binary Packages

The Linux binary packages are built in a controlled, relatively old environment
and include their own copy of Qt to maximise compatibility. Currently, that environment is:

The necessary scripts and a Vagrantfile (see are in pkg/cross-linux.
Using Vagrant is not strictly necessary. You can just bring your own minimal CentOS 6 installation or use e.g. Docker instead,
but you'll have to adjust some paths in the scripts.


You only need to perform these steps once, when creating or updating the build environment.
Note that these steps will download several GB of files and the resulting VM will
consume ~12 GB of disk space.

  1. (optional) Edit Vagrantfile to assign more cores to the VM.
  2. Run vagrant up to set up the VM. This also runs the and
    scripts to set up the environment. If you don't use Vagrant, you'll have to run those
    scripts manually.
  3. Run vagrant ssh to log into the VM (or use
    vagrant-multi-putty on Windows).
  4. Run sh /vagrant/ to build Qt. Note that this can take a long time, depending
    on your CPU and the number of cores you assigned to the VM.

Build the Packages

So long as the build environment is set up as described above, the following steps
will generate the binary packages:

  1. Edit the RELEASE_VERSION=... line in; this is used for the
    package version.
  2. In the VM, run sh /vagrant/

The final packages can be found in pkg/cross-linux/dist. Six packages will be created:
deb, rpm and a tarball for x86 and amd64 each.

Updating the Build Environment

When modifying the build environment (OS, toolchain, dependencies or Qt version), keep
these points in mind:

  • Building on an old Linux distribution increases binary compatibility with older libc,
    libstdc++ and libgcc_s versions. In general, pick the oldest distribution that can provide all the required
  • Always try to install as few additional library devel packages as possible.
    This minimizes the danger of unintended dependencies.
  • Similarly, in the Qt build, use as many bundled libraries as possible or omit
    some features entirely, if acceptable (SpeedCrunch doesn't currently need OpenGL, for instance).
  • Go conservative on the optimizations. Currently, the Qt build sticks to SSE2.
  • When given the choice between directly linking to a shared library, dlopen()ing a shared
    library at runtime, or not including a feature, prefer dlopen() if the library is
    actually optional. However, if it isn't (e.g. libdbus which is required for
    accessibility), make the dependency explicit.
  • Sanity-check the library dependencies of the final speedcrunch binaries using
    readelf -d. This lists only the shared libraries that the binary links to; ldd
    will also list transitive library dependencies.
  • As necessary, update the required packages in pkg/cross-linux/deb-control. This should
    usually be the result of dpkg-shlibdeps on the oldest Debian-based system that
    the binary runs on.

And of course, whenever you make major changes to the process, test the packages on
as many Linux distributions as you can get your hands on.

Further Reading