// ジェットラグ 2006/09/20 // GSLをCygwinでmakeして、はまりまくりました。同じ轍を踏むことの無いように、また備忘録として記しておきます。 SIZE(30){RからGSL(WinXP用)} Windows XPでCプログラムからdllを作成するときに、Cプログラム内で[[GSL(GNU Scientific Library):http://www.gnu.org/software/gsl/]]が提供する関数を使えるようにする。ちなみに、[[Cygwin:http://cygwin.com/]]は使わず、[[MinGW:http://www.mingw.org/]]と[[MSYS:http://www.mingw.org/msys.shtml]]を使います。 -少なくとも私の環境では下記の手順で動作しましたが、他の環境で成功するかは分かりません。 -内容の誤りや別の方法などがあれば、適宜修正していただければ幸いです。 * 下準備 ** MinGWおよびMSYSのインストール Windows用バイナリが用意されているので、それを使いましょう。 ダウンロードはhttp://www.mingw.org/download.shtmlから、 MinGWは Priveous -> MinGW -> bin -> MinGW-3.1.0-1.exe, MSYSは Current -> MSYS -> bin -> MSYS-1.0.10.exe, をダウンロード。ダブルクリックして、デフォルトのままインストールして問題ありませんでした(インストール方法の詳細は、[[Google:http://www.google.co.jp]]で検索すれば沢山見つかります。 -MinGW-5.0.3.exeを使うと、途中でエラーが出て正常にインストールできませんでした。 -ActivePerlも必要かもしれません。[[ここ:http://www.activestate.com/Products/ActivePerl/Download.html]]からたどってダウンロードし、c:/Perlへインストールます。 **環境変数PATHの修正 環境変数PATHの''先頭''に次の一行 c:/MSYS/1.0/bin;c:/MinGW/bin; (Perlも必要な場合はc:/MSYS/1.0/bin;c:/MinGW/bin;c:/Perl/bin;) を追加して、マシンを(GSLのインストールをする前までに)再起動する。必ず''先頭''に追加しましょう。PATHの追加を忘れたり、先頭に追加しないと、Rからdllファイルを作成するときにエラーがでます。 * GSLのインストール ** GSLソースコードの入手 http://ftp.gnu.org/gnu/gsl/から、最新のもの(2006.9.20現在gsl-1.8.tar.gz)をダウンロードして適当な場所(例えばc:/temp)などに保存する。 ** ソースコードの伸張とmake、インストール gsl-1.8.tar.gzをc:/tempに保存したとして、 MSYSを起動し、プロンプト($)で以下のように入力する。 $ cd c:/temp $ tar zxvf gsl-1.8.tar.gz カレントディレクトリ(c:/temp)にgsl-1.8フォルダができるので、適当な場所(例えばc:/)にフォルダを移動する。MSYSでカレントディレクトリをc:/gsl-1.8に変更し、configureをする。 $ cd c:/gsl-1.8 $ ./configure ''自動的''に進行するので、しばし待つ。再びプロンプトが現れたら $ make をすると、再び自動的に進行するので、これまたしばし待つ。問題なければ $ make install でインストールされる。最後に $ make clean をすると余計なファイルを消してくれる。 * Makevars.winファイルの作成 作業ディレクトリ(コンパイルしようとするxxx.cがあるフォルダ)に、以下の内容を含むMakevars.winファイルをエディタで作成する。 PKG_LIBS = -L/usr/local/lib -lgsl -lgslcblas PKG_CPPFLAGS = -I/usr/local/include -PKG_LIBSはlibgsl.aとlibgslcblas.aのありかを指定する(デフォルトではc:/MSYS/1.0/lib)。 -PKG_CPPFLAGSは、xxx.cファイルで#includeしたgsl_*.hのありかを示す(デフォルトではc:/MSYS/1.0/include)。 -Makevars.winファイルの役割は"Writing R Extensions ver2.3.1"のp.10やp.57を参照のこと。 これで準備は完了。 * 例:ベッセル関数 mybess.cを、例えばc:/testに作成する。 こんな感じ。 #include <stdio.h> #include <gsl/gsl_sf_bessel.h> void mybessel(double *x, double *y) { *y = gsl_sf_bessel_J0 (*x); } mybess.cと同じディレクトリにMakevar.winがあることを確認して、DOS窓から次のコマンドを入力。 C:\test>R CMD SHLIB mybess.c 以下のメッセージが表示されて、dllファイルが作成される。 making mybess.d from mybess.c gcc -I/usr/local/include -Ic:/R-2.3.1/include -Wall -O2 -c mybess.c -o mybess.o gcc -shared -s -o mybess.dll mybess.def mybess.o -Lc:/R-2.3.1/bin -L/usr/local/lib -lgsl -lgslcblas -lR RからCへ変数を引き渡すラッパーを作成する。 bess = function(x) { .C("mybessel", as.double(x), result = double(1))$result } 次にRを起動して、動作を確認する。 > setwd("c:/test") > dyn.load("mybess.dll") > bess = function(x) { .C("mybessel", as.double(x), result = double(1))$result } > bess(5) [1] -0.1775968 めでたしめでたし。 **はまった場合 近くにいる、いろいろなことに詳しい人に助けを求めましょう。そういう人が近くにいない場合は、潔く諦めるか、気合いで何とかするしかありません。まずはPATHの設定とか、Makevars.winに記したPKG_LIBSやPKG_CPPFLAGSが正しい場所を指しているか確認しましょう。 編集した後は,「タイムスタンプを変更しない」をチェックすること。