// ジェットラグ 2006/09/
// GSLをCygwinでmakeして、はまりまくりました。同じ轍を踏むことの無いように、また備忘録として記しておきます。
// ActivePearlが必要であることの追記。 ジェットラグ 2006/09/26
// Rの組み込み関数によるベッセル関数の結果を追加。 ジェットラグ 2006/09/27
// 「Rから他言語利用」のページをリンク。 ジェットラグ 2006/09/29
// R 2.4.0に関する注記を追加。 ジェットラグ 2006/12/01
// R 2.4.0の仕様変更に併せて、Makevar.winファイルの記述を変更。その他細かな誤りなどを修正。 ジェットラグ 2006/12/05
// R 2.4.1で"PKG_LIBS="が使えるようになったこと、細かな修正。 ジェットラグ 2006/12/19

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]]を使います。

--RからC言語を利用する際の一般的な手順は、[[Rから他言語利用]]を参照ください。
--少なくとも私の環境(R 2.3.1および2.4.0、日本語WinXP SP2 & Pentium Mと英語版WinXP SP2 & Pentium 4)では下記の手順で動作しましたが、他の環境で成功するかは分かりません。
--内容の誤りや別の方法、成功した、など、適宜修正・報告していただければ幸いです。
-R のパッケージに gsl という GSL ライブラリーへの wrapper (と説明)がありますが、GSL のコンパイルは各自やるとして、もしかして最後(実際に使用するくだり)あたりを簡単にしてくれるのでは。 -- [[使ったことのない人]] &new{2006-09-28 (木) 16:31:29};
-パッケージgslのマニュアルを確認してみました。このパッケージ、GSLが提供する特殊関数と疑似乱数列発生関数へのラッパー集ですね。例示したベッセル関数は、gslを使えば、わざわざCでコードを書いてdllを作成するという手間は省略できそうです(Rの組み込み関数を使うのが一番簡単ですが)。GSLの他の機能(私の場合特にベクトルや行列処理)を使いたい場合には、gslにはそのためのラッパーが含まれていませんので、Cコード->dllという手順は省略できそうにありません。 -- [[ジェットラグ]] &new{2006-09-28 (木) 17:08:54};
-ついでに好奇心からですが教えて下さい。GSL ライブラリーを特に使いたい動機はなんでしょう。なにか、魅力的なものがありますでしょうか。 -- [[使ったことのない人]] &new{2006-09-28 (木) 19:23:24};
-「格好良さそうだから」という理由は別にして、GSLを使う最大の理由は、C言語で行列やベクトル計算をしてくれる関数群を利用するためです。行列演算に特化した[[Meschach:http://www.math.uiowa.edu/~dstewart/meschach/]]というライブラリもありますが、こちらはインストールがうまくいかずに利用を断念しました。他のライブラリをご存じでしたらご教示いただければ幸いです。 -- [[ジェットラグ]] &new{2006-09-28 (木) 21:33:05};
-以下の記事によると Meshach は行列演算がかなり早いらしい。GSL は比較されていないけど。R の組み込みライブラリはどうなんだろう。[[IBM developerworks article:http://www-128.ibm.com/developerworks/linux/library/l-matrix.html]] -- [[使ったことのない人]] &new{2006-09-29 (金) 14:11:33};
-この記事によれば、Meschachはかなり早いですね。行列演算に限らず、RからCを使う場合、皆さんはどのようなライブラリを使われているんでしょうか?こういうノウハウが蓄積されれば、役立ちそうですね。 -- [[ジェットラグ]] &new{2006-09-29 (金) 19:32:47};
- R2.10.1で試しました。Makevars.winを"PKG_LIBS = -L/usr/local/lib -lgsl -lgslcblas"に修正する必要があるようです。 -- [[なかの]] &new{2010-05-03 (月) 21:30:06};

#comment

* 下準備
** MinGW、MSYSおよびActive Perlのインストール
* 下準備 [#g6e369d1]
** MinGW、MSYSおよびActive Perlのインストール [#ib644ab0]
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,
をダウンロード。ダブルクリックして、デフォルトのままインストールして問題ありませんでした。
-MinGW-5.0.3.exeを使うと、途中でエラーが出て正常にインストールできませんでした。

Active Perlは、http://www.activestate.com/Products/ActivePerl/Download.htmlから、
 Free Download -> Continue
とたどって、適切なバージョン(私の環境ではver. 5.8.8.819, Windows (X86) MSI)
をダウンロードし、c:/Perlへインストールます。最後にパスを追加するかどうか聞かれるので、追加しておきましょう。

**環境変数PATHの修正
**環境変数PATHの修正 [#l42de548]
環境変数PATHの''先頭''に次の一行
 c:/MSYS/1.0/bin;c:/MinGW/bin;
 (Perlのインストールでパスを追加していない場合は、c:/MSYS/1.0/bin;c:/MinGW/bin;c:/Perl/bin;)
を追加する。必ず''先頭''に追加してください。R_HOME/binへもパスを通しておきます。これらのパスが正しく設定されていないと、あとで説明するR CMD SHLIBでdllファイルを作成することができません。

* GSLのインストール
** GSLソースコードの入手
* GSLのインストール [#t6b39e36]
** GSLソースコードの入手 [#x2928321]
http://ftp.gnu.org/gnu/gsl/から、最新のもの(2006.9.20現在gsl-1.8.tar.gz)をダウンロードして適当な場所
(例えばc:/temp)などに保存する。

** ソースコードの伸張とmake、インストール
** ソースコードの伸張とmake、インストール [#k42bf69e]
gsl-1.8.tar.gzをc:/tempに保存したとして、
MSYSを起動し、プロンプト($)で以下のように入力する。
 $ cd c:/temp
 $ tar zxvf gsl-1.8.tar.gz -C /c
c:/にgsl-1.8フォルダができる。MSYSで
カレントディレクトリをc:/gsl-1.8に変更し、configureをする。
 $ cd c:/gsl-1.8
 $ ./configure
''自動的''に進行するので、しばし待つ。再びプロンプトが現れたら
 $ make
をすると、再び自動的に進行するので、これまたしばし待つ(10分以上掛かります)。問題なければ
 $ make install
でインストールされる。最後に
 $ make clean
をすると余計なファイルを消してくれる。
-GSLのインストールはこれでお終いです。MSYSはこれ以降使わないので、$ logoutか、ウインドウを閉じて終了させます。

* Makevars.winファイルの作成
* Makevars.winファイルの作成 [#w5ad8b2c]
作業ディレクトリ(コンパイルしようとするxxx.cがあるフォルダ)に、以下の内容を含むMakevars.winファイルをエディタで作成する。
  EXTRA_LIBS = -L/usr/local/lib -lgsl -lgslcblas
  PKG_CPPFLAGS = -I/usr/local/include
-EXTRA_LIBSはlibgsl.aとlibgslcblas.aのありかを指定する(デフォルトではc:/MSYS/1.0/local/lib)。
-PKG_CPPFLAGSは、xxx.cファイルで#includeしたgsl_*.hのありかを示す(デフォルトではc:/MSYS/1.0/local/include/gsl)。
-Makevars.winファイルの役割は"Writing R Extensions"や
"R Installation and Administration"を参照のこと。
-R 2.4.0では、"PKG_LIBS="が正常に読み込まれなくなりました。代わりに"EXTRA_LIBS="を使いましょう。"EXTRA_LIBS="は、ver. 2.3.1および2.4.0とも正常に働きます。
-R 2.4.1では、"PKG_LIBS="が使えるように再度変更されました。

これで準備は完了。

* 例:ベッセル関数
* 例:ベッセル関数 [#d7392af1]
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 Ver. 2.4.0では、最初に"/bin/sh.exe: latex: command not found"というエラーが表示されるものの、無視して差し支えないようです。

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)       # GSLのベッセル関数による計算結果
  [1] -0.1775968
  > besselJ(5,0)  # Rの組み込み関数による計算結果
  [1] -0.1775968

めでたしめでたし。

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