diff options
Diffstat (limited to 'meson/docs/markdown/Creating-Linux-binaries.md')
-rw-r--r-- | meson/docs/markdown/Creating-Linux-binaries.md | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/meson/docs/markdown/Creating-Linux-binaries.md b/meson/docs/markdown/Creating-Linux-binaries.md new file mode 100644 index 000000000..71c96e470 --- /dev/null +++ b/meson/docs/markdown/Creating-Linux-binaries.md @@ -0,0 +1,133 @@ +--- +short-description: Creating universal Linux binaries +... + +# Creating Linux binaries + +Creating Linux binaries that can be downloaded and run on any distro +(like .dmg packages for OSX or .exe installers for Windows) has +traditionally been difficult. This is even more tricky if you want to +use modern compilers and features, which is especially desired in game +development. There is still no simple turn-key solution for this +problem but with a bit of setup it can be relatively straightforward. + +## Installing system and GCC + +First you need to do a fresh operating system install. You can use +spare hardware, VirtualBox, cloud or whatever you want. Note that the +distro you install must be *at least as old* as the oldest release you +wish to support. Debian stable is usually a good choice, though +immediately after its release you might want to use Debian oldstable +or the previous Ubuntu LTS. The oldest supported version of CentOS is +also a good choice. + +Once you have installed the system, you need to install +build-dependencies for GCC. In Debian-based distros this can be done +with the following commands: + +```console +$ apt-get build-dep g++ +$ apt-get install pkg-config libgmp-dev libmpfr-dev libmpc-dev +``` + +Then create a `src` subdirectory in your home directory. Copy-paste +the following into `install_gcc.sh` and execute it. + +```bash +#!/bin/sh + +wget ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.9.2/gcc-4.9.2.tar.bz2 +tar xf gcc-4.9.2.tar.bz2 + +mkdir objdir +cd objdir +../gcc-4.9.2/configure --disable-bootstrap --prefix=${HOME}/devroot \ + --disable-multilib --enable-languages=c,c++ +make -j 4 +make install-strip +ln -s gcc ${HOME}/devroot/bin/cc +``` + +Then finally add the following lines to your `.bashrc`. + +```console +$ export LD_LIBRARY_PATH=${HOME}/devroot/lib +$ export PATH=${HOME}/devroot/bin:$PATH +$ export PKG_CONFIG_PATH=${HOME}/devroot/lib/pkgconfig +``` + +Log out and back in and now your build environment is ready to use. + +## Adding other tools + +Old distros might have too old versions of some tools. For Meson this +could include Python 3 and Ninja. If this is the case you need to +download, build and install new versions into `~/devroot` in the usual +way. + +## Adding dependencies + +You want to embed and statically link every dependency you can +(especially C++ dependencies). Meson's [Wrap package +manager](Wrap-dependency-system-manual.md) might be of use here. This +is equivalent to what you would do on Windows, OSX, Android etc. +Sometimes static linking is not possible. In these cases you need to +copy the .so files inside your package. Let's use SDL2 as an example. +First we download and install it as usual giving it our custom install +prefix (that is, `./configure --prefix=${HOME}/devroot`). This makes +Meson's dependency detector pick it up automatically. + +## Building and installing + +Building happens in much the same way as normally. There are just two +things to note. First, you must tell GCC to link the C++ standard +library statically. If you don't then your app is guaranteed to break +as different distros have binary-incompatible C++ libraries. The +second thing is that you need to point your install prefix to some +empty staging area. Here's the Meson command to do that: + +```console +$ LDFLAGS=-static-libstdc++ meson --prefix=/tmp/myapp <other args> +``` + +The aim is to put the executable in `/tmp/myapp/bin` and shared +libraries to `/tmp/myapp/lib`. The next thing you need is the +embedder. It takes your dependencies (in this case only +`libSDL2-2.0.so.0`) and copies them in the lib directory. Depending on +your use case you can either copy the files by hand or write a script +that parses the output of `ldd binary_file`. Be sure not to copy +system libraries (`libc`, `libpthread`, `libm` etc). For an example, +see the [sample +project](https://github.com/jpakkane/meson/tree/master/manual%20tests/4%20standalone%20binaries). + +Make the script run during install with this: + +```meson +meson.add_install_script('linux_bundler.sh') +``` + +## Final steps + +If you try to run the program now it will most likely fail to start or +crashes. The reason for this is that the system does not know that the +executable needs libraries from the `lib` directory. The solution for +this is a simple wrapper script. Create a script called `myapp.sh` +with the following content: + +```bash +#!/bin/bash + +cd "${0%/*}" +export LD_LIBRARY_PATH="$(pwd)/lib" +bin/myapp +``` + +Install it with this Meson snippet: + +```meson +install_data('myapp.sh', install_dir : '.') +``` + +And now you are done. Zip up your `/tmp/myapp` directory and you have +a working binary ready for deployment. To run the program, just unzip +the file and run `myapp.sh`. |