2016-09-21 8 views
3

AndroidビルドをAntからGradleに移動し始めてから、私のC++コードにcmakeを使用したいと思います。ビルドは現在正常に実行されていますが、aarファイルを作成する前にjniLibsフォルダにコピーされた共有オブジェクトはありません(これは現在Windows 10上に構築されているライブラリプロジェクトです)。Android用cmakeを使用しているときに共有オブジェクトをjniLibsにコピー

私は./gradlew assembleDebugでビルドするときに実行されているタスクを見てきました。彼らは以下のとおりです。

:app:preBuild UP-TO-DATE 
:app:preDebugBuild UP-TO-DATE 
:app:checkDebugManifest 
:app:preDebugAndroidTestBuild UP-TO-DATE 
:app:preDebugUnitTestBuild UP-TO-DATE 
:app:preReleaseBuild UP-TO-DATE 
:app:preReleaseUnitTestBuild UP-TO-DATE 
:app:prepareComAndroidSupportAppcompatV72221Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportV42221Library UP-TO-DATE 
:app:prepareDebugDependencies 
:app:compileDebugAidl UP-TO-DATE 
:app:compileLint UP-TO-DATE 
:app:copyDebugLint UP-TO-DATE 
:app:copyLibs 
:app:compileDebugRenderscript UP-TO-DATE 
:app:generateDebugBuildConfig UP-TO-DATE 
:app:generateDebugResValues UP-TO-DATE 
:app:generateDebugResources UP-TO-DATE 
:app:mergeDebugResources UP-TO-DATE 
:app:processDebugManifest UP-TO-DATE 
:app:processDebugResources UP-TO-DATE 
:app:generateDebugSources UP-TO-DATE 
:app:incrementalDebugJavaCompilationSafeguard UP-TO-DATE 
:app:compileDebugJavaWithJavac UP-TO-DATE 
:app:extractDebugAnnotations UP-TO-DATE 
:app:mergeDebugShaders UP-TO-DATE 
:app:compileDebugShaders UP-TO-DATE 
:app:generateDebugAssets UP-TO-DATE 
:app:mergeDebugAssets UP-TO-DATE 
:app:mergeDebugProguardFiles UP-TO-DATE 
:app:packageDebugRenderscript UP-TO-DATE 
:app:packageDebugResources UP-TO-DATE 
:app:processDebugJavaRes UP-TO-DATE 
:app:transformResourcesWithMergeJavaResForDebug UP-TO-DATE 
:app:transformClassesAndResourcesWithSyncLibJarsForDebug UP-TO-DATE 
:app:generateJsonModelDebug UP-TO-DATE 
:app:externalNativeBuildDebug 
    building E:\path\to\app\Android\app\.externalNativeBuild\cmake\debug\libs\x86\libApp.so 
    building 
:app:mergeDebugJniLibFolders 
:app:transformNative_libsWithMergeJniLibsForDebug 
:app:transformNative_libsWithSyncJniLibsForDebug 
:app:bundleDebug 
:app:compileDebugSources 
:app:assembleDebug 

これはすべてが順調と良いですが、フォルダapp/src/main/jniLibsは空で、これ何の共有オブジェクトは、AARファイルにコピーされません。したがって、これらのファイルを実際にコピーするためのグラデルビルドステップを追加する方法の問題があります。これは非常に困難であることが分かっています。

アプローチ1:

:app:bundleDebugタスクの前に実行するコピータスクを作成してください。

第一の可能性:

task copyLibs(type: Copy, dependsOn: 'bundleDebug') { 
    from ('.externalNativeBuild/cmake/debug/libs') { 
     include '**/libApp.so' 
    } 
    into 'src/main/jniLibs' 
} 

第二の可能性:私は行う必要がコピーを強制することができますので、パスが、正しいことを

task copyLibs(type: Copy) { 
    from ('.externalNativeBuild/cmake/debug/libs') { 
     include '**/libApp.so' 
    } 
    into 'src/main/jniLibs' 
} 

tasks.whenTaskAdded { task -> 
    if (task.name == 'bundleDebug') { 
     task.dependsOn copyLibs 
    } 
} 

は注意私はこれを行うには、いくつかの試みがなされてきました代わりにコピーステップを内部に持つtask copyLibs <<を使用してください。共有オブジェクトが最初に存在しないため、これはの2番目のビルドでコピーされます。 (タスクので、最初に実行されます。)

アプローチ2:

はcmakeの中にコピーを行います。これは実現可能ですが、望ましくありません。それゆえ、私はこの道を歩いていない。

コメントと詳細情報は以下のコメントのとおりです。

は、ここに私のbuild.gradleです。

apply plugin: 'com.android.library' 

// This task is run before everything else, so it does the copy on the *second* build, 
// thereby copying the shared objects from the *previous* build. 
//task copyLibs << { 
// copy { 
//  from ('.externalNativeBuild/cmake/debug/libs') { 
//   include '**/libApp.so' 
//  } 
//  from ('.externalNativeBuild/cmake/release/libs') { 
//   include '**/libApp.so' 
//  } 
//  into 'src/main/jniLibs' 
//  includeEmptyDirs = false 
// } 
//} 

// This is the task signature if tasks.whenTaskAdded below is *not* used. If both are 
// used we get a circular dependency. 
//task copyLibs(type: Copy, dependsOn: 'bundleDebug') { 

task copyLibs(type: Copy) { 
    from ('.externalNativeBuild/cmake/debug/libs') { 
     include '**/libApp.so' 
    } 
    into 'src/main/jniLibs' 
} 

tasks.whenTaskAdded { task -> 
    if (task.name == 'bundleDebug') {} 
     // This dependecy *is* set. This can be seen by using task copyLibs(type: Copy, dependsOn: 'bundleDebug') 
     // together with this and get a circular dependency. 
     task.dependsOn copyLibs 
    } 
} 

// Prints: 
// [task ':app:assemble', task ':app:assembleAndroidTest', task ':app:assembleDefault', task ':app:buildDependents', 
// task ':app:buildNeeded', task ':app:check', task ':app:compileLint', task ':app:connectedCheck', task ':app:copyLibs', 
// task ':app:deviceCheck', task ':app:extractProguardFiles', task ':app:lint', task ':app:preBuild', task ':app:sourceSets', 
// task ':app:uninstallAll'] 
println(tasks) 

android { 
    compileSdkVersion 22 
// buildToolsVersion "22.0.1" 
    buildToolsVersion "24.0.2" // Tried using latest for good measures 

    defaultConfig { 
     minSdkVersion 12 
     targetSdkVersion 22 
     versionCode 1 
     versionName "1.0" 

     // Some defines to build certain architectures, e.g. with './gradlew -Ponly-x86 assembleDebug'. This is working. 
     if (project.hasProperty('only-x86')) { 
      ndkConfig.abiFilters = ["x86"] as Set<String> 
     } 
     else if (project.hasProperty('only-armeabi-v7a')) { 
      ndkConfig.abiFilters = ["armeabi-v7a"] as Set<String> 
     } 
     else { 
      ndkConfig.abiFilters = ["x86", "armeabi-v7a"] as Set<String> 
     } 

     externalNativeBuild { 
      cmake { 
       cppFlags "-fexceptions", "-frtti", "-Wno-error" 
       arguments "-DANDROID_STL=gnustl_static" 
      } 
     } 
    } 

    buildTypes { 
     release { 
     } 
     debug { 
     } 
    } 

    externalNativeBuild { 
     cmake { 
      path '../../../CMakeLists.txt' 
     } 
     beforeEvaluate(println("I ma printed at the top.")) 
     afterEvaluate { println("I am printed before compiling.") } 
    } 
} 


dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    compile 'com.android.support:appcompat-v7:22.2.1' 
} 

task clean(type: Delete) { 
    delete "${rootProject.buildDir}" 
    delete "${project.buildDir}" 
    delete "${project.projectDir}/.externalNativeBuild" 
    delete fileTree(dir: "${project.projectDir}/src/main/jniLibs", include: '**/*.so') 
} 

その他の情報:

  • cmakeのバージョン:共有オブジェクトはjniLibsフォルダ内にあるので、ビルドが実際に除いて動作しているか3.6.3155560
  • AARファイルが正しく作成されましたコピーステップのために。

答えて

2

私は最後にそれを行う方法を考え出しました。ビルドされた共有オブジェクトをいくつかの場所から組み込むには、build.gradleのandroid部分にsourceSets.main.jniLibs.srcDirsを使用する必要があります。以下の例は、共有オブジェクトのAndroid cmake出力ディレクトリ(デバッグ用)から直接取り出します。例えば

android { 
    ... 
    defaultConfig { 
     ... 
    } 

    buildTypes { 
     release { 
     } 
     debug { 
     } 
    } 

    sourceSets { 
     main { 
      // Bundle so files with the final apk. 
      // NOTE: Currently bundles all shared objects in that directory. 
      // It was not straightforward to exclude in Android sourceSets at the time of writing, 
      // see https://code.google.com/p/android/issues/detail?id=64957 
      jniLibs.srcDirs = ['.externalNativeBuild/cmake/debug/libs'] 
     } 
    } 

    externalNativeBuild { 
     cmake { 
      path '../../../CMakeLists.txt' 
     } 
    } 
} 
関連する問題