【问题标题】:Run CMake from gradle before compile Kotlin code在编译 Kotlin 代码之前从 gradle 运行 CMake
【发布时间】:2019-11-08 08:08:42
【问题描述】:

使用 Gradle 5.4.1,我想为 Android 应用构建一个 CMake 项目。这可以在 app/build.gradle 中完成:

externalNativeBuild {
    cmake {
        // Provides a relative path to your CMake build script.
        version "3.13.0+"
        path "../subproject/CMakeLists.txt"
    }
}

该项目使用 SWIG 生成一个共享库和一些 Java 文件。我可以通过 -DJAVA_OUTPUT_DIR=generated/java 指定 Java 源的输出目录。

如何强制 gradle 在编译主应用源代码 (Kotlin) 之前等待 CMake 构建?源代码导入生成的 JAVA 文件,当前构建过程因缺少 Java 文件而失败。看来 gradle 并行运行 cmake 和 Kotlin 编译器。

额外问题:如何将生成的源输出目录作为生成的源添加到 AndroidStudio 项目树中?树中有一个用于生成源的特殊条目。

版本信息:

$ ./gradlew --version -------------------------------------------------- ---------- 摇篮 5.4.1 -------------------------------------------------- ---------- 构建时间:2019-04-26 08:14:42 UTC 修订:261d171646b36a6a28d5a19a69676cd098a4c19d 科特林:1.3.21 时髦的:2.5.4 Ant:2018 年 7 月 10 日编译的 Apache Ant(TM) 版本 1.9.13 JVM:11.0.5(Debian 11.0.5+10-post-Debian-1deb10u1) 操作系统:Linux 4.19.0-6-amd64 amd64

【问题讨论】:

  • @SergeyVoytovich 不,我的 gradle 脚本中没有任何自定义任务。或者我可以写一些类似 preBuild.dependsOn(some_cmake_build_task) 的东西吗?那么任务的正确名称是什么?

标签: android gradle kotlin cmake swig


【解决方案1】:

您应该添加cmake 任务作为compileKotlin 任务的依赖项。

Gradle 任务是部分排序的(一些任务应该在其他一些任务之前启动)。依赖关系用于表达这种关系。

要声明对 externalNativeBuild 的依赖 - 将此附加到 build.gradle

project.afterEvaluate {
    if (tasks.findByName("externalNativeBuildDebug")) {
        compileDebugKotlin.dependsOn externalNativeBuildDebug
    }
    if (tasks.findByName("externalNativeBuildRelease")) {
        compileReleaseKotlin.dependsOn externalNativeBuildRelease  
    }
}
  • 什么是afterEvaluate?这是 gradle 的生命周期阶段。这是阅读和应用所有定义的时候。阅读更多here

  • externalNativeBuildDebugexternalNativeBuildRelease 是什么?这些是对externalNativeBuild 任务的引用,具体取决于特定的构建命令

【讨论】:

  • 这失败了:Could not get unknown property 'compileKotlin' for project ':app' of type org.gradle.api.Project.
  • @cytrinox 在 android 项目 stackoverflow.com/questions/44141076/… 中看起来名称不同。我更新答案
  • 最后一行应该是compileReleaseKotlin而不是compileDebugKotlin?
【解决方案2】:

虽然接受的答案效果很好,但我使用libraryVariants 来做到这一点。我个人觉得它更优雅。这是我的 Kotlin DSL 脚本中的样子:

android {
    libraryVariants.all {
        tasks.findByName("compile${name.capitalize()}Kotlin")
            ?.dependsOn(tasks.findByName("externalNativeBuild${name.capitalize()}"))
    }
}

此解决方案的显着优势在于它与您的构建变体无关,并且如果您更改/添加变体,它将继续工作而无需修改。

【讨论】:

  • 我的印象是 OP 的项目是一个应用程序项目,所以在这种情况下,它可能应该是 applicationVariants.all 而不是 libraryVariants.all
  • 真的!感谢您的精确!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 2018-05-15
相关资源
最近更新 更多