October 2010 Archives

autotoolsとNDKの併用

| No Comments | No TrackBacks

Android NDKでautotoolsベースのライブラリをビルド出来ないかと何日か試していたのだけど、けっこう上手く行っていなかった。昨日何とかそれらしい共有ライブラリのビルドが出来たので、まだ動作確認出来ていないけどとりあえず載せておこうと思う。基本部分は先日書いた簡単なビルドの紹介文から。

export ANDROID_ROOT=/cygdrive/c/android-ndk-r4b
export PATH=$PATH:$ANDROID_ROOT/build/prebuilt/windows/arm-eabi-4.2.1/bin
export ANDROID_VER=8 # could be 3, 4, 5 or 8
echo RUN: ./configure --host=arm-eabi CC=arm-eabi-gcc CPPFLAGS="-I$ANDROID_ROOT/build/platforms/android-$ANDROID_VER/arch-arm/usr/include/" CFLAGS="-nostdlib" LDFLAGS="-Wl,-rpath-link=$ANDROID_ROOT/build/platforms/android-$ANDROID_VER/arch-arm/usr/lib/ -L$ANDROID_ROOT/build/platforms/android-$ANDROID_VER/arch-arm/usr/lib/" LIBS="-lc "
echo THEN RUN: make
echo NOTE: to link with libc, use: -L $ANDROID_ROOT/build/platforms/android-X/arch-arm/usr/lib -lc
echo NOTE: to generate shared library from static library, run:
echo $ arm-eabi-gcc -nostdlib -shared -s -o YOUR_LIBRARY.so --whole-archive -Wl,-whole-archive YOUR_PROJECT/src/.libs/YOUR_LIBRARY.a -Wl,-no-whole-archive --no-whole-archive -L /cygdrive/c/android-ndk-r4b/build/platforms/android-$ANDROID_VER/arch-arm/usr/lib -lc

これは実際には環境変数などを適当に設定しているだけで、コマンドの実行は使う人に見せているだけだ。その内容も、configure, makeした後、手動でldを呼び出して、静的ライブラリ(.aファイル)から共有ライブラリ(.soファイル)を生成する、というだけの手順だ。ビルドした.soファイルは手動で jni/../libs にコピーする必要がある(JNIを使う場合)。

ld(コマンドライン上はarm-eabi-gcc)の呼び出しで行っているのは、autotoolsに基づくconfigureとmakeでビルドした静的ライブラリから、jniで使用するような動的ライブラリを生成するということだ。

このオプションで重要なのは、-Wl,-whole-archive と -Wl,-no-whole-archive で、これは静的ライブラリで参照されていないコードを削除するというldの機能を制御することにある。

通常のhello worldをビルドする場合などを例として考えれば分かると思うけど、hello worldではprintfで使用されるコードだけがlibcの静的ライブラリ(libc.a)から取り出されて、実行ファイル上にリンクされて埋め込まれる。libc全体をリンクしたら、hello worldの実行プログラムのサイズはlibcを上回るものになるはずだけど、そうならないのは、libcで使われていないコードをstripしてリンクしているからだ。

でも、このstripする動作は、ビルドされた静的ライブラリの機能全体を共有ライブラリに取り込みたい場合には適合しない。ライブラリの機能を全て参照するコードなんて(通常は)書かれていないし、自分でも書かない(いずれにしろ自動化できない)からだ。でも、-Wl,-whole-archiveを指定すると、このstrippingを行わないようにしてくれる(ちなみに "-Wl,-whole-archive" で1つのオプションになっていることに注意)。

stripが適正に行われていないと、共有ライブラリの生成はエラーなしで成功しているかのように見えるけど、生成されたファイルは1kb前後しか無く、リンクが正しく行われていないことが分かる。

あと標準ライブラリは自動的に取り込まず、-nostdlibでいったん無効にした後、-lc で明示的にlibcを指定している(-Lでライブラリのロードパスを指定してリンクするbionic libcを選んでいる)。

本当はこの辺の事はndk-buildで出来ればよいのだけど、後述する参考サイトにある通り、どうやら途中までしか出来ていないようだ。

最後に、基本情報として使用したサイト以外の参考情報を載せておこうと思う:

  • GNU リンカldの使い方(マニュアル)。これを全部読んだわけではなく、静的ライブラリのリンクに関する引数を探した。
  • このフォーラムエントリでは、ビルドオプションの指定で何が足りないとどういうエラーになるかというのを、詳細に説明している。とても教育的でエラーフレンドリだ。
  • このstackoverflowのエントリでは、NDK r4bで静的ライブラリをAndroid.mkでビルドに取り込みつつ不要なコードをstripしない方法について説明してある。どうやらNDK r4bでちゃんと実装されていない部分のようだ。

playing around ndk

| No Comments | No TrackBacks

しばらくここに書いていなかったので、昨日書いたネタも割と唐突な感じに見えてきた。というわけで、GUI設計まわりで少しここに雑然としたメモを残しておこうと思う。

  • JavascriptでRaphaelを使うことを考えたが、これはSVGまたはVMLというアプローチを採るようで、これではAndroidで使えない。
  • OpenGLで自前で実装するのは大変そうなので、それはやめておこうと思った。
  • OpenGL本家にはglutのようなものがあるが、C#で使おうと思ったら、OpenTKには無いので使いようがない。むしろglutやSDLをP/Invokeしているライブラリの方が可能性があるかもしれない(ただしSilverlightでは使えなくなる)。
  • OpenVGというものがあるらしいが、まだ始まったばかりでAndroidなどでも実装が無いようだ。もしかしたらAndroidでも動くリファレンス実装があるのかもしれないけど。

今考えているのが、最新のAndroidではSVGが有効になっているはずなので、それをandroidのソースツリーから引っ張ってきて、自前でwebkitごとNDKでビルドしてしまうという方法だ。NDKはもともとandroidのソースと同じ構成を採用しているはずなので、敷居は高くないだろう(と思いたい)。ただ、そうするとandroid.webkitはjniで直接システムのandroidを呼び出すことになるかもしれないから(apkでjniを解決するかに依る)、場合によってはandroid.webkitも自前でビルドしてパッケージすることになるかもしれない。それは名前がかぶらないように変更したりしないといけないだろうし、そもそも可能なのかどうかも怪しいところだ。まあ、必ずしもwebkitの別のバインディングを使えば、必ずしも既存のJNIコードを利用する必要は無いとは思っている。

そんなわけで、試しにいじってみる余地がありそうだ。もしかしたら既に誰かが試しているかもしれないけど。

NDKまわりは、他の観点でも興味があって、いずれ真面目に使えるようになろうと思っている。といっても、既存のソースコードを取り込みたいだけなのだけど。autotoolsを使っているプロジェクトからライブラリをビルドする方法については、簡単なブログエントリでまとめられていたので、それを参考にしてライブラリをビルド出来そうだ。ただ、やはりAndroid.mkを自前で書いて中にソースファイル名を列挙するのは面倒なので、その辺も自動的にやっつけられないかと思っている。

もっとも、取り込みたいプロジェクトがautotoolsでなくcmakeだったりもして、どこから手を付けたら良いやらという感じでもある。

HTML5 Canvasいじり

| No Comments | No TrackBacks

いまGUIデザイナーの類でも作ってみようかと思っているのだけど、なかなか進まない。以前にも書いたと思うけど、Android環境ではSVGが使えないので、vector graphicsベースの部品が使えない。それならとりあえず非vectorのCanvasを使って書かなければならないだろう。分かってはいるのだけど、筋があまり良くなくて面倒なので、手を付けようという気持ちが起こらなくて困っていた。

しかしそう言っていたら進まない。というわけで、とりあえず手を動かしてみようと思って、何となくHTML5 Canvasの習作みたいな感じで、androidのGUI部品をいくつか書いてみた。mldspでやったようにprocessingを使っても良かったのだけど、今回はHTML5 Canvasにしてみた。

ただ、あまり数が多くないことを期待していたandroid.widgetのクラス群だけど、これだけの部品を作るのにも数時間かかって、まだ描画しか出来ていない(ドラッグして移動してプロパティ値を書き換えたりとかが出来ていない)ことを考えると、実用的なものを作ろうと思ったら長大な時間が必要な気もする。あと、TextViewで複数行テキストをどうサポートするかなど、実質的に実装不可能なものが立ちはだかってきたので、HTMLコンポーネントを使い回すなどする必要が出てきて、そうなると最早Canvasではないので、ちょっと立ち止まることにした。

ちなみに当初は、描画だけでなくユーザーインタラクションもある程度サポート出来るようにしようと思っていたのだけど、ボタンやチェックボックスはある程度は簡単にできても、テキストボックスでキーボード入力を受け付けることを考えると、放棄せざるを得ない。そうでなくてもマウスでテキスト選択などもやりたくない。あくまでデザイナーはデザイナーと割り切ってやる必要がありそうだ。

あと、いまAndroidとは別のGUIフレームワークの類を考えているのだけど、やはりテキスト入力などをサポートするとしたら、HTMLなどをベースにしてTextBoxなど既存のGUI toolkitのウィジェットを活用した方が良さそうだ。自前で実装しているものは、そのほとんどが破滅の道を通過しているか、その過程で敗れているかだ。Adobe AIRなど大手の実装ですら苦しい。

まあ、テキスト入力はキャンバス上では行わないようにすれば、問題無いかもしれない。デザイナを使用して作成するGUIの仕様を洗っておく必要がありそうだ。

About this Archive

This page is an archive of entries from October 2010 listed from newest to oldest.

September 2010 is the previous archive.

November 2010 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.23-en