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:
runtime
dependency specified in buildSrc/build.gradle
and a classpath
dependency specified in a buildscript
block in a regular build.gradle?buildSrc
and not have to also add the buildscript
block to their build.gradle
?buildSrc is a directory at the Gradle project root, which can contain our build logic. This allows us to use the Kotlin DSL to write our custom build code with very little configuration and share this logic across the whole project.
Gradle builds a script file for handling two things; one is projects and other is tasks. Every Gradle build represents one or more projects. A project represents a library JAR or a web application or it might represent a ZIP that is assembled from the JARs produced by other projects.
The " buildscript " configuration section is for gradle itself (i.e. changes to how gradle is able to perform the build). So this section will usually include the Android Gradle plugin. The " allprojects " section is for the modules being built by Gradle.
There are two general types of plugins in Gradle, binary plugins and script plugins.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With