ライブラリサーチパスの取得 - nmosh / Racket / Gauche / chibi-scheme / Sagittarius
DLLのソースコード生成は完成してGitHubにpushしたが特に書くことが無かった。。
というわけで淡々と続きを作っていく。今回はライブラリサーチパスの取得。
どこにDLLを配置するか問題
そろそろyuniFFIについてもテスト環境を構築する必要が有る。yuniFFIがサポートしようとしているScheme処理系は:
- nmosh - Win32 / Win64 / Cygwin64 / MacOSX amd64 / Linux amd64 / FreeBSD amd64
- Racket - Win64
- Gauche - Cygwin32
- chibi-scheme - Cygwin64
- Sagittarius - Win64 / Cygwin64
- Vicare - Linux amd64
- Larceny - Linux amd64
今はゲーム開発の方が忙しい状況で、手元のマシンを全部Windows/Macにしている。というわけでLinux/BSDはVMでしかテストできないので優先度が下がり気味という状況にある。
というわけで、開発効率を意識しつつ以下のようなルールを決めた:
- Windows上ではテストツリーと開発ツリーを分離しない。VisualStudio等で直接デバッグするため。
- つまり、Win32 / Win64 / Cygwin32 / Cygwin64で同一ツリーにDLLを配置できる必要がある。他の環境は後で考える。
- Windows / MacOS / Linux / FreeBSDではツリーを混ぜない。
yuniのツリーを`run/buildstub.sh`でビルドすると、ディレクトリ`lib-stub`が生成され、各種Scheme処理系に合わせたライブラリwrapperが生成される。このlib-stubをDLLの配置場所に流用し、以下のように配置することにする。
lib-stub/ + yunistub-win32/yunistub_SDL2.dll + yunistub-win64/yunistub_SDL2.dll + yunistub-cygwin32/cygyunistub_SDL2.dll + yunistub-cygwin64/cygyunistub_SDL2.dll + yunistub/libyunistub_SDL2.so + yunistub/libyunistub_SDL2.dyld
つまりWindowsだけABI固有ディレクトリを持ち、それ以外のOSでは、単にlib-stub/yunistubを使用する。
Scheme側のライブラリは"yunistub_SDL2"という名前でこれらのDLLなりsoなりdyldにアクセスするが、ランタイムライブラリがプレフィックスやライブラリパスを補って総当たりで検索することになる。
各種Scheme処理系でのライブラリパスの取得
大抵のScheme処理系では、ライブラリパスをコマンドラインによって指定することができる。yuniのリポジトリには、サポートしている処理系向けに、リポジトリ内のライブラリをライブラリパスに含めて処理系を起動するためのスクリプトが色々揃えてある( https://github.com/okuoku/yuni/tree/master/run )。
しかし、このライブラリパスを取得するための方法は処理系によってマチマチなので、compatレイヤとして処理系毎に実装してやる必要がある。
nmoshはグローバル変数`prefix-list`にライブラリパスを格納しているので、それをprimitives構文でインポートしてやればアクセスできる。
... ちゃんとAPIにした方が良さそうだ。
Racketは、(racket base)ライブラリにあるcurrent-library-collection-pathsパラメタで取得することができるが、取得できるのはpathオブジェクトのimmutableなpairでできたlistであるため、mapとpath→string手続きで変換してやる必要がある。
... そして、R6RSのmapはmutableなpairでできたlistのmapであるため、Racketのmapを明示的にimportしてきて使用する必要がある。
Gaucheはグローバル変数*load-path*にライブラリパスを格納している。というわけで、専用のGaucheモジュールを用意し、それをR7RSライブラリにimportしてアクセスする。
(gauche base)あたりのモジュールでエクスポートされていると思いきや存在しないようだ。
ドキュメントされていないパラメタcurrent-module-pathでライブラリパスにアクセスできる。
Sagittariusは組込み手続きのload-pathでライブラリパスにアクセスできる。