precomp 使うと C のコードも生成してくれるんだ。
何が目的ということもなく precomp で Gauche のスクリプトを dynamic-load できるようにコンパイルしてみた。
調べたこと、やったこと
ext/util/Makefile にこんなのがあったので
$(PRECOMP) -e -P -o util--match $(top_srcdir)/libsrc/util/match.scm
trunk を PRECOMP で grep 検索してみるとこんなの見つかる。
./ext/Makefile.ext:46:PRECOMP = $(GOSH) $(top_srcdir)/src/precomp
そこでこんな感じで実行してみます。
gosh ~/src/System/gauche/trunk/src/precomp -e -P -o net--favotter \ ~/share/lib/gauche/net/favotter.scm
とやると favotter.sci, net--favotter.c の二つが得られる。
最初の Makefile に戻るとこういうのもある。
$(MODLINK) util--match.$(SOEXT) $(util_match_OBJECTS) $(EXT_LIBGAUCHE) $(LIBS)
そこで今度は MODLINK で grep 検索するとこんなのが見つかる。
./ext/Makefile.ext:39:MODLINK = $(CCLD) $(CFLAGS) $(LDFLAGS)
上のマクロは私の環境だとどうやら
CCLD='gcc -std=gnu99' CFLAGS='-g -O2' LDFLAGS=' ' LIBS='-ldl -lcrypt -lutil -lm -lpthread' EXT_LIBGAUCHE=''
になっているようなので、こうやってみるか。
gcc -std=gnu99 -g -O2 net--favotter.so net--favotter.o \ -ldl -lcrypt -lutil -lm -lpthread
gcc: net--favotter.so: そのようなファイルやディレクトリはありません gcc: net--favotter.o: そのようなファイルやディレクトリはありません
よく考えるとまだ object ファイルは生成していないな。
もうめんどくさくなってきたので一回 make してどんなことしてるか見てみるか。
../../src/gosh -ftest ../../src/precomp -e -P -o util--match ../../libsrc/util/match.scm gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../../src -I../../gc/include -g -O2 -fPIC -fomit-frame-pointer -march=i686 -DUSE_I686_PREFETCH -c util--match.c gcc -std=gnu99 -g -O2 -fPIC -shared -o util--match.so util--match.o -L../../src -ldl -lcrypt -lutil -lm -lpthread
なので適当にディレクトリ構成を直して
gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ~/src/System/gauche/trunk/src \ -I ~/src/System/gauche/trunk/gc/include \ -g -O2 -fPIC -fomit-frame-pointer -march=i686 \ -DUSE_I686_PREFETCH -c net--favotter.c gcc -std=gnu99 -g -O2 -fPIC -shared \ -o net--favotter.so net--favotter.o \ -L../../src -ldl -lcrypt -lutil -lm -lpthread
- 環境変数 GAUCHE_DYNLOAD_PATH に ~/lib/gauche を設定
- 生成された net--favotter.so をそのディレクトリの直下へ配置。
- favotter.sci を favotter.scm と同じディレクトリに配置。*1
とやるだけで、元の scm ファイルと同じように使えるようになった!完全に一緒なのかどうかはわからないけど。。まだ私がほとんど理解できていない継続 (call/cc) があるときはまた何かが違ってくるのかも。
まとめ
- precomp で *.c と *.sci ファイルが生成される。
- *.sci は dynamic ライブラリへのポインタ。 dynamic-load でライブラリをロードする。
- gcc で *.c ファイルを割と普通にコンパイルすれば dynamic link ライブラリが生成される。
そういえば gauche の benchmark ってどうやるんだろうか。比較してみたかったんだ。よく考えるとこういうネットワークアクセスするライブラリって benchmark するのに適切なライブラリではないな。というところに私の浅はかさが表れています。orz
C からこの dynamic link library 呼び出せるなら、次からは C の案件もほとんど gauche でできますね!*2