问题
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:
- What's the difference between a
runtime
dependency specified inbuildSrc/build.gradle
and aclasspath
dependency specified in abuildscript
block in a regular build.gradle? - How can I arrange things so that users can apply the plugin from
buildSrc
and not have to also add thebuildscript
block to theirbuild.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.gradle
s 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