六本木で働くデータサイエンティストのブログ

元祖「銀座で働くデータサイエンティスト」です / 道玄坂→銀座→東京→六本木

{Rcpp}を入れる時はシステム内に既にあるgccに注意

最近こんな素晴らしい勉強会があったと知りまして。主催は7月の1ヶ月間で何故か3回も一緒に飲んだこの人。


元々WinBUGSは{R2WinBUGS}経由で使っていたんですが、やっぱり{Rcpp}経由でC++コンパイラで高速で走るStan良さそうだなーということで{RStan}を入れてみようと思ったのでした。


・・・ところが。RStan Getting Startedに書いてある手順を何度やっても色々エラーが出まくって動かないというorz 仕方ないのでTwitterオッサン大仏様やら冒頭記事のブログ主に聞くなりして、ようやく解決して{Rcpp}も{RStan}も動くようになったのでした。


ということで、その一部始終を簡単にまとめておきます。まだるっこしい説明が嫌だという人は、全てすっ飛ばして一番後ろの「結論」だけ読めばOKです。


前提


最初に僕の環境をまとめておきます。


Windows環境なのは歴史的経緯(笑)によります。なお、今回Rtools + {Rcpp}を入れようとしているのはあくまでも{RStan}を入れるための前段階です。


Rtoolsを入れる

RtoolsはWindows環境でR本体をソースからビルドするためのツールパッケージです。なので、Rから読み込むのではなく、インストーラをDLしてきて入れる必要があります。これは普通に今使っているRのバージョンに対応したものをただ入れれば問題ないはずです。最新版であればgcc-4.6.3が入っています。


インストール手順は{RStan}のサイトのInstall Rtools on Windowsに書いてあるので、本当にただこの通りにやれば良い!はずなんですが。。。


Rcppが動くかどうか試してみたら!


一応入ったので、Install Rtools on Windowsに書かれているようにまずはWindows側のPATH設定に以下の通り追記します。

c:\Rtools\bin;c:\Rtools\gcc-4.6.3\bin;C:\Windows\system32;


さらに、gccのステータスをR側からチェックしてみます。

> system('g++ -v')
Using built-in specs.
COLLECT_GCC=C:\MINGW3~1\bin\G__~1.EXE
COLLECT_LTO_WRAPPER=c:/mingw3~1/bin/../libexec/gcc/mingw32/4.5.2/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.5.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-werror --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.5.2 (GCC) 


あれ、gcc-4.5.2が入ってることになってる。それでもまぁいいや、gccが認識されていることだし、と思ってRStan Getting Startedにならって動作確認をしてみると。。。

> # using library inline to compile a C++ code on the fly
> library(inline) 
> library(Rcpp)

 次のパッケージを付け加えます: ‘Rcpp’ 

 以下のオブジェクトはマスクされています (from ‘package:inline’) : 

     registerPlugin 

> src <- ' 
+ std::vector<std::string> s; 
+ s.push_back("hello");
+ s.push_back("world");
+ return Rcpp::wrap(s);
+ '
> hellofun <- cxxfunction(body = src, includes = '', plugin = 'Rcpp', verbose = FALSE)
C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:196: warning: overriding recipe for target `.m.o'
C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:189: warning: ignoring old recipe for target `.m.o'
filea072b4c44.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
make: *** [filea072b4c44.o] Error 1

ERROR(s) during compilation: source code errors or compiler configuration errors!

Program source:
  1: 
  2: // includes from the plugin
  3: 
  4: #include <Rcpp.h>
  5: 
  6: 
  7: #ifndef BEGIN_RCPP
  8: #define BEGIN_RCPP
  9: #endif
 10: 
 11: #ifndef END_RCPP
 12: #define END_RCPP
 13: #endif
 14: 
 15: using namespace Rcpp;
 16: 
 17: 
 18: // user includes
 19: 
 20: 
 21: // declarations
 22: extern "C" {
 23: SEXP filea072b4c44( ) ;
 24: }
 25: 
 26: // definition
 27: 
 28: SEXP filea072b4c44(  ){
 29: BEGIN_RCPP
 30:  
 31: std::vector<std::string> s; 
 32: s.push_back("hello");
 33: s.push_back("world");
 34: return Rcpp::wrap(s);
 35: 
 36: END_RCPP
 37: }
 38: 
 39: 
Error in compileCode(f, code, language = language, verbose = verbose) : 
  Compilation ERROR, function(s)/method(s) not created! C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:196: warning: overriding recipe for target `.m.o'
C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:189: warning: ignoring old recipe for target `.m.o'
filea072b4c44.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
make: *** [filea072b4c44.o] Error 1
In addition: Warning message:
running command 'C:/PROGRA~1/R/R-30~1.2/bin/x64/R CMD SHLIB filea072b4c44.cpp 2> filea072b4c44.cpp.err.txt' had status 1 
> cat(hellofun(), '\n')
Error in cat(hellofun(), "\n") : could not find function "hellofun"


全力でコケてますorz 明らかにコンパイラが認識されてません。


悪さをしているのはどいつだ?


コンパイラが認識されていないということで、思い当たるのは既に書いたように「gcc-4.6.3 (Rtools)を入れてるはずなのにR側ではgcc-4.5.2しか認識されていない」という点。そこで、Windows内のどこにあるか探してみます。すると。。。ありました。

C:\MinGW32-xy\lib\gcc\mingw32\4.5.2


こいつか!このPython(x,y)で一緒に入ってくるやつ!!こいつがgcc-4.5.2の正体だったのかぁぁぁっっっ!!! ということで、こいつをWindows側のPATHから削除します。その上で、R + RStuidioを再起動してからもう一度gccのバージョンをチェックすると。。。

> system('g++ -v')
Using built-in specs.
COLLECT_GCC=c:\Rtools\GCC-46~1.3\bin\G__~1.EXE
COLLECT_LTO_WRAPPER=c:/rtools/gcc-46~1.3/bin/../libexec/gcc/i686-w64-mingw32/4.6.3/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: /data/gannet/ripley/Sources/mingw-test3/src/gcc/configure --host=i686-w64-mingw32 --build=x86_64-linux-gnu --target=i686-w64-mingw32 --with-sysroot=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/mingw32 --prefix=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/mingw32 --with-gmp=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/prereq_install --with-mpfr=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/prereq_install --with-mpc=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/prereq_install --disable-shared --enable-static --enable-targets=all --enable-languages=c,c++,fortran --enable-libgomp --enable-sjlj-exceptions --enable-fully-dynamic-string --disable-nls --disable-werror --enable-checking=release --disable-win32-registry --disable-rpath --disable-werror CFLAGS='-O2 -mtune=core2 -fomit-frame-pointer' LDFLAGS=
Thread model: win32
gcc version 4.6.3 20111208 (prerelease) (GCC) 

ちゃんとgcc-4.6.3が認識されました!後はダメ押しでhello worldのコードを回してみると。。。

> # using library inline to compile a C++ code on the fly
> library(inline) 
> library(Rcpp)

 次のパッケージを付け加えます: ‘Rcpp’ 

 以下のオブジェクトはマスクされています (from ‘package:inline’) : 

     registerPlugin 

> src <- ' 
+ std::vector<std::string> s; 
+ s.push_back("hello");
+ s.push_back("world");
+ return Rcpp::wrap(s);
+ '
> hellofun <- cxxfunction(body = src, includes = '', plugin = 'Rcpp', verbose = FALSE)
cygwin warning:
  MS-DOS style path detected: C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf
  Preferred POSIX equivalent is: /cygdrive/c/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
> cat(hellofun(), '\n') 
hello world 


無事動きました。。。もちろんこの後{RStan}もインストールして、ちゃんと動きました。よかったよかった。


結論:システム内に既に入っているgccに注意!


要は、WindowsのPATH編集ダイアログを開いて、システム内既存のgccへのパスである(この場合はMinGW

C:\MinGW32-xy\bin


を手動で削除し、代わりにRStan Getting StartedのInstall Rtools on Windowsでも指定されている

C:\Rtools\bin;c:\Rtools\gcc-4.6.3\bin;C:\Windows\system32;


を追記して、OKして保存したらR + RStudioを再起動すれば、ちゃんとgcc-4.6.3へのパスが通って{Rcpp}が動くようになります。恒久的にこのままにしておくとPython側で不具合を起こす可能性はゼロではありませんが、Python側でMinGWが必要なことをやらない限りはこのままでも問題ないと思います。


ということで、RとPython(x,y)を共存させているWindows環境だったり、MinGWやその他gccを入れていて、どーしても{Rcpp}が走らない!という人はこの辺チェックしてみると良いでしょう。お粗末様でした。