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 dependencies.
  • 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