読者です 読者をやめる 読者になる 読者になる

やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

Gradle+Androidプラグイン(0.7以降)でNDKプロジェクトをビルドする

Androidの新ビルドシステムであるGradle plugin for Androidでは、0.7からNDKのビルドがサポートされました。

が、いまだに(一年前の)0.4ベースのエントリが参照されていたり、ググると上位にいるようなので、現状をまとめなおします。

環境

  • Android SDK Build-tools r19.1
  • Gradle 1.12(1.10以上)
  • Gradle plugin for Android 0.11.0(Gradleによってインストール)

Gradleのインストール方法は、下記エントリを参照してください。

AndroidプラグインのNDKサポート

以前は、build.gradleにカスタムタスクを定義してndk-buildを実行していましたが、現在は以下のように書くことができます。

android {
    defaultConfig {
        ndk {
            moduleName "cppmodule"
            abiFilter "armeabi-v7a"
            stl "gnustl_static"
        }
    }
}

ビルドした共有ライブラリをapkに取り込むために記述していた下記タスクは削除してください。(pkgTask#jniDir()は削除されました)

- tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
-     pkgTask -> pkgTask.jniDir new File(projectDir, 'libs')
- }

ビルド対象のソースは、従来のjni/ディレクトリではなく、src/main/jni/に置きます。また、以下のファイルは自動生成されますので不要になります。

最後に、local.propertiesファイル(もしくは環境変数ANDROID_NDK_HOME)にAndroid NDKのパスを定義します。(パスは各自のインストールパスを指定してください)

ndk.dir=/Applications/android-ndk-r9d/

これで、これまで通り下記コマンドでビルドが実行されます。

$ gradle build

ndkのプロパティ

ndk{}内のプロパティには、Android.mkおよびApplication.mkに定義していた内容を設定することができます。

また例えばabiFilterなどは、defaultConfigでなくプロダクト・フレーバーごとに記述することもできます。新ビルドシステムのサンプルプロジェクトndkSanAngelsでは、プロダクト・フレーバーとしてx86, arm, mips, fatをそれぞれビルドしています。

ビルド済み共有ライブラリの利用

別途ビルドした共有ライブラリ(.soファイル)を利用する場合は、src/main/jniLibsにファイルを格納しておくことでビルド時にパッケージされます。

以上で、ほとんどのケースでbuild.gradleの記述だけでNDKプロジェクトのビルドが実現できるのではないでしょうか。

だが断る

現時点(Gradle plugin for Android 0.11.0)では残念ながら、標準サポートされた機能ではスタティックライブラリ(.aファイル)を含むプロジェクトはビルドすることができません。

スタティックライブラリを含むプロジェクトでは、0.4ベースのエントリに書いた設定をベースに以下を修正してください。

1.ビルドした共有ライブラリをapkに取り込むために記述していた下記タスクは削除してください。(pkgTask#jniDir()は削除されました)

- tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
-     pkgTask -> pkgTask.jniDir new File(projectDir, 'libs')
- }

2.ndk-buildで生成された.soファイルを、libs/からsrc/main/jniLibs/にコピーします。(シンボリックリンクを張るなどでも可)

task ndkCopy(type: Copy) {
    from 'libs'
    into 'src/main/jniLibs'
}
tasks.withType(Compile) {
    compileTask -> compileTask.dependsOn ndkBuild, ndkCopy
}

サンプルプロジェクト

https://github.com/nowsprinting/GradleAndroidNdkExample を更新してあります。