TOP > プログラミング関連 > SFML をマルチスレッド(/MT) でビルド

◆◆ SFML をマルチスレッド(/MT) でビルド ◆◆
問題意識
敢えて語弊のある言い方をします。
SFML の公式サイトに置いてあるバイナリを使って、Visual C++ でアプリを作ると、 他の人のマシンでは実行できない実行ファイルになってしまいます。大変!
一般的な話
Visual C++ には、ランタイムライブラリの設定があります。
リリースビルドの場合は、選択肢は2つです。
◆ 設定画面への道のり ◆
プロジェクトを右クリックして、
プロパティ>構成プロパティ>C/C++>コード生成>ランタイムライブラリ


「マルチスレッド DLL (/MD)」は動的リンクです。ランタイムライブラリが実行ファイルに含まれません。 「マルチスレッド (/MT)」は静的リンクです。ランタイムライブラリが実行ファイルに含まれます。

早い話、前者を選択していると、出来上がった実行ファイルを単体では実行できない、ということです。 VisualStudio をインストールしているマシン(開発に使っているマシン)には もちろんランタイムライブラリが入っているので実行できます。 が、成果物を配布して他の人に使ってもらおうと思ったときに問題が起きます。 その人のマシンに VisualStudio のランタイムライブラリが入っているとは限らない(むしろ入っているわけがない)からです (ちなみに、この設定がデフォルト。なぜだマイクロソフト?)。
ランタイムライブラリがないので "msvcr80.dllが見つからない" などのエラーが出てしまいます。

後者の設定にしておくと、そうした問題は発生しません。
成果物の中にランタイムライブラリが埋め込まれた形になるので、 実行ファイル単体で実行できる、というわけです。

もちろん、その分、実行ファイルのサイズは大きくなります。
それを気にするかどうかは、開発者の考え方次第でしょうか。
大きくなるとは言っても 数百kb程度ですので、私は「マルチスレッド (/MT)」にしたい派です。

サイズが大きいから利用者にとって不便?
DLL が別途必要だから利用者にとって不便?

やっぱり、開発者の考え方次第ですね。
うかつに口を開くと血を見てしまいそうですので、ここではこの件についての議論は控えることにします(ぶるぶる)。

公式サイトの SFMLバイナリは「マルチスレッド DLL (/MD)」
どうやら、公式サイトの SFMLバイナリは「マルチスレッド DLL (/MD)」でビルドされているみたいです。
ですので、SFML を使うには、自分のアプリのビルドの設定も、 それに合わせて「マルチスレッド DLL (/MD)」にしておかないといけません。
そうしないと、ビルドのときにエラーになってしまうのです。


【エラーメッセージ一部抜粋】
2>msvcrt.lib(MSVCR100.dll) : error LNK2005: ___iob_func は既に LIBCMT.lib(_file.obj) で定義されています。
2>msvcprt.lib(MSVCP100.dll) : error LNK2005: "void __cdecl std::_Xlength_error(char const *)" (?_Xlength_error@std@@YAXPBD@Z) は既に libcpmt.lib(xthrow.obj) で定義されています。

福音
SFML を使ったアプリを「マルチスレッド (/MT)」でビルドすることはできないのか?!

できます!
SFML をソースからビルドすればいいんです!
そうすれば、「マルチスレッド (/MT)」でビルドされた SFML のライブラリが手に入ります!
SFML をソースからビルドする
SFML の公式サイトにはソースも置いてあります。
チュートリアルにもあるように、これを CMake というツールを使ってビルドします(ビルドできる状態にします)。

チュートリアルの方では、一般的な手順が淡々と述べられているだけですが、 ここでは上記の問題意識に沿って、 Visual Studio で マルチスレッド(/MT)でビルドするまでの手順を紹介します。

以下の手順は Windows7+Visual C++2010、SFML 2.1 でのものです。
スタティックリンクライブラリの SFML を マルチスレッド(/MT)でビルドします。
1. SFML のソースをダウンロード
公式サイトのダウンロードページへ行きます。
この記事を書いている時点での最新版は 2.1 です。
ページの左上の「SFML 2.1 latest stable version」をクリック。
次のページの最下部「All Source code」をクリックしてソースをダウンロード。

2. CMake をダウンロード
公式サイトのダウンロードページへ行きます。
この記事を書いている時点での最新版は 2.8.12.2 です。
「Latest Release (2.8.12.2)」の少し下にある「Binary distributions: 」のコーナーの中の 「Windows ZIP」をダウンロードします(ファイル名は "cmake-2.8.12.2-win32-x86.zip")。
インストーラー版もあるみたいですので、お好きな方を落とせばいいと思います。

3. 両者を、日本語が含まれていないパスに配置

たとえば、こういう感じです。



4. CMake-GUI を起動
VisualStudio のコマンドプロンプトを起動して、そこから CMake-GUI を起動します。
こうすると、VisualStudioの環境変数が設定された状態で CMake を起動できます。

VisualStudio のコマンドプロンプトは、スタートメニューから起動できます。


"cd" コマンドで、cmake のフォルダに移動しましょう。(がんばって!)
"bin" フォルダに cmake-gui.exe が入ってます。"cmake-gui" と入力してエンターキー押下。


CMake の GUI が起動します。

5. CMake に必要な項目を入力
上記画像で示した "1" に SFMLのソースの場所を入力。
"2" に ソリューションファイルの生成場所を入力。
"3" の "Configure" ボタンをクリック。

"2" の生成場所として、事前にどこかにフォルダを作っておくとよいです。(日本語を含まないパスに!)

6. ジェネレーターを選択

"Visual Studio 10" と "use default native compilers" で "Finish"。



実行中。しばらく待ちましょう。



完了すると、↓のような画面になります。
7. 設定項目を変更して、VCのソリューションを生成
変更箇所は2つ。
BUILD_SHARED_LIBS のチェックを外す。
SFML_USE_STATIC_STD_LIBS にチェックを入れる。



その他、触っておきたいところがあれば、今のうちに。
こちらのチュートリアルを参照してください。


変更ができたら "Configure" をもう一度クリック。
画面が白くなって、メッセージ欄に "Configuring done" と出ます。


"Generate" ボタンをクリック。

これで、指定した場所にソリューションファイルが生成されているはずです。
8. sfml.sln をクリックして VisualStudio を起動


9. リリースモードにする

ここではリリース版の話だけをしますが、 必要ならデバッグ版もビルドしておくとよいでしょう。


10.「マルチスレッド(/MT)」に変更する
SFML の各モジュールのビルド設定を「マルチスレッド(/MT)」に変更します。

"sfml-audio" など、SFML の各モジュールに対応したプロジェクトがありますね?
"sfml-*****" 以外のプロジェクトは無視してください。

1つずつ設定していきましょう。
プロジェクト名を右クリックして "プロパティ" を選択。

まずは「構成プロパティ>全般」を開きます。
以下の項目を確認します。

・構成の種類 → スタティックライブラリ(.lib)
・ターゲットの拡張子 → .lib



"ターゲット名" は生成されるファイル名です。
お好みでどうぞ。

次は「C/C++>コード生成」を開きます。
以下の項目を変更します。

・ランタイムライブラリ → マルチスレッド(/MT)

念願の設定項目ですね。



設定ができたら "OK" をクリック。 他のプロジェクトも同じように設定を変更します。
そして、ビルド。
11. libファイルを入手
「/lib/Release」フォルダに libファイルが生成されているはずです。
この libファイルを使えば、マルチスレッド(/MT)でアプリをビルドできます。





以上です。うまくいったでしょうか?
出来上がった libファイルの使い方は、公式サイトで配布されているバイナリと同じです。 こちらのチュートリアルをご覧になってください。

SFML でアプリを開発して、配布できるようになることを祈ってます。
楽しい SFML ライフを!