Android NDKとNexus9を使って64bit ARMのバイナリを試してみた。
ちなみに去年(2014年)、iOSで64bit ARMのバイナリをコンパイルして動かすのを試している。
→ iOSのJailbreak環境で64bit ARM(AARCH64)のバイナリを試してみた
→ iOSのJailbreak環境で64bit ARM(AARCH64)のインラインアセンブラを試す
今回は、Android NDKで64bit ARMのバイナリをコンパイルするのを試してみる。
まず、Android NDKをインストールする。
Windows7(64bit版)のPCを使って、c:\android-ndk-r10dというフォルダーに入れた。
適当な作業フォルダー(例えば、c:\workなど)を作って、ソースコードを書く。
c:\workの下にjniというフォルダを作成し、そこにソースコードのファイルのhello.cを置く。
hello.c (c:\work\jni\hello.c) の内容は、以下の通り。
#include <stdio.h> int main(int argc, char **argv, char **evnp) { #ifdef __LP64__ printf("64bit\n"); #else printf("32bit\n"); #endif printf("Hello world.\n"); return 0; }
そして、Android.mkというビルド用の設定を記述したファイル作る。
Android.mk (c:\work\jni\Android.mk) の内容は、以下の通り。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello LOCAL_SRC_FILES := hello.c include $(BUILD_EXECUTABLE)
ビルド用のバッチファイルbuild.batというファイルも作成した。
build.bat (c:\work\build.bat) の内容は以下の通り。
rem =========== environment setting ========== set PATH=%PATH%;c:\android-ndk-r10d\ set ANDROID_NDK_ROOT=c:\android-ndk-r10d\ set NDK_PROJECT_PATH=. echo =========== 64bit build ============ call ndk-build -B V=1 APP_ABI=arm64-v8a pause
このバッチファイルを実行すると、ソースコードhello.cがビルドされて、64bitのバイナリがc:\work\libsフォルダー以下に生成される。
hello (c:\work\libs\arm64-v8a\hello) が、64ビットのバイナリのファイルだ。
このファイルをNexus9の実機に転送して実行してみた。
Nexus9はroot化したものを使った。
Nexus9の/sdcardフォルダーの直下にtmpというフォルダを作ってそこに一旦helloを転送する。
adb push hello /sdcard/tmp/hello
そして、Nexus9側で、
/dataフォルダー直下にtmpというフォルダを作って、そちらにコピーする。
(フォルダーのパーミッション設定が必要だったかも)
cp /sdcard/tmp/* /data/tmp
そして、実行するためにchmodコマンドで実行属性を付ける。
chmod 744 /data/tmp/hello
そして実行する。
64bit ARMのコードが実行されたのが確認できた。
次に64bit ARMのインラインアセンブラも試してみた。
同様の手順で、ソースコード(addvalue.c)は次のように書いた。
アセンブラで2つの数字を加算するというコードだ。
#include <stdio.h> long int addvalues(long int val1,long int val2) { long int result; __asm__ ( "ADD %[Rd],%[Rs1],%[Rs2]" : [Rd] "=r" (result) : [Rs1] "r" (val1), [Rs2] "r" (val2) ); return result; } int main(int argc, char **argv, char **envp) { long int val=addvalues(1234567890123456789L,1L); printf("addvalues = %ld\n",val); return 0; }
同様にビルドして実行すると、次のようになった。
1234567890123456789と1が加算された結果の1234567890123456790が表示された。
無事、64bitのARMのインラインアセンブラも使うことができた。
—
追記
ビルド時のndk_buildでAPP_ABI=arm64-v8aを指定せずにビルドさせると、32bitのARMのバイナリが生成されるはずである。
しかし、そうして生成した32bitのバイナリはNexus9で実行しようとするとエラーになってしまった。
error: only position independent executables (PIE) are supported.というエラーだ。
なぜ??
[続き]
—
さらに追記
インラインアセンブラでなく、直接アセンブラで書いてみた。