ところが、自分の環境(Windows 8.1+Haslell Platform 2014.2.0.0)でbzlibパッケージをインポートするサンプルプログラムをビルド・実行しようとすると、以下のようなエラーになってしまいました。
> runghc examples/bunzip2.hs bunzipz2.hs: C:\Users\XXX\AppData\Roaming\cabal\x86_64-windows-ghc-7.8.3\bzlib-0.5.0.5\HSbzlib-0.5.0.5.o: unknown symbol `fileno' bunzip2.hs: bunzip2.hs: unable to load package `bzlib-0.5.0.5'ネット上の情報を漁ってみたのですが同じ問題に遭遇している人はいなさそう・・・。ということで、自力で調べてみました。以下、分かったことと回避方法をまとめておきます。
問題の原因:
- 詳細は「調査の内容」に記しましたが、bzlibが内部で呼び出しているfileno()とfdopen()が定義されているmingwのlibmoldname.aがリンクされないのが原因のようです。
問題の回避方法
- libmoldname.aをリンクする修正が正しいのですが、その方法が分からなかったため、bzlibのコードに手をいれてileno()とfdopen()を呼ばないバージョンをビルドし、それで正規のパッケージを置き換えることで、bzlibが利用できるようになりました。以下、その手順です。
- cabalのpackageがダウンロードされているディレクトリに移動する
- bzlib-0.5.0.5.tar.gzを展開する
- このパッチをDLしてbzlib.patchという名前で保存し、適用する
- パッチを含んだアーカイブでオリジナルのbzlib-0.5.0.5.tar.gzを置き換える
- bzlibパッケージをreinstallする
% cd C:\Users\XXX\AppData\Roaming\cabal\packages\hackage.haskell.org\bzlib\0.5.0.5
% tar xzf bzlib-0.5.0.5.tar.gz
% patch -p1 < bzlib.patch
% tar czf bzlib-0.5.0.5.tar.gz bzlib-0.5.0.5/
% cabal install bzlib --reinstall
調査の内容:
- 自分の環境にcygwinとHaskell付属のmingwの両方が存在しているが原因かと思ったがそうではないらしい。
- mingwのライブラリにもfilenoがちゃんと用意されている。
- mingw環境においてここのfilenoのサンプルがビルドでき、動作しているため
- > gcc fileno.cpp
- mingw環境の確認
- filenoを利用するC言語版サンプルをビルドしてmapファイルを出力したところ、filenoはlibmoldname.aというライブラリの定義をリンクしていることが分かった。
- gcc -Wl,-Map=a.map -g fileno.cpp
.text 0x0000000000402c10 0x8 c:/program files/haskell platform/2014.2.0.0/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/lib/../lib/libmoldname.a(dnvzs00026.o) 0x0000000000402c10 fileno
- filenoがunknown symbolとなっているのは以下の2つのオブジェクトファイル
- bzlib-0.5.0.5/dist/build/cbits/bzlib.o
- bzlib-0.5.0.5/dist/build/cbits/HSbzlib-0.5.0.5.o
- 上記オブジェクトファイルで同じくunknown symbolになっているfopen, fread, fwrite, fcloseといった関数はlibmoldname.aとは別のlibmsvcrt.aにアーカイブされている。
- a.mapより
.text 0x0000000000402c70 0x8 c:/program files/haskell platform/2014.2.0.0/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/lib/../lib/libmsvcrt.a(dnhvs00971.o) 0x0000000000402c70 fopen .text 0x0000000000402c78 0x8 c:/program files/haskell platform/2014.2.0.0/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/lib/../lib/libmsvcrt.a(dnhvs00979.o) 0x0000000000402c78 fread
- 試しに、libmoldname.aを削除してcabal buildをビルドしてみたところ、リンクエラーになりました。ということは、パッケージビルド時にはlibmoldname.aをリンクしようとしていることになります。・・・ハズレ。
Resolving dependencies... Configuring bzlib-0.5.0.5... Building bzlib-0.5.0.5... Preprocessing library bzlib-0.5.0.5... c:/program files/haskell platform/2014.2.0.0/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmoldname c:/program files/haskell platform/2014.2.0.0/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmoldname collect2: ld returned 1 exit status linking dist\build\Codec\Compression\BZip\Stream_hsc_make.o failed (exit code 1) command was: C:\Program Files\Haskell Platform\2014.2.0.0\mingw\bin\gcc.exe dist\build\Codec\Compression\BZip\Stream_hsc_make.o dist\build\Codec\Compression\BZip\Stream_hsc_utils.o -o dist\build\Codec\Compression\BZip\Stream_hsc_make.exe -LC:\Users\XXX\AppData\Roaming\cabal\x86_64-windows-ghc-7.8.3\bytestring-0.10.4.1 -LC:\Program Files\Haskell Platform\2014.2.0.0\lib\deepseq-1.3.0.2 -LC:\Program Files\Haskell Platform\2014.2.0.0\lib\array-0.5.0.0 -LC:\Program Files\Haskell Platform\2014.2.0.0\lib\base-4.7.0.1 -lwsock32 -luser32 -lshell32 -LC:\Program Files\Haskell Platform\2014.2.0.0\lib\integer-gmp-0.5.1.0 -LC:\Program Files\Haskell Platform\2014.2.0.0\lib\ghc-prim-0.3.1.0 -LC:\Program Files\Haskell Platform\2014.2.0.0\lib/rts-1.0 -lm -lwsock32 -lgdi32 -lwinmm
- これはどこの設定に書かれているのか・・・?
備考:
- 冒頭に書いたとおり、本来ならば適切にlibmoldname.aをリンクするように修正するのが正しい解決方法なのですが、bzlibパッケージの中にそのような見つからず、どこを変えれば良いか分かりませんでした・・・。orz 。どこを修正すればリンクライブラリを追加できるか知っている方、是非ご教示ください。 m(_ _)m
- unknown symbolとなるfilenoとfdopenはbzlib-0.5.0.5/cbits/bzlib.cの中で呼び出しています。コードを確認したところどちらも環境によってはundefされており、呼び出さなくても問題はないことを確認しました。
- なお、Linux, Mac環境上ではこの問題は発生しません。問題なく利用できています。
0 件のコメント:
コメントを投稿