kenhys

Gaucheが最近気になっている人です。

Lenovoのトラベルキーボード ウルトラナビ付を愛用しています。 トラックポイントがないと駄目な体になってしまいました。ちなみにソフトドーム派です。

目次

Gauche:ExtensionHowTo

はじめに

Gaucheのための拡張ライブラリを書くときに、あれこういうときどうするんだっけ?というのをまとめたい。

前提条件

Gauche 0.9.3.2かつMinGWという縛りで話をする。
c-wrapperでできるしね、という人ならきっとautotools族には詳しいだろうし、 自分で拡張として使いたいというライブラリの面倒を見れるはず。

gauche-packageを活用する方向でまとめられたらいいな。

参考資料

gauche-package編

Q.拡張ライブラリの雛形を生成するにはどうすればいいですか?

A. gauche-package generate (なんか適当な拡張名)を実行すると雛形が作成できます。

 $ gauche-package generate foobar

Q.拡張ライブラリの雛形はどんなファイルが作成されますか?

A. .stubとか.hとか.cとか.scmとか.acとかです。

 $ cd gauche-foobar
 $ ls
 DIST         VERSION    configure.ac  foobar.h    foobarlib.stub
 Makefile.in  configure  foobar.c      foobar.scm  test.scm

Q.拡張ライブラリの雛形をビルドするにはどうすればいいですか?

A. ./DIST gen;./configure;makeを実行します。

 $ ./DIST gen
 $ ./configure
 $ make

Q.configureが生成するVERSIONが1.0になっています。変更するにはどうすればいいでしょうか?

A.configure.acでそう指定されているからです。

 AC_INIT(foobar, 1.0, shiro@acm.org)

適当なバージョンに書き換えましょう。あと、メールアドレスもついでに変更しておきましょう。
変更し終わったら、./DIST genを再度実行するのを忘れずに。

Q.生成されるdllの名前を変更したいです。どうすればいいでしょうか?

A.gauche-packageに渡す引数を変更するといいと思います。

Gaucheの拡張ライブラリのdllと元となるライブラリのdll名が一緒なのが問題なら、 gauche-package compileに渡す引数を変更してあげると良いです。 たとえばgauche--foobar.dllが生成されるようにしたいなら、Makefile.inを以下のように 変更してあげるとうまくいきます。Makefile.inを変更したら、configureの再実行をお忘れなく。

 foobar.$(SOEXT): $(foobar_SRCS)
        $(GAUCHE_PACKAGE) compile \
          --local=$(LOCAL_PATHS) --verbose gauche--foobar $(foobar_SRCS)

Q.雛形のディレクトリ構造でfoo.barを用意したいです。どうしたらいいでしょうか?

A.gauche-package generate gauche-foobar2 foo.barとか実行してみるのはどうでしょうか。

 $ ls -R gauche-foobar2/
 gauche-foobar2/:
 DIST         configure.ac  gauche_foobar2.c  gauche_foobar2lib.stub
 Makefile.in  foo           gauche_foobar2.h  test.scm
 
 gauche-foobar2/foo:
 bar.scm

Q.雛形のディレクトリ構造を変えるにはどうしたらいいでしょうか?

A.gauche-package generateはフラットな階層で拡張に必要な雛形ファイルを生成します。 とはいえlibとかtestとかsrcディレクトリを切りたくなったりします。

Makefile.inをsrc/Makefile.inなどとしてコピーして、 configure.inの AC_OUTPUTに src/Makefileを追加したりするといいんじゃないでしょうか。


stub編

Q.stubファイルを分割することはできますか?

A.できます。その際はモジュールの初期化関数(Scm_Init_XXXX)内で追加したstubファイルの 初期化関数を登録してあげる必要があります。

例えば、foobar.cがあって、foobar2.stubを追加したならScm_Init_foobar内で以下の ようにfoobar2.stubから生成されるcの初期化関数を登録してあげます。modはScmModuleへのポインタです。

 Scm_Init_foobar2(mod);

Q.stubファイルから生成される.cファイルを確認したいのですがどうしたら良いでしょうか?

A. gauche-package compileではstubファイルから生成した.cファイルを残さないので、 genstubで.cファイルの生成をやりましょう。

以下のコマンドを実行することで、foobarlib.stubからfoobarlib.cが生成されます。 .cのソースを確認して問題となる箇所を調べてみましょう。

 gosh `gauche-config --syslibdir`/genstub foobarlib.stub

Q.enumはどう扱ったら良いですか?

A.define-enumというのがありますのでそれを使いましょう。

 (define-enum Gaucheでの定義名 Cでの定義名)

Q.Cの関数はどう扱ったら良いですか?

A.define-cprocを使いましょう。

 (define-cproc test-foobar () ::<const-cstring>
  (result "foobar is working"))

戻り値として文字列へのポインタを返すような場合は、上記のように書くことができます。 (resultを使うと戻り値関連の変換コードを面倒見てもらえるので便利です。

Q.void*はどのように扱ったら良いのでしょうか?

A. Gauche拡張ライブラリ入門?のvoid*の項が参考になるかも知れません。


テスト編

Q.テストを実行するにはどうすればいいですか?

A. make checkを実行しましょう。

 $ make check

Q.テストを実行したらモジュールのロードに失敗します。どうしたらいいでしょうか?

A.生成されるdllとuseしているモジュール名が一致していることを確認しましょう。

 Testing foobar ...                                               gosh: "error":
 Compile Error: can't find dlopen-able module "foobar"
 "././test.scm":8:(use foobar)
 
 make: *** [check] Error 1

例えば、元々foobar.dllを生成していたのをgauche--foobar.dllに変更したなら foobar.scmのdynamic-loadも変更しないといけません。

 ;; Loads extension
 (dynamic-load "gauche--foobar")

Gauche Nightly Tester Builds

当初はVS2005でビルドしてみるという企画だったのが、svn HEADでのWindowsサポートがすすんだので、 拡張を含めたインストーラを作ってみる企画へ趣旨換え。Shibuya.lisp #6 LTにて発表した。(2010年)

対応してみたつもりの拡張

svn HEADでOpenGLは標準サポートされたようです。0.9.1がリリースされたころの話。

Gauche Night

Gauche GongでGauche-hpdfについてのデモをしました。(2007年)

Gauche-hpdf

libharuのGaucheバインディング。PDFがつくれます。現在開発はgithub上で行っています。

Windows関連のメモ

kenhys:log2011

More ...