首页 > 解决方案 > 如何过滤 gradle 中的子模块以应用适当的插件?

问题描述

我有一个多模块项目,其中一些是 Java 库,另一些是 Android 库。我想根据项目类型为我的子项目(模块)应用自定义插件,所以我在我的项目根build.gradle文件中做了类似的事情(见下面的代码片段)。此设置有效,但我想知道是否还有其他方法可以做到这一点。Gradle 建议按属性过滤,Cannot add task 'integTest' as a task with that name already exists但如果我尝试这样做,我会收到错误消息。这integTest是我在customJavaBuild.gradlecustomAndroidBuild.gradle文件中创建的任务。任何帮助表示赞赏。谢谢!

def javaLibraries = ["projA", "projB"]
def androidLibraries = ["projC"]

subprojects {
    if (javaLibraries.contains(it.name)) {
        apply from: '$rootDir/gradle/customJavaBuild.gradle'
    } else if (androidLibraries.contains(it.name)) {
        apply from: '$rootDir/gradle/customAndroidBuild.gradle'
    } else {
        //Apply custom plugin for some other project type.
    }
} 

按属性过滤

subprojects {
    project.ext {
        projectType = null
    }

    project.afterEvaluate {
        if (project.ext.projectType == 'jar') {
            apply from: '$rootDir/gradle/customJavaBuild.gradle'
        } else if (project.ext.projectType == 'aar') {
            apply from: '$rootDir/gradle/customAndroidBuild.gradle'
        } else {
            //Apply custom plugin for some other project type.
        }
    }
}

ext.projectType = 'jar'我的子模块(projA、projB、projC)build.gradle文件中有这个额外的属性。

标签: androidgradleandroid-gradle-pluginbuild.gradle

解决方案


问题是,在您的project.afterEvaluate块中,您将自定义 gradle 脚本应用于root project而不是评估,这会导致已定义任务sub project的错误。integTest

project.afterEvaluate您应该使用类似于以下内容的内容重写您的 块:

subprojects {
    project.ext {
        projectType = null
    }

    project.afterEvaluate {
        if (project.ext.projectType == 'jar') {
            // WARNING : use "project.apply ..." instead of "apply ..." here
            project.apply from : "$rootDir/gradle/customJavaBuild.gradle"
        } else if (project.ext.projectType == 'aar') {
            project.apply from : "$rootDir/gradle/customAndroidBuild.gradle"
        } else {
            // nothing
        }
    }

}


推荐阅读