// ジェットラグ 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が正しい場所を指しているか確認しましょう。



編集した後は,「タイムスタンプを変更しない」をチェックすること。


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS