简体   繁体   English

Gradle 模块构建顺序 2

[英]Gradle Module Build Order 2

I have and Android Gradle project with many modules (only AARs, no APP).我有很多模块的 Android Gradle 项目(只有 AAR,没有 APP)。

Because Google does not support fat AARs, I need to do the repackaging myself (I tried multiple fat AAR Gradle plugins but none of it is actually working, support did not help me at all).因为谷歌不支持胖 AAR,我需要自己重新打包(我尝试了多个胖 AAR Gradle 插件,但没有一个实际工作,支持根本没有帮助我)。

So I have to write the repackaging myself (as a Groovy script, directly into my Gradle build system).所以我必须自己编写重新打包(作为 Groovy 脚本,直接写入我的 Gradle 构建系统)。

For that I need to:为此,我需要:

  • Build many AARs - these are multiple Gradle modules构建许多 AAR - 这些是多个 Gradle 模块
  • Repackage all those AARs into the one big AAR - this is a special Gradle module (all the AARs above are set as the implementation dependency to this AAR)将所有这些 AAR 重新打包成一个大 AAR - 这是一个特殊的 Gradle 模块(以上所有 AAR 都设置为该 AAR 的实现依赖项)
  • Then obfuscate everything using DexGuard (no ProGuard/R8 - these are too weak)然后使用 DexGuard 混淆所有内容(没有 ProGuard/R8 - 这些太弱了)

The repackaging works fine to me.重新包装对我来说很好。 BUT...但...

If I execute this to ensure the clean release build:如果我执行此操作以确保干净的发布版本:

./gradlew clean :MbiSdkLibrary:assembleRelease

It first cleans everything and then tries to build my FAT library.它首先清理所有内容,然后尝试构建我的 FAT 库。

The problem is that the MbiSdkLibrary AAR build starts in parallel with the build of dependency AARs, while the build of the other AARs is NOT fully completed yet.问题是 MbiSdkLibrary AAR 构建与依赖 AAR 的构建并行开始,而其他 AAR 的构建尚未完全完成。 In other words, Gradle seems to ignore the dependencies when determining the build order.换句话说,Gradle 在确定构建顺序时似乎忽略了依赖关系。

Subsequently the repackaging of MbiSdkLibrary (the final fat AAR) fails randomly (it is a race) on the missing AAR from the other (parallel) builds.随后,MbiSdkLibrary(最终的胖 AAR)的重新打包在其他(并行)构建中丢失的 AAR 上随机失败(这是一场竞赛)。

Of course I can achieve the build working this way (I tested, it works just fine):当然,我可以通过这种方式实现构建(我测试过,效果很好):

  • Build the dependency AARs first with a separate gradle command首先使用单独的 gradle 命令构建依赖项 AAR
  • Build the final fat AAR afterwards (without the clean task)之后构建最终的胖 AAR(没有清理任务)

But that solution sounds stupid to me, I believe Gradle cannot be that limited to be unable to do such a simple thing properly...但是这个解决方案对我来说听起来很愚蠢,我相信 Gradle 不能被限制到无法正确地做这么简单的事情......

I also Googled a lot and tried a few workarounds, including eg this one:我也用谷歌搜索了很多并尝试了一些解决方法,包括例如这个:

My question is related to this question: Gradle Module Build Order .我的问题与这个问题有关: Gradle Module Build Order

Sorry, for some reason, I am not allowed to communicate there so I am forced to flood SO with another (very similar) question.抱歉,出于某种原因,我不允许在那里进行交流,所以我被迫用另一个(非常相似的)问题来淹没 SO。

I was able to HACK the problem using the task of GradleBuild type.我能够使用 GradleBuild 类型的任务来解决这个问题。

But it made the build 5 times slower and consuming a lot of more memory.但它使构建速度变慢了 5 倍并消耗了更多内存。

This is my method这是我的方法

// Note: This method is a bit hacky solution:
// - It creates a child Gradle build which can easily cause OOM error
// Awaiting response for the Gradle related question:
// - https://stackoverflow.com/questions/59624688/gradle-module-build-order-2
// - Hopefully someone knows better way hot to do this properly

def aarDependencies_setupModuleDependencies(task) {
    String buildType
    if (task.name == 'preBuild') {
        buildType = ''
    } else if (task.name == 'preDebugBuild') {
        buildType = 'Debug'
    } else if (task.name == 'preReleaseBuild') {
        buildType = 'Release'
    } else {
        return
    }
    List<String> taskList = new ArrayList<>()
    project.ext.REPACKAGING__PROJECT_DEP.each { dirFn ->
        String moduleName = dirFn[1]
        String taskToRun = ":$moduleName:assemble$buildType"
        taskList.add(taskToRun)
    }
    task.dependsOn tasks.create(name: "buildDependenciesFor${buildType}", type: GradleBuild) {
        dir "../../"
        buildFile 'build.gradle'
        setTasks(taskList)
        doFirst {
            aarDependencies_log("Ensuring dependencies for build type '${buildType}' are available...")
        }
        doLast {
            aarDependencies_log("Ensuring dependencies for build type '${buildType}' are available: DONE")
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM