SpiderMonkey のビルドに四苦八苦中

以前 SpiderMonkey 1.60 の頃に tarball 取ってきて VS2005 でビルドしてみたことがありますが、あのときはなんというか、苦難の道だったなあという印象がまず第一です。
まず、Visual Studio 用のプロジェクトファイルである js.mdp が tarball に入っているのですが、VS2005 で import しようとすると変換エラーが出て使えない。仕方ないので nmake 用の js.mak を使ってビルドしようとすると、jsiter.{cpp,h} に対する dependency が足りなくてエラーが出る。
じゃあ最近はどうなのかなあと思って調べてみると、1.70 の tarball が出ているのがわかりましたが、せっかくなら trunk のコードをビルドしてみたくなりまして。で、今日は一日四苦八苦してました。


まずは、ビルド環境なのですが、Windows の場合 MozillaBuild というビルド環境構築用のパッケージが用意されており、それを使うのがよいとのこと。(Windows Build Prerequisites) MozillaBuild は、MSYS (要するに MinGW のツール群)などをベースに構築されていますが、Mercurial などのツールも入っているので先にインストールしておくのが手軽のようです。
もちろんこのほかに Visual C++ コンパイラ類と、MozillaBuild の起動には Microsoft Platform SDK (2008 は環境を壊すので使ってはいけないそうです)が必要となります。これらの準備ができたら、MozillaBuild のプロンプトを立ち上げてその環境でビルド操作を行います。


まずソースコードの checkout。Getting SpiderMonkey source code に手順が書いてあります。
tarball を使う手もありますが、ここでは mercurial で拾ってきましょう。

$ mkdir /path/to/workdir; cd /path/to/workdir
$ hg clone http://hg.mozilla.org/mozilla-central/

次にビルド。基本手順は SpiderMonkey Build Documentation にありますが、autoconf → configure → make です。

$ cd mozilla-central/js/src
$ autoconf-2.13
$ ./configure
$ make

ここで、autoconf は 2.13 でなければならないようです。違うバージョンのものを使うとエラーが出ます。
とりあえずこれでひとまずビルドできることは確認できました。


その後 thread safe な SpiderMonkey をビルドしてみようとしてはまってます。
nspr をビルド、インストールし、configure にスレッディングオプションをつけてみたはよいものの、今度は DLL の作成でこけます。

$ cd ../../nsprpub
$ ./configure --prefix=D:/Devel/mozilla --enable-optimize --disable-debug
$ make && make install
...

$ cd ../js/src
$ ./configure --prefix=D:/Devel/mozilla --with-nspr-prefix=D:/Devel/mozilla --with-system-nspr --enable-threadsafe
$ make
...
link -NOLOGO -DLL -OUT:js3250.dll -PDB:js3250.pdb -SUBSYSTEM:WINDOWS  jsapi.obj
jsarena.obj jsarray.obj jsatom.obj jsbool.obj jscntxt.obj jsdate.obj jsdbgapi.ob
j jsdhash.obj jsdtoa.obj jsemit.obj jsexn.obj jsfun.obj jsgc.obj jshash.obj jsin
terp.obj jsinvoke.obj jsiter.obj jslock.obj jslog2.obj jsmath.obj jsnum.obj jsob
j.obj json.obj jsopcode.obj jsparse.obj jsprf.obj jsregexp.obj jsscan.obj jsscop
e.obj jsscript.obj jsstr.obj jsutil.obj jsxdrapi.obj jsxml.obj prmjtime.obj jstr
acer.obj Assembler.obj Fragmento.obj LIR.obj RegAlloc.obj avmplus.obj Nativei386
.obj jsbuiltins.obj     -NXCOMPAT -SAFESEH -DYNAMICBASE    -LD:/Devel/mozilla/li
b -lplds4 -lplc4 -lnspr4 kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib
 advapi32.lib
LINK : warning LNK4044: オプション '/LD:/Devel/mozilla/lib' は無効です。無視され
ます。
LINK : warning LNK4044: オプション '/lplds4' は無効です。無視されます。
LINK : warning LNK4044: オプション '/lplc4' は無効です。無視されます。
LINK : warning LNK4044: オプション '/lnspr4' は無効です。無視されます。
jsapi.obj : MSIL .netmodule または /GL を伴ってコンパイルされたモジュールが見つ
かりました。/LTCG を使用して再開始してください。リンカのパフォーマンスを向上させ
るためには、コマンドラインに /LTCG を追加してください。
LINK : warning LNK4044: オプション '/LD:/Devel/mozilla/lib' は無効です。無視され
ます。
LINK : warning LNK4044: オプション '/lplds4' は無効です。無視されます。
LINK : warning LNK4044: オプション '/lplc4' は無効です。無視されます。
LINK : warning LNK4044: オプション '/lnspr4' は無効です。無視されます。
   ライブラリ js3250.lib とオブジェクト js3250.exp を作成中
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_NotifyCondVar" は未解決です。

jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_Lock" は未解決です。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_AtomicDecrement" は未解決です
。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_DestroyCondVar" は未解決です
。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_NewLock" は未解決です。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_NewCondVar" は未解決です。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_Unlock" は未解決です。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_AtomicIncrement" は未解決です
。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_DestroyLock" は未解決です。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_WaitCondVar" は未解決です。
jsapi.obj : error LNK2001: 外部シンボル "__imp__PR_NotifyAllCondVar" は未解決で
す。
jscntxt.obj : error LNK2001: 外部シンボル "__imp__PR_GetCurrentThread" は未解決
です。
jscntxt.obj : error LNK2001: 外部シンボル "__imp__PR_NewThreadPrivateIndex" は未
解決です。
jscntxt.obj : error LNK2001: 外部シンボル "__imp__PR_GetThreadPrivate" は未解決
です。
jscntxt.obj : error LNK2001: 外部シンボル "__imp__PR_SetThreadPrivate" は未解決
です。
prmjtime.obj : error LNK2001: 外部シンボル "__imp__PR_CallOnce" は未解決です。
js3250.dll : fatal error LNK1120: 外部参照 16 が未解決です。
make[1]: *** [js3250.dll] Error 96
make[1]: Leaving directory `/d/Devel/mozilla/mozilla-central/js/src'
make: *** [default] Error 2

$

エラーメッセージは未解決シンボルですが、直前にリンカが警告を出しており、nspr のライブラリ指定が無視されていることによるもののようです。Windows の link.exe は GNU ld ではないので、-L とか -l とか使えないのですが、nspr のリンカオプションが適切に設定されていないのが原因だと思われます。
configure が作成する config/autoconf.mk を修正して Windows の記法に合わせてみると、今度はそのライブラリが dependency に入ってしまって見つからないとエラー。
このへんは make の rule で吸収すべきところだと思うのですが、どうもうまくない…。configure の責任か、それとも rules.mk の責任か。よくわかりません。


かといって、Makefile.ref を使うと今度は prmjtime.cpp のビルドでエラーになります。
こっちは now() とかを実装しているコードなのですが、コンパイラオプションが足りないのか、プラットフォームの日時取得 API が判別できないと言ってきます。
Makefile によるビルドではちゃんと通過しているので、おそらくコンパイラオプションなんだろうけれど…といったところで今日は時間切れ。


そもそも、Makefile を使うのが正しいのか、Makefile.ref を使うのが正しいのかよくわからなかったりして。
これに比べて V8 のビルドの簡単さはほんと、ありがたいですわ。