Android Studioも1.3になって暫く立ちますがやっぱりNDKのビルドには色々問題が有ります。
ということでやっぱりApplicationb.mk/Android.mkを使ってndk-buildでビルドしたいです。本音はEclipseの時のようにデバッグできるのが一番ですけど。
Android Studio 1.3になっても前の記事のままでも動きますが、ちょっとだけ違う方法も書いてみま〜す。大して変わらないけど。
前回の記事ではndk-buildでネイティブライブラリをビルドした後gradle様にjarに組み込んでもらっていましたが今回は自前でjarに押し込みます。何のメリットが有るかって?ん〜ん多分無いキッパリ せいぜいgradle様の闇…ブラックボックスの中身が少し見えた気分になれるだけかなぁ(笑)
local.propertiesについては前回と同じでこげなことを書いておきます。
1 2 |
sdk.dir=/Users/saki/android-sdks ndk.dir=/Users/saki/android-ndks |
実際のパスは各自の環境に合わせて設定くだされ。
おまじないの2つ目も大体同じです。
1 |
jni.srcDirs = [] |
をbuild.gradleにポイっと書いておきます。ちょっと違うのは
1 |
jniLibs.srcDir 'src/main/libs' |
の部分が無いってことでgradle様が自分でネイティブライブラリを取り込まないようにします。まぁあってもエラーにはならないので良きにはからいたもうれ。
おまじないの3つ目も大体同じ…結局前と一緒やんとか言わないでぇ〜
1 2 3 |
tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn ndkLibsToJar } |
Javaのソースコードのコンパイルの際についでにndkLibsToJarというタスクも実行してもらいます。前回の時はここで直接ndkBuildタスクを呼んでいましたが今回は少し違います。前回の記事ではjarの生成はgradle様におまかせでしたが今回は自分でjarにするのでもう1つTaskを追加しています。
でもってその感じのjar生成はと言うとこんな感じ。Jarを作るついでにndkBuildタスクも呼び出すことにして…えぃっ^^
1 2 3 4 5 6 7 8 9 |
task ndkLibsToJar(type: Zip, dependsOn: 'ndkBuild', description: 'Create a JAR of the native libs') { destinationDir new File(buildDir, 'libs') baseName 'ndk-libs' extension 'jar' from(new File(buildDir, 'libs')) { include '**/*.so' } into 'lib/' } |
にゃぁ〜後はndkBuildタスクを定義してあげれば桶\(^o^)/
1 2 3 4 5 6 7 8 9 10 11 |
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') { println('executing ndkBuild') def ndkBuildingDir = project.plugins.findPlugin('com.android.library').sdkHandler.getNdkFolder().absolutePath def ndkBuildPath = ndkBuildingDir if (Os.isFamily(Os.FAMILY_WINDOWS)) { ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd' } else { ndkBuildPath = ndkBuildingDir + '/ndk-build' } commandLine ndkBuildPath, '-j4', '-C', file('src/main').absolutePath } |
ちなみに、Android.mkやApplication.mkの場所を指定してビルドしたい場合にはコマンドラインに
1 2 3 |
'NDK_PROJECT_PATH=build', 'APP_BUILD_SCRIPT=src/main/jni/Android.mk', 'NDK_APPLICATION_MK=src/main/jni/Application.mk', |
を含めます。こんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') { println('executing ndkBuild') def ndkBuildingDir = project.plugins.findPlugin('com.android.library').sdkHandler.getNdkFolder().absolutePath def ndkBuildPath = ndkBuildingDir if (Os.isFamily(Os.FAMILY_WINDOWS)) { ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd' } else { ndkBuildPath = ndkBuildingDir + '/ndk-build' } commandLine ndkBuildPath, '-j4', 'NDK_PROJECT_PATH=build', 'APP_BUILD_SCRIPT=src/main/jni/Android.mk', 'NDK_APPLICATION_MK=src/main/jni/Application.mk', } |
その代わり指定した場所にAndroid.mkやApplication.mkがなければビルドがコケます。あまり使うことはないかな?
あっそうそうbuild.gradleの先頭で次のimportをしといてね。
1 |
import org.apache.tools.ant.taskdefs.condition.Os |
最後に全部載っけてみよう〜(^o^)/前回は全文は載せてなかったからね。ネイティブライブラリを含むライブラリモジュールをビルドする時のbuild.gradleになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
apply plugin: 'com.android.library' import org.apache.tools.ant.taskdefs.condition.Os android { compileSdkVersion 23 buildToolsVersion "23.0.0" defaultConfig { minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main { jniLibs.srcDir 'src/main/libs' // gradleでnative libをJARに含める場合 jni.srcDirs = [] // Gradleが自動でndk-buildを呼び出すのを防ぐためにjniのソースディレクトリを空に設定する } } } dependencies { compile fileTree(dir: new File(buildDir, 'libs'), include: '*.jar') } tasks.withType(JavaCompile) { // compileTask -> compileTask.dependsOn ndkBuild // gradle様にお願いする時。jniLibs.srcDirの記述も必要 compileTask -> compileTask.dependsOn ndkLibsToJar // 自前でネイティブライブラリをJARに組み込む時 } // Javaのコンパイル時にネイティブライブラリを同時にビルドしてJARに含めるタスク task ndkLibsToJar(type: Zip, dependsOn: 'ndkBuild', description: 'Create a JAR of the native libs') { destinationDir new File(buildDir, 'libs') baseName 'ndk-libs' extension 'jar' from(new File(buildDir, 'libs')) { include '**/*.so' } into 'lib/' } // ndk-buildを使ってネイティブライブラリをビルドするタスク task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') { println('executing ndkBuild') def ndkBuildingDir = project.plugins.findPlugin('com.android.library').sdkHandler.getNdkFolder().absolutePath def ndkBuildPath = ndkBuildingDir if (Os.isFamily(Os.FAMILY_WINDOWS)) { ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd' } else { ndkBuildPath = ndkBuildingDir + '/ndk-build' } commandLine ndkBuildPath, '-j4', '-C', file('src/main').absolutePath } |
でもビルドは出来てもデバッグがまだまだへっぽこな気がするんだなぁ(´・ω・`)
お疲れ様〜(^_^)/~