eaglesakuraの技術ブログ

twitterから派生した、技術的にちょっと込み入った話題とか。

Android NDKで"Unknown Application ABI:" エラーが発生した場合の対症療法

Android NDKのデバッグは容易になった・・・はずなのに

Androidアプリは基本的にSDKを利用し、Java言語で記述します。ですが、Android NDKを利用することでC/C++言語でもアプリを記述できるのは周知のとおりです。

最初は「できるやつだけついてこい」的にほとんど整備されていなかったNDKの開発環境ですが、最近ではEclipseとの連携が可能になり、更にはコマンドラインベースだったデバッグEclipseを使ってGUI上でできるようになっています。

  1. Add Native Supportを設定する f:id:eaglesakura:20130317220540j:plain
  2. Debug As -> Native Application f:id:eaglesakura:20130317220640j:plain
  3. エディタ上でブレークポイントを設定 f:id:eaglesakura:20130317220728p:plain
  4. あとはステップ実行なり変数のウォッチなりが簡単にできる f:id:eaglesakura:20130317220755p:plain

そのおかげで、あんどろいどたん(Google Play)を始めとして最近の案件はAndroid NDKを多く利用していたわけですが、唐突に次のようなコンソールに出力されるようになり、デバッガが接続できなくなりました。

[2013-03-17 21:36:50 - アプリ名] Unknown Application ABI: 
[2013-03-17 21:36:50 - アプリ名] 
[2013-03-17 21:36:50 - アプリ名] Unable to detect application ABI's

対症療法

しばらくの間は「アルェ〜、ナンデナンデ!?」状態で仕方なくprintfデバッグをしてたわけですが、次の条件でデバッガが接続できることがわかりました。

無駄だったこと

  • 端末再起動
  • ndk-build -clean
  • キャッシュ的なファイルを全て削除
  • Eclipseを通常再起動
  • Eclipseの再インストール(再設定)
  • Eclipseの英語版を利用

効果的だったこと

  • eclipse -clean で起動する
    • ただしclean起動後も、通常起動したらまたデバッグできなくなる
    • つまりはデバッグしたくなる度にclean起動が必要

ですが、boost等の重いライブラリを利用していると、clean起動する度にインデクサーがガリガリと幾千のファイルをチェックしてしまうため、ストレスがマッハです。

デバッガが接続できるアプリ・できないアプリがあった

つい最近わかったことは、同一のEclipse環境・端末環境でもデバッグできるあぷり・できないアプリがあるということです。
チェックしてみると、比較的規模の大きな案件でビルドしたアプリは接続できず、小さいアプリは接続できるということでした。

原因

いろいろ調べた結果、(今のところ)理由は次の一点でした。

  • Android.mk/Application.mkで自分で作ったファイル(共通のmkファイル等)をincludeするとデバッガが接続できない
  • どちらか(もしくは両方)にincludeがあるとエラーが発生する
  • include先に書いてある内容をコピペして、includeしないようにすればおk
# ダメなApplication.mk

APP_MODULES := sample
include shared_application.mk

------
# shared_application.mkの中身

APP_STL:=gnustl_static
APP_ABI := armeabi-v7a
# 問題ないApplication.mk

APP_MODULES := sample
# コピペして持ってくれば大丈夫
APP_STL:=gnustl_static
APP_ABI := armeabi-v7a

反省

「本来includeは使わねーよwwww」とか、私が知らないだけでmakefileのルールに則ってないのかもしれませんが、共通部分をどっかにまとめとこう的なことはしばらく考えないほうがよさそうです。