LoginSignup
20
16

More than 5 years have passed since last update.

CMake

Posted at

※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の最適なプラットフォームバージョンを選択します:
  1. もしminSdkVersionと同じABIバージョンがあれば、それを使います。
  2. そうでなければ、minSdkVersionより小さいプラットフォームバージョンがある場合、その中で最も高いプラットフォームバージョンを使います。これはプラットフォームバージョンが無いということはその前のバージョンからネイティブプラットフォームAPIに何の変更もないということなので、合理的な選択です。
  3. そうでなければ、minSdkVersionより大きな、次に利用可能なバージョンを使います。
ANDROID_STL 完全なリストはヘルパーランタイムを見てください。デフォルトでは、gnustl_staticを使います。 STLを指定します。
ANDROID_PIE
  • ON (ANDROID_PLATFORM = android-16以上の場合のデフォルト)
  • OFF (ANDROID_PLATFORM = android-15以下の場合のデフォルト)
position-independent executables (PIE)を使うかどうかを指定します。AndroidのダイナミックリンカーはAndroid4.1以上でPIEをサポートします。
ANDROID_CPP_FEATURES デフォルトでは空ですが、次のようないくつかの引数を渡すことができます:
  • rtti (RTTIを使うかどうか)
  • exceptions (C++例外を使うかどうか)
ネイティブライブラリをコンパイルする時に使う必要があるC++機能を指定します。例えばRTTI (RunTime Type Information) や C++ 例外等です。
ANDROID_ALLOW_UNDEFINED_SYMBOLS
  • TRUE
  • FALSE (デフォルト)
CMakeが未定義の参照に遭遇した時に未定義のシンボルエラーを投げるかどうかを指定します。この種類のエラーを無効にするためには、TRUEを指定してください。
ANDROID_ARM_MODE
  • arm
  • thumb (デフォルト)
ARMターゲットバイナリをarmthumbどちらのモードで生成するかを指定します。thumbモードでは、全ての命令は16ビット幅で、thumb/ディレクトリ以下のSTLライブラリとリンクされます。armを指定するとCMakeはライブラリのオブジェクトファイルを32ビットarmモードで生成します。
ANDROID_ARM_NEON
  • TRUE
  • FALSE (デフォルト)
NEONサポートを使ってネイティブライブラリをビルドするかどうかを指定します。
ANDROID_DISABLE_NO_EXECUTE
  • TRUE
  • FALSE (デフォルト)
NXビットを使うかどうかを指定します。この機能を無効にするには、TRUEを指定してください。
ANDROID_DISABLE_RELRO
  • TRUE
  • FALSE (デフォルト)
読み取り専用の再配置を有効にするかどうかを指定します。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を使います。

有効なターゲット名は:
  • armeabi: ARMv5TE based CPU with software floating point operations.
  • armeabi-v7a: ARMv7 based devices with hardware FPU instructions (VFPv3_D16).
  • armeabi-v7a with NEON: Same as armeabi-v7a, but enables NEON floating point instructions. This is equivalent to setting -DANDROID_ABI=armeabi-v7a and -DANDROID_ARM_NEON=ON.
  • arm64-v8a: ARMv8 AArch64 instruction set.
  • mips: MIPS32 instruction set (r1).
  • mips64 - MIPS64 instruction set (r6).
  • x86: IA-32 instruction set.
  • x86_64 - Instruction set for the x86-64 architecture.
-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

(以下はあまり興味なさそうだったので省略しました)

20
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
16