【C言語】MinGWでマルチスレッドプログラムのコンパイルができなかった話
戦車の話が一切出てこない暇人戦車長です。
今回はWindows環境でのC言語プログラム作成でこけた話です。
Windows10環境にMinGWを導入してまともなソースコードが書けている状態からスタートです。
この解決法で問題が起きても僕は一切責任を負いませんので自己責任でお願いします。
コンパイル通らん
「-lpthread」をつけてgccしたのにエラーが・・・
Makefileでは
$gcc -o ファイル名 ソースファイル名 -lpthread
的なことしてます。
エラーコードは
"fatal error: pthread.h: No such file or directory
#include <pthread.h>
^
compilation terminated.
make: *** [XX.o] Error 1"
つまり「ライブラリpthread.hが見つからん」ってことですね。
ヘッダファイル等の手動導入
ないなら手動で入れるしかないじゃないということでgithubの
にアクセスして、
・libpthread-2.8.0-3-mingw32-dll-2.tar.lzma
・pthreads-w32-2.8.0-3-mingw32-dev.tar.lzma
をDL。
$lzma -d ファイル名
を実行して二つともを解凍一回目。
できた二つのファイル↓を
WinRARとかで解凍2回目。
するとこの二つのフォルダ―ができる
この中身の「bin」「lib」「include」をフォルダごとMinGW直下↓にコピーすればOK。
それでもエラーは吐かれ続ける
「ヘッダファイル突っ込んだしコンパイル通るやろ」と思ってコンパイルしたら
$ make all gcc -c XX.c
In file included from c:\mingw\include\pthread.h:288:0,
from XX.c:5:
c:\mingw\include\sched.h:152:47: error: unknown type name 'pid_t'
PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy);
^~~~~
c:\mingw\include\sched.h:154:47: error: unknown type name 'pid_t'
PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid);
^~~~~
In file included from XX.c:5:0:
c:\mingw\include\pthread.h:307:8: error: redefinition of 'struct timespec'
struct timespec {
^~~~~~~~
In file included from c:\mingw\include\pthread.h:218:0,
from XX.c:5:
c:\mingw\include\time.h:115:8: note: originally defined here
struct timespec
^~~~~~~~
make: *** [XX.o] Error 1
エラーだよコンチクショウ!!!
エラーコードを見ると
① sched.hでのerror: unknown type name 'pid_t'
② pthread.h&time.hでのerror: redefinition of 'struct timespec'・originally defined here(競合)
の二つかなぁと見れる
インクルードガードやらを追記
①の方はtype nameを宣言?してやれば解決しそうってことで覗くと
sched.h
おろ?
宣言されてるやん。
if文で弾かれたかな???って当たりを付けて
sched.h
#endifの後(126行目)に
typedef int pid_t;
を追記。
良くはないだろうけどまぁ行けるっしょって感じで。
②は・・・
競合かなぁ
"struct timespec"っていう関数が重複して宣言されてるって感じ。
インクルードガードは???
まさか・・・
pthread.h
oh.....
time.hが先に読まれた場合の記述がない
time.hの方には
#if defined __need_struct_timespec && ! __struct_timespec_defined
がありますね。
なので、pthread.h→time.hの順に読まれてたらセーフだったのかも。
pthread.hにインクルードガードを追記しましょう
timespec関数を定義する部分を挟むように
#ifndef _TIME_H
と
#endif
を追記。
コンパイル通してみると
無事通りました。
これが正しいやり方なのかわかりませんが無事に通ってよかったです。
ホントめんどくさかった・・・。