简体   繁体   English

Android Gradle:未找到 ID 为“XXXX”的自定义插件 - Kotlin DSL

[英]Android Gradle: Custom Plugin with id 'XXXX' not found - Kotlin DSL

I'm trying to develop a gradle plugin to use it for generating some objects and methods for our api using some scheme.我正在尝试开发一个 gradle 插件,以使用它为我们的 api 使用某些方案生成一些对象和方法。 I have followed some tutorials but they all seem not to work, atleast for me.我遵循了一些教程,但它们似乎都不起作用,至少对我来说。 Some of these tutorials were:其中一些教程是:

  1. https://musings.animus.design/kotlin-poet-building-a-gradle-plugin/ https://musings.animus.design/kotlin-poet-building-a-gradle-plugin/
  2. https://medium.com/@magicbluepenguin/how-to-create-your-first-custom-gradle-plugin-efc1333d4419 https://medium.com/@magicbluepenguin/how-to-create-your-first-custom-gradle-plugin-efc1333d4419

I have not used the buildSrc module because I'm already using it for Kotlin DSL, so I decided to create a new module and create my plugin there.我没有使用 buildSrc 模块,因为我已经将它用于 Kotlin DSL,所以我决定创建一个新模块并在那里创建我的插件。

My plugin's module build.gradle.kts looks like this:我的插件模块build.gradle.kts看起来像这样:

plugins {
    id("java-gradle-plugin")
    id("kotlin")
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath(config.ClassPaths.androidBuildTools)
        classpath(config.ClassPaths.kotlinGradlePlugin)
    }
}

repositories {
    google()
    jcenter()
}

dependencies {
    implementation(config.ClassPaths.androidBuildTools)
    implementation(config.ClassPaths.kotlinGradlePlugin)
}

gradlePlugin {
    plugins {
        create("Generator") {
            id = "Generator"
            implementationClass = "Generator"
        }
    }
}

My projects settings.gradle.kts looks like this:我的项目settings.gradle.kts看起来像这样:

include(":SampleProject", ":scheme-generator")

And in my application module's build.gradle.kts I'm applying this plugin like this:在我的应用程序模块的build.gradle.kts中,我正在应用这个插件,如下所示:

apply(plugin = "Generator")

The build script stops here with an error: plugin 'Generator' not found构建脚本在此处停止并出现错误:未找到插件“生成器”

My Generator class looks like this:我的发电机 class 看起来像这样:

class Generator : Plugin<Project> {
    override fun apply(target: Project) {
        target.android().variants().all { variant ->

            // Make a task for each combination of build type and product flavor
            val myTask = "myFirstTask${variant.name.capitalize()}"

            // Register a simple task as a lambda. We can later move this to its own
            // class to make our code cleaner and also add some niceties.
            target.tasks.create(myTask){task ->

                // Group all our plugin's tasks together
                task.group = "MyPluginTasks"
                task.doLast {
                    File("${target.projectDir.path}/myFirstGeneratedFile.txt").apply {
                        writeText("Hello Gradle!\nPrinted at: ${SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(Date())}")
                    }
                }
            }
        }
    }
}

The android and variants methods are declared in a utils file, they look like this: androidvariants方法在 utils 文件中声明,它们如下所示:

object GeneratorUtils {

    fun Project.android(): BaseExtension {
        val android = project.extensions.findByType(BaseExtension::class.java)
        if (android != null) {
            return android
        } else {
            throw GradleException("Project $name is not an Android project")
        }
    }

    fun BaseExtension.variants(): DomainObjectSet<out BaseVariant> {
        return when (this) {
            is AppExtension -> {
                applicationVariants
            }

            is LibraryExtension -> {
                libraryVariants
            }

            else -> throw GradleException("Unsupported BaseExtension type!")
        }
    }

}

I have tried many things, but I seem not to get this right.我已经尝试了很多事情,但我似乎没有做到这一点。

EDIT: Using the buildSrc module for my plugin works totally fine, the plugin is applied and the gradle tasks are visible.编辑:为我的插件使用 buildSrc 模块工作得很好,插件被应用并且 gradle 任务是可见的。 However, buildSrc is reserved for other purposes, and we would like our plugin to be in a separate module, so we will be able to use it in other projects.但是,buildSrc 是为其他目的而保留的,我们希望我们的插件在一个单独的模块中,这样我们就可以在其他项目中使用它。

EDIT 13/04/2021编辑 13/04/2021

I have managed to see the tasks that are added by my plugin in my app tasks list by including this module as a composite build.通过将此模块包含为复合构建,我已设法在我的应用程序任务列表中查看我的插件添加的任务。

My settings.gradle now looks like this:我的settings.gradle现在看起来像这样:

pluginManagement {
    includeBuild("generator")
}

include(":SampleProject")

build.gradle of my plugin looks like this:我的插件的build.gradle如下所示:

apply plugin: 'java-gradle-plugin' // Allows us to create and configure custom plugins
apply plugin: 'kotlin' //Needed as we'll write our plugin in Kotlin

buildscript {
    ext {
        kotlin_version = '1.4.31'
        gradle_version = '4.1.2'
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.android.tools.build:gradle:$gradle_version"
    }
}

repositories {
    google()
    jcenter()
}

dependencies {
    // Android gradle plugin will allow us to access Android specific features
}

gradlePlugin {
    plugins {
        create("Generator") {
            id = "Generator"
            implementationClass = "com.example.Generator"
        }
    }
}

And my generator class now looks like this:我的发电机 class 现在看起来像这样:

class Generator : Plugin<Project> {

    override fun apply(project: Project) {

        project.tasks.register("generationTask") { task ->
            task.apply {
                group = "generation"
                actions.add(Action {
                    print("Hello from generation task!")
                })
            }
        }
    }

}

I can see generationTask in my tasks list and I can execute it normally.我可以在我的任务列表中看到generationTask ,我可以正常执行它。 It prints the text without any problems.它打印文本没有任何问题。

The problem now is to include com.android.tools.build:gradle:4.1.2 in my dependecies to use it to access build types and flavors and their paths to save my generated code there.现在的问题是在我的依赖项中包含com.android.tools.build:gradle:4.1.2以使用它来访问我的构建类型和风格及其保存路径。 When I add it to my dependencies block, gradle fails with this error: Could not find com.android.tools.build:gradle:4.1.2.当我将它添加到我的依赖项块时,gradle 失败并出现此错误: Could not find com.android.tools.build:gradle:4.1.2.

How can I solve this problem?我怎么解决这个问题?

Gradle build goes through specific set of phases , and the Configuration phase comes before the Execution phase. Gradle 构建经历了 一组特定的阶段,配置阶段在执行阶段之前。 So you cannot use a plugin, which is built in the same build process, because by the time gradle tries to use it on Configuration phase, the plugin has not been built yet.因此,您不能使用在相同构建过程中构建的插件,因为当 gradle 尝试在配置阶段使用它时,该插件尚未构建。

buildSrc directory is a special one, it's built not as part of the same build process, but in a separate build, before the main build process starts. buildSrc目录是一个特殊的目录,它不是作为同一构建过程的一部分构建的,而是在主构建过程开始之前在单独的构建中构建的。 This feature is called included or composite build .此功能称为包含或复合构建 buildSrc is just a pre-defined way to set up a composite build and you can define your own included builds. buildSrc只是一种设置复合构建的预定义方式,您可以定义自己的包含构建。 So to make your plugin visible to the main build, you need to put it into a separate build and include this build into a composite build as described in the doc above.因此,要使您的插件对主构建可见,您需要将其放入单独的构建中,并将此构建包含到复合构建中,如上面的文档中所述。 Here is an article describing how to transform a plugin defined in buildSrc into a composite build. 是一篇描述如何将buildSrc中定义的插件转换为复合构建的文章。

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

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