- 001 - g++でコンパイルできる環境作成
- 002 - Windows上で実行可能にする <--- 今回の内容
C++開発環境構築(MSYS2) - 002
Windows上で実行可能なexeファイルを作成可能にする。
前回はMSYS2上で実行可能なexeファイルを作成した。
今回はwindows上で実行可能なファイルを作成するのが目的です。
前回作成したプログラムを実行すると下記のようなエラーが発生しました。
今回はこのエラーを回避する方法を調べました。
DLLの依存関係を調べる
まず、DLLの依存関係を調べます。
siunのメモを参考にしました。
lld(list dynamic dependecies)というコマンドを使用して、ダイナミックライブラリの依存関係を調べます。
$ ldd ./hello.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffcd27f0000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffcd0ab0000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffcd03c0000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffcd21c0000)
libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x7ffc75520000)
libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x7ffcb2620000)
libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x7ffca45b0000)
このうち以下3種(mingw64/bin/以下にあるDLL)は、windows上でPATHが通っていないため、エクスプローラーから直接起動した時にエラーの原因になります。
-
libstdc++-6.dll
-
libwinpthread-1.dll
-
libgcc_s_seh-1.dll
静的にリンクする
前項で調べたエラーの原因となるDLLを静的にリンクします。
windows側でPATHを通すという手もあるのですが、それだと既に同名のDLLを別のPATHで通していた場合におかしくなるそうです。
また、DLLをexeと同じディレクトリに置くという手もあります。1
windowsとmsys2の環境を分けておきたいという好みの問題もあるため、今回は静的にリンクするという手段をとります。
静的リンクには-static
と-l
のオプションを使用します。
処理 | オプション |
---|---|
静的にリンクする C++ ライブラリを指定する。 |
-staticlib= llst |
リンカーのライブラリ検索リストに lib lib.a または lib lib.so を追加する。 |
-l lib |
C++ コンパイラオプションを参考にコンパイラオプションを調べました。
上記サイトの-l
オプションの説明がサッパリわからなかったためgcc/g++の"-l"オプションの意味を参考にしました。
追加するオプションは以下のようになります。
-static -lgcc -lstdc++ -lwinpthread
Sample source : hello.cpp
# include <iostream>
int main()
{
std::cout << "hello";
}
上記コードをコンパイルします。
$ g++ -o hello.exe ./hello.cpp -static -lgcc -lstdc++ -lwinpthread
結果を確認する
DLLの依存関係を調べます。
$ ldd ./hello.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffcd27f0000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffcd0ab0000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffcd03c0000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffcd21c0000)
今回はDLLの問題が解決できていそうです。実際にwindows上で実行してみます。
コマンドプロンプト上で実行できました。hello
と表示されています。
まとめ
- msys2で作成したプログラムはwindows上で実行できないことがある。
- 少なくとも今回はDLLが問題となっていた。
- 解決方法は3つ。(1)windows上でPATHを通す。(2)DLLをexeと同じディレクトリに置く1。(3)コンパイル時に静的リンクする。
-
@yumetodo様のコメントを受けて追記 ↩ ↩2