Ruby2.0 (RubyInstaller版)で自前のC拡張がビルドできなかった問題について
まず結論から言うと、
です。
前提として次の環境でした。
- Ruby2.0.0p0 (RubyInstaller版 32bit)
- DevKitは DevKit-mingw64-32-4.7.2-20130224-1151-sfx の方
- 32bit/64bitで分けたらしい
- C拡張はC++
- Rixmapのことです
- 無駄にC++0xを有効にしてました
この状態でextconfしてmakeしたら
In file included from E:/Ruby/Ruby200/include/ruby-2.0.0/ruby/defines.h:153:0, from E:/Ruby/Ruby200/include/ruby-2.0.0/ruby/ruby.h:70, from E:/Ruby/Ruby200/include/ruby-2.0.0/ruby.h:33, from pcx.cxx:2: E:/Ruby/Ruby200/include/ruby-2.0.0/ruby/win32.h: In function 'double rb_w32_pow( double, double)': E:/Ruby/Ruby200/include/ruby-2.0.0/ruby/win32.h:787:51: error: '_controlfp' was not declared in this scope E:/Ruby/Ruby200/include/ruby-2.0.0/ruby/win32.h:788:16: error: '_PC_64' was not declared in this scope E:/Ruby/Ruby200/include/ruby-2.0.0/ruby/win32.h:788:24: error: '_MCW_PC' was not declared in this scope
などと言われて ( ゚д゚) としてました*1
でまぁどうなってのかなって思ったら
#elif defined(__MINGW64_VERSION_MAJOR) /* * Set floating point precision for pow() of mingw-w64 x86. * With default precision the result is not proper on WinXP. */ static inline double rb_w32_pow(double x, double y) { double r; unsigned int default_control = _controlfp(0, 0); _controlfp(_PC_64, _MCW_PC); r = pow(x, y); /* Restore setting */ _controlfp(default_control, _MCW_PC); return r; } #endif
とかなってるわけですよ。これといっておかしいところはないと。
仕方ないんで_controlfpがドコに居るのかっていうのをぐーぐるさんに聞いたら float.h にいるとか言われたんで見てみたんですよ。そしたらですね。この_controlfpとかって__STRICT_ANSI__が定義されてると使えないってなってるじゃないですか。すごく怪しい。
んで、これが定義される条件を調べたらとりあえず
- -std=c99
- --ansi
が付くと定義されるとかって見つかりまして。そして気になる記述がソコに
c99の場合は__STRICT_ANSI__が定義される
Memo/std=c99とstd=gnu99の違い - たむちょんの脳内図鑑
( ゚д゚) (つд⊂)ゴシゴシ ( ゚д゚)
それで思い出しんたんですよね-、-std=gnu++0xの存在を。
なんでc++0xを使うのに-std=c++0xと-std=gnu++0xがあるのかと思ってたんですが、規格に厳格かどうかっていうのが違ったのか-、っていう新しい発見でした。
…でもこれって、C99を指定するときに-std=c99してるC拡張がビルドできないっていう問題が出るんだけどどうなんだろコレ…