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 

とやるだけで、元の 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

*1:*.scm と *.sci だと sci が優先されるようです。

*2: