Android Studio で NaviteActivity のプロジェクトを作成するメモ (CMake使用)
お仕事で、久しぶりにAndroidのプログラムを作成することになりました。以前は、ADT+NDK (Android.mk) で作成していたのですが、最近では開発環境も一新されているようなので、この機に、Android Stuido + CMake の環境に移行することにしました。
以前の記事のとおり、CMakeについて軽く調べたので、そちらを利用してAndroid版のプログラムもビルドできるようにしようという目論見です。また、できるだけJavaのプログラムを書かなくても良いように、今回はNativeAvtivityも使ってみようと思います。
この記事執筆時点の環境のバージョンは、以下のとおりです。
- Android Studio 2.3.3
プロジェクトの作成
この記事では、CMakeLists.txt等も外部のものを利用するような場合について書いていきます。まずは、空のプロジェクトを作成します。メニューの[File] – [New Project]を選択します。ダイアログが表示されたら、以下のような設定を行います。
- (New Project)「Include C++ Support」にはチェックしない
- (Add an Activity to Mobile) 「Add No Activity」を選択
「Include C++ Support」にチェックを入れると、自動的にCMakeLists.txt等ができてしまいます。
外部のCMakeLists.txtを読み込む
IDE横のProjectペインから、以下のような手順で設定します。
- [Project] ペインを開いて、上のプルダウンメニューから[Android] ビューを開きます。
- モジュールのルートを右クリックし、[Link C++ Project with Gradle]を選択します。
- 表示されるダイアログから、対象のCMakeLists.txtファイルを選択します。
以上の設定を行うと、モジュールのbuild.gradleに以下のような設定が追加されます。
1 2 3 4 5 6 7 8 9 10 |
android { // ... externalNativeBuild { cmake { path '../../../Documents/NATest/CMakeLists.txt' // CMakeLists.txtへの相対パス } } } |
Gradleに設定を追加
build.gradleに、ビルド用の設定を追加することも可能です。対象のConfig(defaultConfig)内にexternalNativeBuildのブロックを作り、そこに書き込んでいきます。先のブロックとは違うので注意して下さい。Android用にビルドするにあたり、筆者は以下のように設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
android { // ... defaultConfig { // ... externalNativeBuild { cmake { cppFlags "-std=c++11 -frtti -fexceptions" // C++11 例外 動的キャスト等 arguments "-DANDROID_ARM_NEON=TRUE"// NEONを有効 } } } |
build.gradleを編集したら、必ず画面右上の「Sync Now」をクリックし、同期して下さい。
何も設定しないと、対応するすべてのアーキテクチャのコンパイルを実行するため、ビルドに結構時間がかかります。そのため、筆者は、上記の設定に加えて、以下のように、ndkというブロックを作り、対象のアーキテクチャを限定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
android { // ... defaultConfig { // ... externalNativeBuild { // ... } ndk{ abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a' } } |
デフォルトのアクティビティの設定
NativeActivityを使う設定をします。AndroidManifest.xml内の<application>タグ内に以下の設定を行います。
1 2 3 4 5 6 7 8 9 10 11 |
<activity android:name="android.app.NativeActivity" android:label="@string/app_name"> <meta-data android:name="android.app.lib_name" android:value="????" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> |
android:value=”????”の????には、ネイティブコンパイルする.soファイルから、拡張子と先頭の”lib”を除いた名前を指定します。(後述する、CMakeLists.txtで指定するライブラリ名そのままでOKです)
CMakeLists.txt 設定時の注意
Android Studioを使ってビルドする場合にも、CMakeLists.txtは、ほとんど通常通りに書けば問題ないようです。ただし、以下の設定は必須です。
- バージョンの指定 : 先頭に「cmake_minimum_required(VERSION 3.4.1)」を記述
- 共有ライブラリ生成の設定 : 「add_library( [ライブラリ名] SHARED [ソースファイルのリスト] )」を記述
※ 1ファイル内にadd_libraryを複数書いたところ、なんだかうまく行きませんでした…
android_native_app_glue を使う
NativeActivitiyを使う際には、多くの場合、「android_native_app_glue」を使うと思います。その場合、以下のような設定をCMakeLists.txtに追加します。下の例は、test.cppというファイルを、native-libという共有ファイルにコンパイルするための設定です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
cmake_minimum_required(VERSION 3.4.1) # glue のインクルードパスを追加 include_directories(${ANDROID_NDK}/sources/android/native_app_glue) # android_native_app_glue.c もコンパイル対象にする # 長いので変数に入れておく set(NA_src ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) add_library( native-lib SHARED test.cpp ${NA_src} # android_native_app_glue.c も加える ) #android や log ようのライブラリも追加しておく target_link_libraries( native-lib android log) |
要するに、「android_native_app_glue.c」も一緒にコンパイルしてしまう設定です。
そのほか、メモ
- CMakeLists.txt内では、「ANDROID=TRUE」と定義される。( if(ANDROID) で判定可能 )