著作一覧 |
x64 rubyでやるようになって、dlが必ずエラーになるのでうんざりして、結局libffi+fiddleを使うようにした。
dlが必ずエラーになるのは、x64ではコールバックがうまくいかないからで、なぜそれを直さないかと言えば、直す未満の問題があると小崎さんの指摘があり(Rubyで学ぶx86_64 ABI)、ではなぜlibffiを正式に入れ込まないかと言えば、MSWin32サポートが心もとない(ということだったと思う)。
で、今は、dlを残しておくけど、必要ならばlibffiをどうにかしてfiddleを使えということらしい。fiddleがあればdl(の.rbのほう)はdl.soではなくfiddleを使う。
で、どうにもいやだが背に腹は代えられないのでmsysを導入する。
bashが動くのは良いけれど、さっそくvcvars_x64.batとかが動かない。ディレクトリセパレータ問題だよ。
見たところ、bash起動前に設定してあるPATH、LIB、INCLUDEについては、ディレクトリセパレータ変換は自動的に行ってくれるようだが、後付けでvcvars*を実行するようなことには耐えてくれないようなので、面倒なのでいい加減なシェルを作って、.コマンドで読み込ませることにする。
export VS100COMNTTOOLS=/c/Progra~2/MICROS~2.0/Common7/Tools export VCDIR=/c/Progra~2/MICROS~2.0/VC export WindowsSdkDir=/c/Progra~2/MIA713~1/Windows/v7.0A export PATH=$VCDIR/bin/amd64:$WindowsSdkDir/bin/NETFX4~1.0TO/x64:$WindowsSdkDir/bin/x64:$WindowsSdkDir/bin:$PATH export INCLUDE=$WindowsSdkDir/include:$VCDIR/include export LIB=$WindowsSdkDir/lib/x64:$VCDIR/lib/amd64 export Platform=X64 export CommandPromptType=Native
これで、x64のVC++が動けるようになった。
で、libffiをgithubからgit clone https://...で取ってくる(と書いておけば、本当はcloneではなくxxxを使えみたいなのがあれば指摘してもらえるだろう)。
READMEを読むとVC++(というよりもcl)をサポートしているから、CCにmsvcc.shを指定しろとか書いてある。で、そうやったらml64でエラーになる。不思議に思ってみると、.386とかいうディレクティブがいきなり書いてあってそれはエラーになるだろう。というか、レジスタもeaxとかばかりだし。
そこでターゲットを指定しなければならないのだとわかり、configureを読みながら次のように実行。
$ ./configure CC="/パス/libffi/msvcc.sh -m64" LD=link CPP="cl -nologo -EP" --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --enable-shared --prefix=/c/Users/arton/64
ところが、--prefixは後で衝撃の事実に見舞われることになる。が、この時点では問題なし。
後で、思い出してうささんの[mswin64] libffiを見たら、ターゲットのことは書いてあった。が、すでにlibffiはfix_src_pathは修正してあるのであった。
で、makeして、make installしたのだが、fiddleのビルドに失敗する。
libffi.lib : warning LNK4003: ライブラリの形式が無効です。ライブラリは無視されます。
えー、とdumpbinをかけると確かにエラーになる。しかもdllがなくてlibだけしか作られていないし。
さらに見ていくと、x86_64-w64-mingw32/src/.libsの下に作成されたlibffi.libとインストールされたlibffi.libで微妙にサイズが異なる。しかも、src/.libsのほうはdumpbinがちゃんと読み込んで処理できる。
ああ、「生成されるlibtoolファイルには余計なことをするバグがある」ってのはこれのことか、と思いながら、.libsのほうのlibffi.libでインストールされたlibffi.libを上書きする。
で、再度、.ext/fiddleの中を消してやって、nmakeすると、今度はfiddle.soができた。
で、nmake test-all TESTS="fiddle"とnmake test-all TESTS="dl"がいずれも通ることを確認。
追記:結局DLLは生成されていないが、ffiとリンクしたいのはfiddleだけなのだからスタティックライブラリで良いことに気付いたので、そこは無視。
ジェズイットを見習え |
GREP_OPTIONS=--text make installするとうまくいくかもです!<br>(libtoolはsrc/直下の生成物(.exeとか)には"%%%MAGIC variable%%%"というようなマジックコメントを埋め込んでいて、インストールするときはgrepでそれを検出したら.libs/以下のやつをインストールする、みたいなことをしているのですが、.exeとかバイナリのやつはgrepがバイナリだなぁと判断してうまく検出できなったりします。ふぅ。(一息で書いてみた。))
おおどうも、ありがとうございます。どうも勝手がわからないのでそういう情報は嬉しいです。<br>ただ、ここで困っていたのはそれとは違う問題みたいです。<br>DLLができていないのは、mingw32(というか64は無いみたいですが)を使ったのでdlltoolがx64に対応していないから(だと思うんだけど、config.logを見てもいまいちよくわからない。Makefileにそれらしいものが無い)<br>で、libffi.lib自体はコピーされているけれど内容がおかしくなるのは、おそらく、以下の実行行で走っているranlibというのがMSVCでリンクした場合は不要なんじゃないかな。<br>libtool: install: ranlib /c/Users/arton/64/lib/libffi.lib
違いましたかー<br>お役に立てず残念。。。