#はじめに
MinGWでOpenMPライブラリを使ってマルチスレッド計算させるプログラムをgccでコンパイルすると,libgomp-1.dllがstatic linkできない問題にぶち当たりました.
結論から言うと消極的解決(libgomp-1.dll等を同ディレクトリに置く)以外の解決法が見つからなかったので,書き残しておきます.
#MinGWにPthreadを導入
そもそもMinGWでOpenMPを使っているプログラムをコンパイルするにはPthreadを導入する必要があります.以下のようにしてPthreadを導入します.
sourceforgeのmingwプロジェクトのpthreadのページから次のファイルをダウンロードする.
- pthreads-w32-2.9.1-1-mingw32-dev.tar.lzma
- pthreads-w32-2.9.1-1-mingw32-dll.tar.lzma
(lzmaで圧縮されているので7zip解凍する)
解凍したら以下のファイルをMinGWディレクトリ以下にコピーする.
pthreads-w32-2.9.1-1-mingw32-dev
- include/
-- pthread.h
-- sched.h
-- semaphore.h- lib/
-- libpthreawd.a
-- libpthread.dll.a
-- libpthreadGC2.a
-- libpthreadGC2.dll.a
-- libpthreawdGCE2.dll.a
pthreads-w32-2.9.1-1-mingw32-dll- bin/
-- pthreadGC2.dll
-- pthreadGCE2.dll
上記のファイルを
c:\MinGW
以下のディレクトリのbin, include, libの中にそれぞれコピーする.参考 demura.net | Windows用pthreadインストールメモ
http://demura.net/misc/10817.html
#MinGWのgccでコンパイル
さてコンパイルします.普通にコンパイルすると例えばlibgcc_s_dw2-1.dll
などのライブラリがダイナミックリンクとなってしまい,環境が変わると少々面倒です.
gccやg++のオプションで,-static-libgcc
や-static-libstdc++
を指定しましょう.指定しないとこうなります.
#MinGWのgccでOpenMPプログラムをコンパイル
本題です.gccで-fopenmpフラグを付けてOpneMPプログラムを普通にコンパイルすると,libgomp-1.dll
がstatic linkになりません.
gccのオプションに-static-libompみたいなのあるのかなと思いましたが,そういうのは無いようです.
色々調べてみましたが,同じ問題にぶつかっている人はいるようですが,解決している例がありません.
MinGW-users - OpenMP static build (link pthread statically)
http://mingw-users.1079350.n2.nabble.com/OpenMP-static-build-link-pthread-statically-td7583565.html
@tonets ここ (https://t.co/HkHGQjNSAI 比較的最近のスレ) で詳しく議論されてるっぽいですが、libgomp が pthread に依存してて、pthread の設計思想が static を許してないから無理みたいな(無理)
— 5 o'clock (@inferist) December 29, 2015
@tonets さっきのスレでも「再配布可能なんだし同梱しちまえばいいだろ」って斬って捨てられてますたw pic.twitter.com/EB1Lr1ZHtl
— 5 o'clock (@inferist) December 29, 2015
結局libgomp-1.dll
をc:/MinGW/bin
からバイナリと同じディレクトリにコピーしてきて解決を図りました.すると,「libgomp-1.dllが無いよ!」のエラーは(当然)消えましたが,「libgcc_s_dw2-1.dllが無いよ!」と「pthreadGC2.dllが無いよ!」のエラーが新たに登場するようになりました.libgcc_s_dw2-1.dll
に至っては-static-libgcc
しているので完全に謎です.
仕方がないので,libgcc_s_dw2-1.dll
(c:/MinGW/bin
にある) と,pthreadGC2.dll
(Pthreadの導入時に持ってきたもの.c:/MinGW/bin
にある) をそれぞれコピーしてきて,無事に実行できるようになりました.
#まとめ
MinGWのgccで-fopenmpしたら,
-
-static-libgcc
を付ける -
-static-libstdc++
を付ける -
libgomp-1.dll
を同梱 -
libgcc_s_dw2-1.dll
を同梱 -
pthreadGC2.dll
を同梱
とすれば,別環境―MSYS以外の例えばコマンドプロンプト等でも実行ができるようになりました(The 消極的解決).
※どなたか解決策が分かりましたら教えて下さい.