Pthreads-w32 2.8.0のバグ
Windows上でPOSIXのpthreadsを実現するライブラリ、POSIX Threads (pthreads) for Win32の最新版、2.8.0(2009年12月現在)にはバグがある。これはMinGW+ffmpeg(5)pthreadやMinGW+ffmpeg(A)pthreadは複雑に書いた使用方法に注意が必要というものではなく、最近のffmpeg等をビルドしようとする場合に、コンパイルエラーとなるバグだ。
動作に関するバグでは無く、発現時には必ずわかるだけまだマシなバグではある。が、その解決方法に関してあまりよろしくない方法が流通しているようなので、ここに現状で適切と思われる方法をメモしておく。
バグの内容
ffmpeg等、_POSIX_C_SOURCEをdefineしているソフトウェアのコンパイル時に、以下のようなエラーが出る。
error: expected ')' before 'pid'
TODO:実際にffmpegをビルド時のエラーに差し替えること。
これはpid_tが型として未定義なために発生しているエラーだ。
pthreads-w32はPOSIX互換のスレッド機能を実装するライブラリなので、当然、_POSIX_C_SOURCEの定義によりその内容が変化する。pid_tは本来sched.hで定義されるはずなのだが、対応が不十分なために未定義になってしまうことがある、というのがその原因だ。
pid_tを強制的に定義してしまえば、コンパイルは通るには通るし、ネット上ではそれが解決方法として多く紹介されている。しかし、より正しくはどう修正すべきなのだろうか。
検索範囲を英語圏に広げると、pthreads-win32のMLにそのものずばり、Help with issues on trying to compile ffmpeg with pthreads supportというスレッドがある。
これに対する回答では、
#if defined(__MINGW32__) || defined(_UWIN) #if PTW32_LEVEL >= PTW32_LEVEL_MAX /* For pid_t */ # include <sys/types.h> /* Required by Unix 98 */ # include <time.h> #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #else typedef int pid_t; #endif
となっているところを
#if defined(__MINGW32__) || defined(_UWIN) #if PTW32_LEVEL >= PTW32_LEVEL_MAX /* For pid_t */ # include <sys/types.h> /* Required by Unix 98 */ # include <time.h> #else typedef int pid_t; #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #else typedef int pid_t; #endif
のようにしろ、と言っている。これは実用上十分な修正ではあるようだが、もう少し踏み込もう。
この回答を書いたRoss Johnson氏は、Ramiro Polla - _POSIX_C_SOURCE-related problemsにも回答を書いていて、こちらが本質的なポイントを突いている。_POSIX_C_SOURCE=200112の場合にはPTW32_LEVEL=3に設定されるべきところが、PTW32_LEVEL=1となってしまうのが根本的な原因だ。
そしてpthreads-win32のCVSには、既に仮の修正がコミットされているとのこと。内容はCVSを見てもらうとして、同様の潜在的問題点はpthread.hにもあるようなので、こちらも同時に修正すべきだ。
猫科研究所では、MinGW猫科研究所パックにpthreads-w32を含むTDM版のGCCを含めているため、猫研パックにはこの修正相当のdiff(patch)を添付している。そのパッチをここに単独で置いておく。
pthreads-w32-2-8-0-fixposix.diff 975.00B (1479) (2009/12/09)
最終更新時間:2009年12月09日 22時18分26秒