「魔法の杖」アプリ修正版 [OpenCV関係]
先日上げた「魔法の杖」アプリは動作しないことがわかりました。コメントで指摘していただいたおれんじさん、ありがとうございます。
修正版をここにおきました。
こちらをダウンロードして下さい。
先日のファイルをダウンロードして「なんだよ、動かないじゃん」と思った人、申し訳ありませんが、上のリンクでやり直してみて下さい。よろしくお願いします。
今回はOpenCVのフレームワークが全部入っている。そのせいで10MBを超えるサイズになっている。OS Xのフレームワークのメカニズムがよくわかっていない、というのが一番の問題。 前回コメントをもらって再確認した。
最初OpenCVをプライベートフレームワークとしてアプリバンドルに含めると巨大なサイズになってしまう。そこで、独立したファイルになっているdylib(ダイナミックリンクライブラリの形式)のうち、使っていないもの、具体的には実行ファイルのシンボルテーブルをたどって、シンボルが解決した時点でツリーに含まれないファイルを、フレームワークから取り除いた。
例えばOpenCVにはhighguiというウィンドウを表示したりマウスをトラックしたり、という機能が含まれているが、今回のアプリでは使っていない。実行時にローダがシンボルテーブルを解決してライブラリ全部をロードし終わったときに、highguiのファイルは本来ならばロードされない。
古典的なunixのライブラリはファイル単位で必要/不要が決まるので、使わないライブラリファイルは存在する必要がない。フレームワークでも同じだと僕は勝手に思い込んで、いらないファイルを消してサイズを小さくした。
ところがOS Xのフレームワークはファイル単位ではなく、フレームワーク全体としてメモリにロードされるらしい。使わないファイルであってもフレームワーク全体の整合性をとるためにロードされなければならないらしい。このへんのメカニズムは良く理解していない。Appleのドキュメントを探しているけどまだそれらしいものは見つからない。
小さなフレームワークにするためにはフレームワークをコンパイルする時点でいらないものを除いておく必要があるらしい。単なるシンボルテーブルだけでなく、どこかにフレームワーク全体のシンボルを記述するファイルなりブロックなりがあるんだろうと思うんだけど、まだよくわからない。
では、僕のiMacではなぜ動くのか、というとつまらない原因だった。僕のiMacの/usr/local/libには以前のバージョンのOpenCVのunixスタイルのライブラリが残ったままになっていた。アプリをダブルクリックするとローダがシンボルを解決しようとする。プライベートライブラリやフレームワークを探した後、unix標準のライブラリパスを探して/usr/local/libに行き着いて、古いライブラリでシンボルが解決してそれをリンクしてしまっていた。この残骸を消すと僕のiMacでもアプリは動かなくなった。
うーん難しい。フレームワークの形は開発時点では便利なのでOpenCVもフレームワークにして使っていた。しかし配布するときにアプリサイズを気にしだすと問題になる、ということがわかった。
ではどうすればいいか、というと
要研究、です。
修正版をここにおきました。
こちらをダウンロードして下さい。
先日のファイルをダウンロードして「なんだよ、動かないじゃん」と思った人、申し訳ありませんが、上のリンクでやり直してみて下さい。よろしくお願いします。
今回はOpenCVのフレームワークが全部入っている。そのせいで10MBを超えるサイズになっている。OS Xのフレームワークのメカニズムがよくわかっていない、というのが一番の問題。 前回コメントをもらって再確認した。
最初OpenCVをプライベートフレームワークとしてアプリバンドルに含めると巨大なサイズになってしまう。そこで、独立したファイルになっているdylib(ダイナミックリンクライブラリの形式)のうち、使っていないもの、具体的には実行ファイルのシンボルテーブルをたどって、シンボルが解決した時点でツリーに含まれないファイルを、フレームワークから取り除いた。
例えばOpenCVにはhighguiというウィンドウを表示したりマウスをトラックしたり、という機能が含まれているが、今回のアプリでは使っていない。実行時にローダがシンボルテーブルを解決してライブラリ全部をロードし終わったときに、highguiのファイルは本来ならばロードされない。
古典的なunixのライブラリはファイル単位で必要/不要が決まるので、使わないライブラリファイルは存在する必要がない。フレームワークでも同じだと僕は勝手に思い込んで、いらないファイルを消してサイズを小さくした。
ところがOS Xのフレームワークはファイル単位ではなく、フレームワーク全体としてメモリにロードされるらしい。使わないファイルであってもフレームワーク全体の整合性をとるためにロードされなければならないらしい。このへんのメカニズムは良く理解していない。Appleのドキュメントを探しているけどまだそれらしいものは見つからない。
小さなフレームワークにするためにはフレームワークをコンパイルする時点でいらないものを除いておく必要があるらしい。単なるシンボルテーブルだけでなく、どこかにフレームワーク全体のシンボルを記述するファイルなりブロックなりがあるんだろうと思うんだけど、まだよくわからない。
では、僕のiMacではなぜ動くのか、というとつまらない原因だった。僕のiMacの/usr/local/libには以前のバージョンのOpenCVのunixスタイルのライブラリが残ったままになっていた。アプリをダブルクリックするとローダがシンボルを解決しようとする。プライベートライブラリやフレームワークを探した後、unix標準のライブラリパスを探して/usr/local/libに行き着いて、古いライブラリでシンボルが解決してそれをリンクしてしまっていた。この残骸を消すと僕のiMacでもアプリは動かなくなった。
うーん難しい。フレームワークの形は開発時点では便利なのでOpenCVもフレームワークにして使っていた。しかし配布するときにアプリサイズを気にしだすと問題になる、ということがわかった。
ではどうすればいいか、というと
- プライベートフレームワークではなくプライベートライブラリの形式にする
- いらないファイルを除いたフレームワークを定義しなおしてコンパイルする
- 必要なソースをアプリのソースの中に含めてしまう
要研究、です。
2013-09-02 22:09
nice!(0)
コメント(0)
トラックバック(0)
コメント 0