※NDKのドキュメントのCMakeのページだけなかなか日本語化されないので、個人的メモ代わりに日本語化してみました。
CMake
Android Studio 2.2以降では、NDKとCMakeを使ってC/C++コードをネイティブライブラリにコンパイルすることができます。Android StudioはIDEの統合されたビルドシステムであるGradleを使ってAPKの中にパッケージします。
Android StudioでCMakeを使うのが初めてなら、プロジェクトへのC/C++コードの追加を読んでプロジェクトにネイティブコードを追加する方法について学んでください。このページでは、CMakeビルドをカスタマイズするためのいくつかの追加の情報を提供します。
GradleでCMake変数を使う
ネイティブライブラリへのGradleのリンクをしたら、ネイティブライブラリのビルド方法を変更するNDK固有の変数を設定することができます。モジュールレベルのbuild.gradle
からCMakeに引数を渡すためには、次のようにします。:
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake build script.
externalNativeBuild {
cmake {
...
// 次のようにして変数を設定します:
// arguments "-D変数名=値".
arguments "-DANDROID_ARM_NEON=TRUE",
// 複数の変数を設定するなら、一緒に渡してください:
// arguments "-D変数名=値1 値2"
// 次の行は 'rtti' と 'exceptions' を 'ANDROID_CPP_FEATURES' に渡します。
"-DANDROID_CPP_FEATURES=rtti exceptions"
}
}
}
buildTypes {...}
// このブロックで Gradle を CMake ビルドスクリプトにリンクします。
externalNativeBuild {
cmake {...}
}
}
次のテーブルはNDKとCMakeで設定可能ないくつかの変数を説明します。
変数名 | 引数 | 説明 |
---|---|---|
ANDROID_TOOLCHAIN | * clang (デフォルト) * gcc (非推奨) |
CMakeが使用するコンパイラーツールチェインを指定します。 |
ANDROID_PLATFORM | プラットフォーム名と対応するAndroidシステムイメージの完全なリストは、Android NDK ネイティブ APIを見てください。 | ターゲットAndroidプラットフォーム名を指定します。例えば、android-18 はAndroid 4.3 (API level 18)を指定します。このフラグを直接変更する代わりに、 minSdkVersion プロパティをモジュールレベルのbuild.gradle ファイルのdefaultConfig もしくはproductFlavors ブロックに指定するべきです。これはライブラリが十分なバージョンのAndroidが動作している端末にインストールされているアプリだけで使われることを確実にします。CMakeツールチェインは次のロジックでABIの最適なプラットフォームバージョンを選択します:
|
ANDROID_STL | 完全なリストはヘルパーランタイムを見てください。デフォルトでは、gnustl_static を使います。 |
STLを指定します。 |
ANDROID_PIE |
|
position-independent executables (PIE)を使うかどうかを指定します。AndroidのダイナミックリンカーはAndroid4.1以上でPIEをサポートします。 |
ANDROID_CPP_FEATURES | デフォルトでは空ですが、次のようないくつかの引数を渡すことができます:
|
ネイティブライブラリをコンパイルする時に使う必要があるC++機能を指定します。例えばRTTI (RunTime Type Information) や C++ 例外等です。 |
ANDROID_ALLOW_UNDEFINED_SYMBOLS |
|
CMakeが未定義の参照に遭遇した時に未定義のシンボルエラーを投げるかどうかを指定します。この種類のエラーを無効にするためには、TRUE を指定してください。 |
ANDROID_ARM_MODE |
|
ARMターゲットバイナリをarm かthumb どちらのモードで生成するかを指定します。thumbモードでは、全ての命令は16ビット幅で、thumb/ディレクトリ以下のSTLライブラリとリンクされます。armを指定するとCMakeはライブラリのオブジェクトファイルを32ビットarmモードで生成します。 |
ANDROID_ARM_NEON |
|
NEONサポートを使ってネイティブライブラリをビルドするかどうかを指定します。 |
ANDROID_DISABLE_NO_EXECUTE |
|
NXビットを使うかどうかを指定します。この機能を無効にするには、TRUE を指定してください。 |
ANDROID_DISABLE_RELRO |
|
読み取り専用の再配置を有効にするかどうかを指定します。ANDROID_DISABLE_FORMAT_STRING_CHECKS |
CMakeビルドコマンドを理解する
CMakeのビルド問題をデバッグするとき、AndroidのためのクロスコンパイルをするときにAndroid Studioが使っているビルド引数を知ることが役に立ちます。
Android StudioはCMakeビルドを実行するのに使用したビルド引数をcmake_build_command.txt
ファイルに保存します。アプリがターゲットにするそれぞれのApplication Binary Interface (ABI)と、それぞれのビルドタイプ(release や debug)ごとに、Android Studioはcmake_build_command.txt
ファイルのコピーを生成します。Android Studioは次のディレクトリにファイルを生成します:
<project-root>/<module-root>/.externalNativeBuild/cmake/<build-type>/<ABI>/
Tip: Android Studioでは検索のキーボードショートカット(shift+shift)を使って cmake_build_command.txt と入力することで、これらのファイルを素早く表示することができます。
次のスニペットはarmeabi-v7aアーキテクチャをターゲットにhello-jniサンプルのデバッグ可能なリリースビルドのためのCMake引数を示します。
Executable : /usr/local/google/home/{$USER}/Android/Sdk/cmake/3.6.3155560/bin/cmake
arguments :
-H/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/src/main/cpp
-B/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/.externalNativeBuild/cmake/arm7Debug/armeabi-v7a
-GAndroid Gradle - Ninja
-DANDROID_ABI=armeabi-v7a
-DANDROID_NDK=/usr/local/google/home/{$USER}/Android/Sdk/ndk-bundle
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/build/intermediates/cmake/arm7/debug/obj/armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_MAKE_PROGRAM=/usr/local/google/home/{$USER}/Android/Sdk/cmake/3.6.3155560/bin/ninja
-DCMAKE_TOOLCHAIN_FILE=/usr/local/google/home/{$USER}/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DANDROID_NATIVE_API_LEVEL=23
-DANDROID_TOOLCHAIN=clang
jvmArgs :
ビルド引数
次のテーブルは主なAndroidのためのCMakeビルド引数を挙げています。これらのビルド引数は開発者が設定するものではありません。代わりにAndroid Plugin for Gradleは、プロジェクトのbuild.gradle設定に基づいてこれらの引数を設定します。
ビルド引数 | 説明 |
---|---|
-G <ビルドシステム> | CMakeが生成するビルドファイルの種類。 ネイティブコードを含むAndroid Studioプロジェクトでは、<ビルドシステム>はAndroid Gradle - Ninjaに設定されます。この設定はCMakeがninjaビルドシステムをC/C++ソースのコンパイルとリンクに使用することを示します。CMakeはコンパイラフラグやターゲット名等のGradleプラグインのためのメタデータを含む android_gradle_build.json ファイルも生成します。ninjaビルドシステムはAndroid Studioがサポートする唯一のジェネレーターです。 |
-DANDROID_ABI | ターゲットABI。 NDKは、ABI管理で説明されているように、一連のABIをサポートしています。このオプションはndk-buildツールが使用する APP_ABI 変数と似ています。デフォルトでは、GradleはネイティブライブラリをABIごとの個別の.soファイルにビルドして、それら全てをAPKにパッケージします。特定のABI設定のビルドのみを行いたい場合は、ABIの指定を見てください。 ターゲットABIが指定されていなければ、CMakeはデフォルトでarmeabi-v7aを使います。 有効なターゲット名は:
|
-DANDROID_NDK <パス> | NDKがインストールされているディレクトリへの絶対パス。 |
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY <パス> | CMakeがビルドしたライブラリを配置するディレクトリ。 |
-DCMAKE_BUILD_TYPE <種類> | ndk-buildツールのビルドタイプと似ています。有効な値はReleaseとDebugです。デバッグを簡単にするため、CMakeはリリース・デバッグバージョンをビルドの中で除去しませんが、GradleはAPKにパッケージする時にバイナリを除去します。 |
-DCMAKE_MAKE_PROGRAM <プログラム名> | ネイティブビルドシステムを起動するツール。Gradleプラグインはこの値をAndroid SDKにバンドルされたCMake ninjaジェネレーターに設定します。 |
-DCMAKE_TOOLCHAIN_FILE <パス> | CMakeがAndroidへのクロスコンパイルで使用するandroid.toolchain.cmake ファイルへのパス。通常、このファイルは$NDK/build/cmake/ディレクトリにあります。$NDKはNDKがインストールされているディレクトリです。詳細は、Cross Compiling for Androidを見てください。 |
-DANDROID_NATIVE_API_LEVEL <レベル> | CMakeがコンパイルするAndroid APIレベル。 |
-DANDROID_TOOLCHAIN <種類> | CMakeが使用するコンパイラツールチェイン。デフォルトはclang 。 |
(以下はあまり興味なさそうだったので省略しました)