Gradle buildSrc and buildscript

谁说我不能喝 提交于 2021-02-18 20:56:13

问题


We have a Gradle build that includes a buildSrc with some custom plugins. Those plugins apply yet other plugins. For example, our plugin applies com.android.tools.build:gradle. For annotation processing that library needs to be on Gradle's classpath during compilation. So, putting this in our main build.gradle works:

buildscript {
    repositories {
        google()
    }
    dependencies {
       classpath "com.android.tools.build:gradle:$gToolsVersion"
    }
}

However, that means that for a user to apply this plugin they must (1) apply our plugin and (2) add that buildscript boilerplate. It seems like that shouldn't be necessary. We can also add a project.buildscript block inside our plugin but that too seems unnecessary and, due to this bug is problematic: https://developer.android.com/studio/build/gradle-plugin-3-0-0.html?utm_source=android-studio#known_issues.

I added the com.android.tools.build:gradle dependency to buildSrc/build.gradle as a runtime dependency. It seems like that should work: I thought that tells Gradle that in order to run my plugin that library (and its dependencies) need to be on the classpath. However, gradle buildEnvironment (and the fact that our build fails) makes it clear that's not the case.

So, questions:

  1. What's the difference between a runtime dependency specified in buildSrc/build.gradle and a classpath dependency specified in a buildscript block in a regular build.gradle?
  2. How can I arrange things so that users can apply the plugin from buildSrc and not have to also add the buildscript block to their build.gradle?

回答1:


I got a slightly different problem and found an acceptable solution that might help with for your second question: I wanted to apply the same repositories in the buildSrc/build.gradle and twice in the root build.gradle.

repositories.gradle in the project root:

repositories {
    if (project.hasProperty('nexus')) {
        maven {
            url 'http://localhost:8081/repository/JCenter/'
        }
        maven {
            url 'http://localhost:8081/repository/Maven_Google/'
        }
    } else {
        jcenter()
        google()
    }
}

ext {
    androidGradleBuildToolsDependency = 'com.android.tools.build:gradle:3.1.3'
}

buildSrc/build.gradle:

buildscript {
    apply from: '../repositories.gradle'
}

allprojects {
    apply from: '../repositories.gradle'
}

dependencies {
    // androidGradleBuildToolsDependency is defined in repositories.gradle
    implementation androidGradleBuildToolsDependency
}

Root build.gradle:

buildscript {
    apply from: 'repositories.gradle'
}

allprojects {
    // this line will also be executed from the build.gradles in subprojects, so the working
    // directory isn't always the same, so we use the absolute path here
    apply from: "${rootProject.projectDir}/repositories.gradle"
}

Note that you do not need the classpath dependency inside the buildscript block of the root build.gradle as you normally would. The implementation dependency in the repositories.gradle seems to auto apply it.

My solution probably doesn't work when the build.gradles are supplied via a dependency.




回答2:


Stumbled upon this while digging into a tangential problem.

I've been successfully using buildSrc/build.gradle as the place to define dependencies that would normally belong in the root-project's buildscript classpath for a few of my projects.

You can see a working example here: https://github.com/episode6/chop/blob/develop/buildSrc/build.gradle

I used to use compile dependencie but just switched to runtimeClasspath which feels more appropriate and also works. I don't think your classpath dependencies were working because they would be on the classpath of the buildSrc project, but not compiled into or run along side it.

If you decide to go this route, you may run into the problem I was just digging into which only came up because of this approach.

When I tried this approach with the dokka plugin, I got the following error

Could not resolve all files for configuration ':detachedConfiguration1'.
   > Cannot resolve external dependency org.jetbrains.dokka:dokka-fatjar:0.9.17 because no repositories are defined

I was able to workaround this by adding jcenter() to the root project's buildscript repositories: https://github.com/episode6/chop/blob/develop/build.gradle#L2



来源:https://stackoverflow.com/questions/47644319/gradle-buildsrc-and-buildscript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!