aboutsummaryrefslogtreecommitdiffstats
path: root/meson/docs/markdown/Creating-Linux-binaries.md
diff options
context:
space:
mode:
Diffstat (limited to 'meson/docs/markdown/Creating-Linux-binaries.md')
-rw-r--r--meson/docs/markdown/Creating-Linux-binaries.md133
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`.