-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCreating-Linux-binaries.html
350 lines (310 loc) · 13 KB
/
Creating-Linux-binaries.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
<!DOCTYPE html>
<html lang="en">
<head>
<base href=".">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Creating Linux binaries</title>
<link rel="stylesheet" href="assets/css/dark-frontend.css" type="text/css" title="dark">
<link rel="alternate stylesheet" href="assets/css/light-frontend.css" type="text/css" title="light">
<link rel="stylesheet" href="assets/css/bootstrap-toc.min.css" type="text/css">
<link rel="stylesheet" href="assets/css/jquery.mCustomScrollbar.min.css">
<link rel="stylesheet" href="assets/js/search/enable_search.css" type="text/css">
<link rel="stylesheet" href="assets/css/prism-tomorrow.css" type="text/css" title="dark">
<link rel="alternate stylesheet" href="assets/css/prism.css" type="text/css" title="light">
<script src="assets/js/mustache.min.js"></script>
<script src="assets/js/jquery.js"></script>
<script src="assets/js/bootstrap.js"></script>
<script src="assets/js/scrollspy.js"></script>
<script src="assets/js/typeahead.jquery.min.js"></script>
<script src="assets/js/search.js"></script>
<script src="assets/js/compare-versions.js"></script>
<script src="assets/js/jquery.mCustomScrollbar.concat.min.js"></script>
<script src="assets/js/bootstrap-toc.min.js"></script>
<script src="assets/js/jquery.touchSwipe.min.js"></script>
<script src="assets/js/anchor.min.js"></script>
<script src="assets/js/tag_filtering.js"></script>
<script src="assets/js/language_switching.js"></script>
<script src="assets/js/styleswitcher.js"></script>
<script src="assets/js/lines_around_headings.js"></script>
<script src="assets/js/prism-core.js"></script>
<script src="assets/js/prism-autoloader.js"></script>
<script src="assets/js/prism_autoloader_path_override.js"></script>
<script src="assets/js/prism-keep-markup.js"></script>
<script src="assets/js/trie.js"></script>
<link rel="icon" type="image/png" href="assets/images/favicon.png">
<link rel="shortcut icon" href="assets/images/favicon.png">
</head>
<body class="no-script
">
<script>
$('body').removeClass('no-script');
</script>
<nav class="navbar navbar-fixed-top navbar-default" id="topnav">
<div class="container-fluid">
<div class="navbar-right">
<a id="toc-toggle">
<span class="glyphicon glyphicon-menu-right"></span>
<span class="glyphicon glyphicon-menu-left"></span>
</a>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-wrapper" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span title="light mode switch" class="glyphicon glyphicon-sunglasses pull-right" id="lightmode-icon"></span>
<form class="navbar-form pull-right" id="navbar-search-form">
<div class="form-group has-feedback">
<input type="text" class="form-control input-sm" name="search" id="sidenav-lookup-field" placeholder="search" disabled>
<span class="glyphicon glyphicon-search form-control-feedback" id="search-mgn-glass"></span>
</div>
</form>
</div>
<div class="navbar-header">
<a id="sidenav-toggle">
<span class="glyphicon glyphicon-menu-right"></span>
<span class="glyphicon glyphicon-menu-left"></span>
</a>
<a id="home-link" href="index.html" class="hotdoc-navbar-brand">
<img src="assets/images/meson_logo.png" alt="Home">
</a>
</div>
<div class="navbar-collapse collapse" id="navbar-wrapper">
<ul class="nav navbar-nav" id="menu">
<li class="dropdown">
<a class="dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Modules <span class="caret"></span>
</a>
<ul class="dropdown-menu" id="modules-menu">
<li>
<a href="CMake-module.html">CMake</a>
</li>
<li>
<a href="Cuda-module.html">CUDA</a>
</li>
<li>
<a href="Dlang-module.html">Dlang</a>
</li>
<li>
<a href="External-Project-module.html">External Project</a>
</li>
<li>
<a href="Fs-module.html">Filesystem</a>
</li>
<li>
<a href="Gnome-module.html">GNOME</a>
</li>
<li>
<a href="Hotdoc-module.html">Hotdoc</a>
</li>
<li>
<a href="i18n-module.html">i18n</a>
</li>
<li>
<a href="Icestorm-module.html">Icestorm</a>
</li>
<li>
<a href="Java-module.html">Java</a>
</li>
<li>
<a href="Keyval-module.html">Keyval</a>
</li>
<li>
<a href="Pkgconfig-module.html">Pkgconfig</a>
</li>
<li>
<a href="Python-3-module.html">Python 3</a>
</li>
<li>
<a href="Python-module.html">Python</a>
</li>
<li>
<a href="Qt4-module.html">Qt4</a>
</li>
<li>
<a href="Qt5-module.html">Qt5</a>
</li>
<li>
<a href="Qt6-module.html">Qt6</a>
</li>
<li>
<a href="Rust-module.html">Rust</a>
</li>
<li>
<a href="Simd-module.html">Simd</a>
</li>
<li>
<a href="SourceSet-module.html">SourceSet</a>
</li>
<li>
<a href="Wayland-module.html">Wayland</a>
</li>
<li>
<a href="Windows-module.html">Windows</a>
</li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Quick References <span class="caret"></span>
</a>
<ul class="dropdown-menu" id="quick-refs-menu">
<li>
<a href="Reference-manual.html">Functions</a>
</li>
<li>
<a href="Build-options.html">Options</a>
</li>
<li>
<a href="Configuration.html">Configuration</a>
</li>
<li>
<a href="Dependencies.html">Dependencies</a>
</li>
<li>
<a href="Unit-tests.html">Tests</a>
</li>
<li>
<a href="Syntax.html">Syntax</a>
</li>
</ul>
</li>
</ul>
<div class="hidden-xs hidden-sm navbar-text navbar-center">
<p><b>The Meson Build System</b></p>
</div>
</div>
</div>
</nav>
<main>
<div data-extension="core" data-hotdoc-in-toplevel="True" data-hotdoc-project="Meson-documentation" data-hotdoc-ref="Creating-Linux-binaries.html" class="page_container" id="page-wrapper">
<script src="assets/js/utils.js"></script>
<div class="panel panel-collapse oc-collapsed" id="sidenav" data-hotdoc-role="navigation">
<script src="assets/js/full-width.js"></script>
<div id="sitenav-wrapper">
<iframe src="hotdoc-sitemap.html" id="sitenav-frame"></iframe>
</div>
</div>
<div id="body">
<div id="main">
<div id="page-description" data-hotdoc-role="main">
<h1 id="creating-linux-binaries">Creating Linux binaries</h1>
<p>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.</p>
<h2 id="installing-system-and-gcc">Installing system and GCC</h2>
<p>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 <em>at least as old</em> 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.</p>
<p>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:</p>
<pre><code class="language-console">$ apt-get build-dep g++
$ apt-get install pkg-config libgmp-dev libmpfr-dev libmpc-dev
</code></pre>
<p>Then create a <code>src</code> subdirectory in your home directory. Copy-paste
the following into <code>install_gcc.sh</code> and execute it.</p>
<pre><code class="language-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
</code></pre>
<p>Then finally add the following lines to your <code>.bashrc</code>.</p>
<pre><code class="language-console">$ export LD_LIBRARY_PATH=${HOME}/devroot/lib
$ export PATH=${HOME}/devroot/bin:$PATH
$ export PKG_CONFIG_PATH=${HOME}/devroot/lib/pkgconfig
</code></pre>
<p>Log out and back in and now your build environment is ready to use.</p>
<h2 id="adding-other-tools">Adding other tools</h2>
<p>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 <code>~/devroot</code> in the usual
way.</p>
<h2 id="adding-dependencies">Adding dependencies</h2>
<p>You want to embed and statically link every dependency you can
(especially C++ dependencies). Meson's <a href="Wrap-dependency-system-manual.html">Wrap package
manager</a> 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, <code>./configure --prefix=${HOME}/devroot</code>). This makes
Meson's dependency detector pick it up automatically.</p>
<h2 id="building-and-installing">Building and installing</h2>
<p>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:</p>
<pre><code class="language-console">$ LDFLAGS=-static-libstdc++ meson --prefix=/tmp/myapp <other args>
</code></pre>
<p>The aim is to put the executable in <code>/tmp/myapp/bin</code> and shared
libraries to <code>/tmp/myapp/lib</code>. The next thing you need is the
embedder. It takes your dependencies (in this case only
<code>libSDL2-2.0.so.0</code>) 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 <code>ldd binary_file</code>. Be sure not to copy
system libraries (<code>libc</code>, <code>libpthread</code>, <code>libm</code> etc). For an example,
see the <a href="https://github.com/jpakkane/meson/tree/master/manual%20tests/4%20standalone%20binaries">sample
project</a>.</p>
<p>Make the script run during install with this:</p>
<pre><code class="language-meson"><a href="Reference-manual_builtin_meson.html#mesonadd_install_script"><ins>meson.add_install_script</ins></a>('linux_bundler.sh')
</code></pre>
<h2 id="final-steps">Final steps</h2>
<p>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 <code>lib</code> directory. The solution for
this is a simple wrapper script. Create a script called <code>myapp.sh</code>
with the following content:</p>
<pre><code class="language-bash">#!/bin/bash
cd "${0%/*}"
export LD_LIBRARY_PATH="$(pwd)/lib"
bin/myapp
</code></pre>
<p>Install it with this Meson snippet:</p>
<pre><code class="language-meson"><a href="Reference-manual_functions.html#install_data"><ins>install_data</ins></a>('myapp.sh', install_dir : '.')
</code></pre>
<p>And now you are done. Zip up your <code>/tmp/myapp</code> directory and you have
a working binary ready for deployment. To run the program, just unzip
the file and run <code>myapp.sh</code>.</p>
</div>
</div>
<div id="search_results">
<p>The results of the search are</p>
</div>
<div id="footer">
<hr>
<div class="license-description">
Website licensing information are available on the <a href="legal.html">Legal</a> page.
</div>
</div>
</div>
<div id="toc-column">
<div class="edit-button">
<a href="https://github.com/mesonbuild/meson/edit/master/docs/markdown/Creating-Linux-binaries.md" data-hotdoc-role="edit-button">Edit on GitHub</a>
</div>
<div id="toc-wrapper">
<nav id="toc"></nav>
</div>
</div>
</div>
</main>
<script src="assets/js/navbar_offset_scroller.js"></script>
</body>
</html>