Androidアプリでネイティブライブラリを利用するため NDK を設定する
ちょっとやりたいことがあるので、Android NDK 環境を準備しようと思う。
Android NDK とは、Andoroid アプリケーションにネイティブコードを利用して作成されたコンポーネントを埋め込むことを可能にするツールセット。Android アプリケーションはDalvikか総マシーンで実行される。NDKは C や C++ などのネイティブコードを使った一部を実装することを可能にする。
いつものように、Android Hacks ―プロが教えるテクニック & ツール を見ながら、ちょちょいのちょいと。。。
は行かなかったので、はまった点などの手順をメモしておく。
1.Cygwinのインストール
Windows 環境でNDKを利用するには、Cygwin が必要。
http://cygwin.com/install.html
上記サイトから、Setup.exe をダウンロードしてきて、ウィザードに従いインストールする途中で、以下の様なインストールパッケージを選択する画面になるので、カテゴリーから、Devel を選択して展開し、
- gcc
- make
をインストールする
辞書順にずーっとみていくと、gcc が存在するので、Skip というアイコンをクリックすると、インストール対象となる。
同様に、make もインストールする。
2.Android NDK のインストール
以下から、Wubdiws版をダウンロードして解凍。
http://developer.android.com/sdk/ndk/index.html
置き場所は、どこでも良いようだが、Android Hacks ―プロが教えるテクニック & ツール にならい、C:\cygwin\home\{ユーザー名}\android-ndk-r7 に配置する
3.サンプルの実行
http://developer.android.com/sdk/ndk/overview.html#samples
解凍、配置したNDKフォルダ直下の、samples フォルダの下に、いくつかのサンプルがあるが、それぞれ、Androidアプリケーションの構造を持っている。
- jni ディレクトリ : Android.mk ファイルとネイティブコードのソースコードを含んでいる
- tests ディレクトリ : ユニットテストコードを含んでいる
3.1 プロジェクトの作成
一番初歩的そうな、helo-jni を選ぶ。
- Eclipse を立ち上げて(もちろんAndroid環境構築済み)、新規 Android プロジェクトから、Create project from existing source にチェックをONにする。
- Location に、上記 samples/helo-jni の位置を指定。
3.2 ビルドファイルの作成
対象のディレクトリまでいって、
android update project -p . –s
コマンドを実行
自分の環境だと、以下。
C:\>cd C:\cygwin\home\piroto\android-ndk-r7\samples\hello-jni C:\cygwin\home\piroto\android-ndk-r7\samples\hello-jni>android update project -p . -s Updated local.properties Added file C:\cygwin\home\piroto\android-ndk-r7\samples\hello-jni\build.xml Added file C:\cygwin\home\piroto\android-ndk-r7\samples\hello-jni\proguard.cfg Error: The project either has no target set or the target is invalid. Please provide a --target to the 'android.bat update' command.
Error??? 一つ目のはまりポイント。
確かに build.xml は生成されるのだが、Ant のデフォルトターゲット が存在していない?
ここは、生成された build.xml の
<project name="HelloJni" default="help">
これを
<project name="HelloJni">
こう修正(default="help"を削除)。
3.3 環境変数の設定
.bash_profile を編集する。cygwin でエディタをインストールしてなければ、C:\cygwin\home\[ユーザー名]\.bash_profile に以下の2行を追記。
$ vim ~/.bash_profile export NDK_ROOT=/cygdrive/c/cygwin/home/piroto/android-ndk-r7 PATH=$PATH:$NDK_ROOT
で、はまりポイント2
最初、何も考えずに、NDK_HOME とかしていたが、NDK_ROOT 環境変数が設定されていないと、
以下の様に、awk が見つからないというエラーになる。また、ディレクトリ末尾の / も不要。
$ cd /cygdrive/c/cygwin/home/piroto/android-ndk-r7/samples/hello-jni piroto@eisai /cygdrive/c/cygwin/home/piroto/android-ndk-r7/samples/hello-jni $ ndk-build C:\cygwin\home\piroto\android-ndk-r7\prebuilt\windows\bin\awk.exe: can't open file /cygdrive/c/cygwi n/home/piroto/android-ndk-r7/build/awk/check-awk.awk source line number 1 source file /cygdrive/c/cygwin/home/piroto/android-ndk-r7/build/awk/check-awk. awk context is >>> <<< Android NDK: Host 'awk' tool is outdated. Please define HOST_AWK to point to Gawk or Nawk ! /cygdrive/c/cygwin/home/piroto/android-ndk-r7/build/core/init.mk:258: *** Android NDK: Aborting. . Stop.
3.4 AWK を差し替える
ここまでで、ndk-build を行うも、check-awk.awk でエラーが発生しているようだ。はまりポイント3。
$ pwd /cygdrive/c/cygwin/home/piroto/android-ndk-r7/build/awk piroto@eisai /cygdrive/c/cygwin/home/piroto/android-ndk-r7/build/awk $ awk check-awk.awk awk: cmd. line:1: check-awk.awk awk: cmd. line:1: ^ syntax error
先人の知恵を参考にすると、どうも、AndroidNDKに含まれている awk では問題あり?とりあえず、AndroidNDKに含まれている awk を _awk にリネームし、/usr/bin/gawk のシンボリックリンクとして awk を作成。
piroto@eisai /cygdrive/c/cygwin/home/piroto/android-ndk-r7/prebuilt/windows/bin $ mv awk.exe _awk.exe piroto@eisai /cygdrive/c/cygwin/home/piroto/android-ndk-r7/prebuilt/windows/bin $ ln -s /usr/bin/gawk ./awk.exe
check-awk.awk をみると、
# This script is used to check that a given awk executable # implements the match() and substr() functions appropriately. # # These were introduced in nawk/gawk, but the original awk # does not have them.
nawk/gawk で導入された、match(),substr() が実装されているかチェックしているっぽい。
オリジナルの awk には含まれてませんよと。
なんじゃそりゃ。
3.5 ようやくビルド
気を取り直して、ndk-build を cygwin から実行。
piroto@eisai /cygdrive/c/cygwin/home/piroto/android-ndk-r7/samples/hello-jni $ ndk-build Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver Gdbsetup : libs/armeabi/gdb.setup Compile thumb : hello-jni <= hello-jni.c SharedLibrary : libhello-jni.so Install : libhello-jni.so => libs/armeabi/libhello-jni.so
成功した!
3.6 エミュレータで実行
おー Hello なんちゃらと表示されました。成功でしょう。
ふぅ。