Android Studio 中的 Gradle 任务排序问题

Posted

技术标签:

【中文标题】Android Studio 中的 Gradle 任务排序问题【英文标题】:Gradle task ordering issue in Android Studio 【发布时间】:2016-08-31 22:58:52 【问题描述】:

我正在使用 android Studio 2.2 Beta 3,我的测试项目使用 CMake 构建混合 C++ 和 Java 应用程序。 JNI 接口由 SWIG 生成。这意味着我想在 externalNativeBuild 和 JavaCompile gradle 任务之前生成 SWIG 包装器;即我的 CMakeLists.txt 指定 SWIG 生成的 cpp 包装文件,我的 java 代码导入 SWIG 生成的 java 包装文件。

为了确保 SWIG 在任何任务之前运行并生成必要的包装文件,我在我的 app/build.gradle 文件中指定了以下内容

project.afterEvaluate 
    preBuild.dependsOn("runSwig")

当我使用命令从命令行运行时

./gradlew assembleDebug

我没有遇到任何问题,正如预期的那样,我的任务“runSwig”在任何其他任务之前运行

:app:runSwig
:app:preBuild
:app:preDebugBuild
<blah blah more tasks>
:app:externalNativeBuildDebug

但问题是当项目第一次在 Android Studio 中打开时,看起来外部原生构建在 runSwig 之前被调用,我得到了错误

CMake Error at CMakeLists.txt:79 (add_library):
  Cannot find source file:

    ../../../wrap.cxx

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx

FAILURE: Build failed with an exception.

错误不会消失,直到我使用命令行或从我的 CMakeLists.txt 中删除 wrap.cxx 文件并在 swig 成功运行至少一次后重新添加它。

【问题讨论】:

【参考方案1】:

我在 Android Studio 3(我猜是 2.3)中的构建顺序也遇到了同样的问题。

我不知道这是否是传统上有效的解决方案,但它 - 似乎 - 在我的 Android/SWIG/NDK 示例中工作(此处:https://github.com/sureshjoshi/android-ndk-swig-example)

我将此添加到我的 Gradle 文件中,以便在构建因丢失文件而失败之前调用 CMake。 CMake 调用 SWIG 来自动生成我的 Java 文件并适当地放置它们。

project.afterEvaluate 
    javaPreCompileDebug.dependsOn externalNativeBuildDebug

我可能还需要一个

javaPreCompileRelease.dependsOn externalNativeBuildRelease

或类似的东西...只是还没有测试过。

源于这个问题:https://github.com/sureshjoshi/android-ndk-swig-example/issues/8

【讨论】:

【参考方案2】:

是的,这是因为 Android Studio IDE 需要在编译之前获取要在 IDE 中显示的文件:暴露命令行和 IDE 构建之间的不同行为。在here 中,我比其他任何事情都更早地下载了所需的存储库,因此 Android Studio 不会抱怨。但它并不漂亮......而且android studio启动时间很长......

【讨论】:

【参考方案3】:

问题:由于某些原因,在“preBuild”任务中添加 build.gradle 自定义任务以运行 SWIG 生成会阻止 CMakeList.txt 编译。

上一个答案SJoshi 对我有很大帮助。 我有 build.gradle.kts 模块,下面的代码正在运行:

    tasks.register("make-swig-script-executable", Exec::class) 
        description = "Make swig-generate script executable"
        commandLine = "chmod +x swig/run_shig.sh".split(" ")
    

    tasks.register("swig-generate", Exec::class) 
        dependsOn("make-swig-script-executable")
        description = "Generating JNI files by swig"
        commandLine = "swig/run_shig.sh".split(" ")
    

    tasks.withType(JavaCompile::class) 
        dependsOn("swig-generate")
    

    project.afterEvaluate 
        task("javaPreCompileDebug").dependsOn("externalNativeBuildDebug")
    

我的代码中有以下几行及其不工作

//same tasks swig-generate and make-swig-script-executable
//but different "trigger event" (on preBuild)

tasks.matching  it.name == "preBuild" .all 
    dependsOn("swig-generate")

【讨论】:

以上是关于Android Studio 中的 Gradle 任务排序问题的主要内容,如果未能解决你的问题,请参考以下文章

React Native:build.gradle 文件中的 Android Gradle Plugin 和 Android Studio 有啥区别?

Gradle,Gradle 包装器在 Android Studio 中的不同实例 by ionic cordova

理解与配置android studio中的gradle

解决android studio中的gradle依赖问题?

详细配置android studio中的gradle

Android Gradle 插件Gradle 构建机制 ⑤ ( 在 Android Studio 中查看 Android Gradle 插件源码 )