Android NDK

http://developer.android.com/sdk/ndk/index.html
http://developer.android.com/sdk/ndk/overview.html

ndk-build

NDK r4から提供されたビルド用のシェルスクリプト。
GNU Make 3.81以上が必要になる。

Android NDK r4以前ではNDK /apps/<name>/ にプロジェクトを置いて

cd $NDK
make APP=<name>

とかだったが、NDK r5からは

cd $PROJECT
$NDK/ndk-build

で動かせる。

コマンド 内容
ndk-build リビルド
ndk-build clean 生成したファイルの削除
ndk-build NDK_DEBUG=1 デバッグ可能なバイナリの生成
ndk-build NDK_DEBUG=0 デバッグビルドを無効=リリースビルド
ndk-build V=1 ビルドを実行し、ビルドコマンドを表示する
ndk-build -B 強制的にリビルドする
ndk-build -B V=1 強制的にリビルドして、ビルドコマンドを表示する
ndk-build NDK_LOG=1 NDKのログを表示する(NDK自身のデバッグで使う)
ndk-build NDK_APPLICATION_MK= Application.mkを指定してのビルド(NDK_APP_APPLICATION_MKはドキュメントの間違い)
ndk-build -C プロジェクトのパスを指定してビルド、プロジェクトディレクトリにcdしなくてもビルドできる

variables/macro

/ndk/docs/ANDROID-MK.htmlをまとめただけ

includeで使えるvariables

ようはmkファイルのパスが格納されている変数。なのでinclude $(CLEAR_VARS)のように使える。変数の説明というより変数が指すmkファイルの説明。

変数 内容
CLEAR_VARS LOCAL_XXX変数を消す
BUILD_SHARED_LIBRARY LOCAL_MODULE,LOCAL_SRC_FILESをもとにshard libraryをビルドする、lib$(LOCAL_MODULE).soができる
BUILD_STATIC_LIBRARY static libraryをビルドする、shard libraryからはLOCAL_STATIC_LIBRARIES,LOCAL_STATIC_WHOLE_LIBRARIESに指定してリンクする、lib$(LOCAL_MODULE).aができる
PREBUILT_SHARED_LIBRARY 配布用、ビルド高速化などで使うために事前にビルドされたshard libraryを取り込む、prebuiltするときにLOCAL_SRC_FILESにはとりこむバイナリファイルを指定する(アーキテクチャに合わせて適切なバイナリモジュールを選ぶ必要がある、TARGET_ARCH_ABIを使ってパスを指定するのが良い)。他のモジュールからはLOCAL_SHARED_LIBRARYで読み込める。ヘッダを公開するときはLOCAL_EXPORT_C_INCLUDES を使う。
PREBUILT_STATIC_LIBRARY PREBUILT_SHARED_LIBRARYのstatic library版
TARGET_ARCH ターゲットのCPUアーキテクチャ名
TARGET_PLATFORM ターゲットのアンドロイドプラットフォーム(≒version)
TARGET_ARCH_ABI ターゲットのCPU+ABI
TARGET_ABI $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)

マクロ

マクロ 内容
my-dir 最後にincludeしたmakefileが含まれるディレクトリを返す。他のmkファイルをincludeしてしまうと値が変わるのでcurrentのmakefileのディレクトリは他のファイルをincludeする前に取得する必要がある
all-subdir-makefiles 再帰的にサブディレクトリのAndriod.mkを検索し、リストとして返す。Include $(call all-subdir-makefiles)などで使う。
this-makefile 現在のmakefileのパスを返す
parent-makefile includeされている親のmakefileのパスを返す
grand-parent-makefile 親の親のmakefileのパスを返す
import-module プロジェクトツリーの外にあるndkモジュールをインポートする、NDK_MODULE_PATH//Andriod.mkが参照されるのでソースプロジェクトをLOCAL_STATIC_LIBRARIES += などを使ってリンクすることが可能

モジュール用(Android.mk)

変数 内容
LOCAL_PATH 現在のファイルがあるパス、$(CLEAR_VARS)ではクリアされない
LOCAL_MODULE モジュールの名前、prefixのlibは自動的につく
LOCAL_MODULE_FILENAME 出力する際にファイル名を明示的に指定する場合に使う
LOCAL_SRC_FILES ソースファイルのリスト、LOCAL_PATHからの相対パスで、/でパスを切ること\はつかうべからず
LOCAL_CPP_EXTENSION cppファイルの拡張子を指定する、デフォルトは”.cpp”
LOCAL_C_INCLUDES includeパスをリスト、NDKルートディレクトリからの相対パスになるため、場合によっては$(LOCAL_PATH)/../fooなどで絶対パスを指定する必要もある
LOCAL_CFLAGS 追加するC/C++のコンパイルフラグ、ただしoptimization/debugging構成レベルの設定はApplication.mkに任せるべき
LOCAL_CXXFLAGS 追加するLOCAL_CPPFLAGSのエイリアス
LOCAL_CPPFLAGS C++のコンパイルフラグ
LOCAL_STATIC_LIBRARIES リンクするstatic libraryのリスト
LOCAL_SHARED_LIBRARIES 実行時に依存するモジュールのリスト
LOCAL_WHOLE_STATIC_LIBRARIES リンカの–while-archiveオプション
LOCAL_LDLIBS 追加するリンカフラグ
LOCAL_ALLOW_UNDEFINED_SYMBOLS ‘true’を指定するとundefined symbolエラーを許可するようになる
LOCAL_ARM_MODE デフォルトは’thumb’で16bit幅の命令コード、’arm’を指定すると32bit
LOCAL_ARM_NEON ‘true’を指定するとARM Advanced SIMDを使える
LOCAL_DISABLE_NO_EXECUTE ‘true’を指定するとAndroid NDK r4で追加されたNX bitセキュリティ機能を無効にする
LOCAL_EXPORT_CFLAGS static/shared libraryが参照先モジュールへ追加するC/C++コンパイラフラグ
LOCAL_EXPORT_CPPFLAGS LOCAL_EXPORT_CFLAGSのLOCAL_CPPFLAGS版
LOCAL_EXPORT_C_INCLUDES LOCAL_EXPORT_CFLAGSのLOCAL_C_INCLUDES版
LOCAL_EXPORT_LDLIBS LOCAL_EXPORT_CFLAGSのLOCAL_LDLIBS版
LOCAL_FILTER_ASM アセンブリファイルをフィルタするシェルコマンド

Application.mk

アプリケーション用の設定、通常このファイルがなくてもデフォルトの設定で動く。
アプリケーションが必要とするnative module(static/shared libraries)についての設定を書くのが目的。

設定 内容
APP_PROJECT_PATH アプリケーションプロジェクトのルートパス、絶対パスで記述
APP_MODULES NDKが自動的に参照モジュールをリストするので不要。Android.mkがLOCAL_MODULEで参照するモジュールをモジュール名をリストする
APP_OPTIM release/debugを設定する。デフォルトはrelease
APP_CFLAGS 各モジュールに対するC/C++コンパイラフラグ(android-ndk-1.5_r1ではCのみ)、パスを指定する場合はNDKルートディレクトリの相対パスになるので注意
APP_CXXFLAGS APP_CPPFLAGSのエイリアス
APP_CPPFLAGS APP_CFLAGSのC++版。C++ファイルのみに適応するコンパイルフラグ(android-ndk-1.5_r1ではCにも適応される)
APP_BUILD_SCRIPT ビルドスクリプトの名前。デフォルトはAndroid.mk
APP_ABI Application Binary Interface。デフォルトはarmeabi
APP_STL C++のランタイムライブラリを指定、デフォルトはsystem, stlport_staticかstlport_sharedでSTLが使えるようになる、複数のshard libraryからSTLを使うならstlport_sharedを使うのが良いだろう、逆にひとつならstaticでlinkさせた方がサイズが小さくなる