SmartPhone開発日記【あいほーん】AndroidNDKでGNUSTLの罠

C++STLをAndroidNDK上で使うには、STLPortを使うやり方とGNUSTLを使うやり方といくつか方法があります。
NDK5から通常は、Application.mkファイルへ

APP_STL := stlport_static

APP_STL := gnustl_static

のどちらかの値を入れて、STLを有効にしますが、gnustl_staticはPlatform-7以前で動作しないようです。
Platform-7以前へバージョンを下げて、STL入りのソースでビルドー>lib****.soモジュールをロードするタイミングで何故かエラーを出してアプリが落ちてしまいます。

NDKの怖いところはこのロードタイミングで落ちると何がなにやらという状態で、ソースを削ったりビルドターゲットを変えたり、DEBUGビルドにしたりと、原因がわからず瞑想するポイント・・・・。

最初原因がわからず色々調べてみると、AndroidNDK付属の逆アセンブルツールなるものがあり、それを使うとログで出たアドレスを元にエラー元のシンボルまではわかるようなので、それでトレースしてみると__eh_globals_init::~__eh_globals_init() というシンボル内でエラーが発生してる模様。
アプリケーション内のソースでグローバルで何か初期化しているものが悪さしてると思い、色々ソースを外してみると、どうやら#include <**> でSTLを引っ張ってるソースが原因と判明。
STLのグローバルで何かやってる処理がおかしなことになってるようで・・・・・

別のSTLが無いか探してみるとstlport_staticとgnustl_staticと二つあり、設定していたのがgnustl_staticだったので、stlport_staticに変更 ー> あっさりとPlatform-4で動作。

Android2.1以降でgnustl_staticが動けばまあそれはそれでよかったのですが、Android2.1は現状無視できないのでgnustl_staticは不採用としました。

うーん 固いライブラリ系でハマるのは非常に痛い。

SmartPhone開発日記【あいほーん】AndroidNDKで並列コンパイル

AndroidNDKを使うにあたって、大量にソースコードが増えてきた場合、マルチコアCPUによる並列ビルドを使うとコア数に合わせてビルド時間が短縮されます。XCodeは自動的にやってくれるものの、AndroidNDKではどうするのかよくわからずしばらくドキュメントに目を通していたところ、ndk-buildのオプションでスレッド指定するとすべてのCPUを使ってくれるようです。

やり方は非常に簡単!
$ ndk-build --jobs=4
とすることで4つスレッドが使われ、旧MacBookPro(2Core4Thread)のCPUでまんべんなく使われるようになります。他、AndroidNDKでのネットワーク分散ビルドのためのdistcc/distccdを見ていたところなかなかやり方がわからず、妥協。
EC2 in Japanのベクトルコンピュータを借りて分散させたりすると相当作業時間の短縮が見込めると思うんだけど・・・・・。先日ESEC展示会でアマゾンの人と話していて、EC2は単位時間あたりの課金でベクトルコンピュータ相当のインスタンスを借りてもそこまで料金的には高くないようで、$100を超えないように使ったりも出来て割と現実的です。

C++コンパイルは非常に時間がかかる性質があり分散コンパイルによる効果が高いのですが、Cのソースだと単一ファイルのコンパイルが短いので分散してもそこまでリターンは見込めないため、分散をやりたい人はその点を指標に導入を検討すると良いと思います。