Android 5.0 Lollipopで32bit ARMバイナリが動かない。
昨日、NDKで64bit ARMのバイナリを作って動かしていて、比較で32bit ARMのバイナリをNexus9(Android 5.0)で動かそうとして気がついた。
error: only position independent executables (PIE) are supported.
というエラーが出るという症状だ。
調べてみると、StackOverflowというサイトに原因と対処法が載っていた。
→ Executable file cannot run on Android L
Android 5.0(Lollipop)からセキュリティ強化のため実行できるバイナリの形式が制限されているらしい。
PIEという形式でないと駄目だそうだ。
対処方法は、Android.mkファイルに以下のコンパイルオプション/リンカーオプションを追加すればいいらしい。
LOCAL_CFLAGS += -pie -fPIE LOCAL_LDFLAGS += -pie -fPIE
ということでこの2行を追加して昨日の手順を試してみた。
しかし、やはり同じエラーで動かなかった。なぜ!?
あと、64bit ARMバイナリは-pieとか指定しなくても特に何もせずに動いたのが不思議だ。
—
追記
解決した。
Android.mkファイルに上記の2行を追加した位置が悪かったのが原因だった。
Android.mkの
include $(BUILD_EXECUTABLE)
よりも前に追加したら、ちゃと-pieの指定がされてビルドできた。実機でも動作した。
makeツールのMakefileだと先頭から順に実行されたりしないので記述順序に無頓着だった。
Android.mkは先頭から順番に実行されるスクリプトみたいなものだとして扱わないと。
—
さらに追記
64bit ARMアセンブラでも、同様にしてリンカーオプションを追加することで無事に実行できた。