Linuxバイナリの作成

Linuxバイナリを作成し、あらゆるディストリビューションでダウンロードして実行できるようにする(OSXの.dmgパッケージやWindowsの.exeインストーラーのように)ことは、従来は困難でした。これは、特にゲーム開発で望まれる最新のコンパイラと機能を使用したい場合はさらに難しくなります。この問題に対するシンプルなターンキーソリューションはまだありませんが、少し設定すれば比較的簡単になります。

システムとGCCのインストール

まず、オペレーティングシステムの新規インストールが必要です。予備のハードウェア、VirtualBox、クラウドなど、何でも使用できます。インストールするディストリビューションは、サポートしたい最も古いリリースと同等以上に古い必要があることに注意してください。Debian stableは通常、良い選択ですが、リリース直後はDebian oldstableまたは前のUbuntu LTSを使用することもできます。CentOSのサポートされている最も古いバージョンも良い選択です。

システムをインストールしたら、GCCのビルド依存関係をインストールする必要があります。Debianベースのディストリビューションでは、次のコマンドで実行できます

$ apt-get build-dep g++
$ apt-get install pkg-config libgmp-dev libmpfr-dev libmpc-dev

次に、ホームディレクトリにsrcサブディレクトリを作成します。次の内容をinstall_gcc.shにコピー&ペーストして実行します。

#!/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

最後に、次の行を.bashrcに追加します。

$ export LD_LIBRARY_PATH=${HOME}/devroot/lib
$ export PATH=${HOME}/devroot/bin:$PATH
$ export PKG_CONFIG_PATH=${HOME}/devroot/lib/pkgconfig

ログアウトして再度ログインすると、ビルド環境を使用する準備が整います。

その他のツールの追加

古いディストリビューションでは、一部のツールのバージョンが古すぎる場合があります。Mesonの場合、これにはPython 3とNinjaが含まれる可能性があります。この場合、通常の方法で、新しいバージョンをダウンロード、ビルド、および~/devrootにインストールする必要があります。

依存関係の追加

できる限りすべての依存関係を埋め込み、静的にリンクする必要があります(特にC++の依存関係)。MesonのWrapパッケージマネージャーがここで役立つ可能性があります。これは、Windows、OSX、Androidなどで実行するのと同等です。場合によっては、静的リンクが不可能な場合があります。このような場合は、パッケージ内に.soファイルをコピーする必要があります。例としてSDL2を使用しましょう。まず、通常どおりダウンロードしてインストールし、カスタムインストールプレフィックス(つまり、./configure --prefix=${HOME}/devroot)を指定します。これにより、Mesonの依存関係検出器が自動的にそれをピックアップします。

ビルドとインストール

ビルドは通常と同じように行われます。注意すべき点は2つだけです。まず、C++標準ライブラリを静的にリンクするようにGCCに指示する必要があります。そうしないと、異なるディストリビューションにはバイナリ互換性のないC++ライブラリがあるため、アプリが確実に壊れます。2番目の点は、インストールプレフィックスを空のステージング領域に指定する必要があることです。それを行うためのMesonコマンドを次に示します。

$ LDFLAGS=-static-libstdc++ meson --prefix=/tmp/myapp <other args>

目標は、実行可能ファイルを/tmp/myapp/binに、共有ライブラリを/tmp/myapp/libに配置することです。次に必要なのは、エンベダーです。これにより、依存関係(この場合はlibSDL2-2.0.so.0のみ)を取得し、libディレクトリにコピーします。ユースケースによっては、ファイルを手動でコピーするか、ldd binary_fileの出力を解析するスクリプトを作成できます。システムライブラリ(libclibpthreadlibmなど)をコピーしないように注意してください。例については、サンプルプロジェクトを参照してください。

これをインストール中に実行するスクリプトを作成します。

meson.add_install_script('linux_bundler.sh')

最終手順

プログラムを実行しようとすると、起動に失敗したり、クラッシュしたりする可能性が非常に高いです。この理由は、システムが実行可能ファイルがlibディレクトリのライブラリを必要とすることを認識していないためです。この解決策は、単純なラッパースクリプトです。次の内容でmyapp.shというスクリプトを作成します。

#!/bin/bash

cd "${0%/*}"
export LD_LIBRARY_PATH="$(pwd)/lib"
bin/myapp

次のMesonスニペットを使用してインストールします。

install_data('myapp.sh', install_dir : '.')

これで完了です。/tmp/myappディレクトリをzip圧縮すると、デプロイ可能な作業用バイナリができます。プログラムを実行するには、ファイルを解凍してmyapp.shを実行するだけです。

検索結果は次のとおりです