Hello, can someone tell me more about `buildSrc`. ...
# gradle
a
Hello, can someone tell me more about
buildSrc
. Is
buildSrc
a 1-to1 replacement to
subProjects
and which one do you recommend to start a new multi module project if you're not writing a gradle plugin. I personally started using
subProjects
+
gradle.properties.kt
to share dep versions and found it to be super easy to use and flexible. Imagine a project where we share dependencies, you might have a root build.gradle, then 2 parents modules, then multiple sub module in each parent. Using subProjects we can have one in Parent A build.gradle.kts so that it doesn't impact sub modules of Parent B etc. From my understanding
buildSrc
is more for if you want to write a gradle plugin with logic and want to re-use kotlin kts script then you'd use the buildSrc and define kotlin files there instead of including scripts
include("myScript.kts")
. Or if you have complex gradle build logic then you'd use buildSrc as a place to essentially write that build logic. is that correct? Thanks
g
What is “subProjects”? Not quite understand, also part about “doesn’t impact sub modules”
I personally started using
subProjects
+
gradle.properties.kt
to share dep versions and found it to be super easy to use and flexible
If the only thing what you need is share depedency versions, do not use buildSrc, it’s very inneficient, because it causes full build scripts invalidation on any change But your gradle.properties.kt probably not the best solution too In both cases any change will recompile all your build scripts, which is very slow Use new version catalog feature for it, see official guide: https://docs.gradle.org/current/userguide/platforms.html
From my understanding
buildSrc
is more for if you want to write a gradle plugin with logic and want to re-use kotlin kts script then you’d use the buildSrc and define kotlin files there instead of including scripts
include("myScript.kts")
.
It’s correct, but also not only Kotlin Kts, but Java or Groovy Also it’s not just a matter of syntax. Because myScript.kts would be extremely hard to use, you cannot use anything inside of this script and it cannot bring any declarations to applied project So this why buildSrc is a lot better than simple included scripts. But not for dependencies, do not use it for dependencies
a
I meant
subprojects
sorry. Basically a way to define common stuff for sub module, eg:
Copy code
subprojects {

	apply(plugin = "org.jetbrains.kotlin.plugin.serialization")

	dependencies {
		implementation(project(":core:core-maths"))

		implementation("ch.qos.logback:logback-classic:$logbackVersion")
		implementation("aws.sdk.kotlin:s3:$awsVersion")
		implementation("io.insert-koin:koin-core:$koinVersion")
		implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion")
		implementation("io.ktor:ktor-client-core:$ktorVersion")
		implementation("io.ktor:ktor-client-cio-jvm:$ktorVersion")
		implementation("io.ktor:ktor-client-serialization-jvm:$ktorVersion")

		testImplementation("io.ktor:ktor-client-mock:$ktorVersion")
	}
}
g
It’s better do not use subprojects, it’s against best practices
subprojects break configuration cache. If you want to apply particular settings per project, it’s better to use buildSrc
a
I thought buildSrc would recompile all sub module when a change occurs ?
g
Though, it doesn’t mean that “Is
buildSrc
a 1-to1 replacement to
subProjects
“, because it’s not really 1 to 1 But yes, for such shared logic it’s better to create new plugin in buildSrc and apply it to any module
I thought buildSrc would recompile all sub module when a change occurs
Correct, same it will happen anyway here
it really depends actually
so there are cases when it will not recompile with buildSrc, also version catalog will help with version update
anyway, subprojects is not recommended and there is even chance that it will be a warning about it, because it doesn’t work with configuration cache
a
Here is an example
• root
build.gradle
makes use of
subprojects
• backend
build.gradle
makes use of
subprojects
• backend-frameworks makes use of
subprojects
so that all sub module have framework dependencies applied automatically, this does not affecdt other sub module that are not under
backend-frameworks
(it doesn't add the dependency to the other parent module etc). You're saying buildSrc would be better for me? Why exactly ? Happy to learn
g
so you apply particular dependencies dependning on project structure, I think it’s a valid strucutre in general, but it’s not what Gradle recommends, and instead recommend to apply plugins explicitly to every module
also problem with subprojects that it breaks configuration cache and will not work with future parallel configuration (aka module isolation)
a
I am happy to change it to
buildSrc
to follow the recommended approach but the doc about
buildSrc
seems to mention it has performance issues ? From what I understand you're saying the performance issues are the same on
buildSrc
and
subprojects
?
g
but the doc about
buildSrc
seems to mention it has performance issues
Could you point out on particular part
👍 1
a
I currently make use of parallel build via
org.gradle.parallel=true
from my
gradle.properties
, it seems to work
g
No, it’s parallel build, I’m talking about parallel configuration (step before build, when gradle compiles and prepares build strucutre)
👍 1
If the only thing what you need is share depedency versions, do not use buildSrc, it’s very inneficient, because it causes full build scripts invalidation on any change
But your gradle.properties.kt probably not the best solution too
In both cases any change will recompile all your build scripts, which is very slow
Pardon the confusion, do you suggest I use
buildSrc
or not for dependencies management ?
g
No, never use it for dependency versions
you can use version catalog (including in buildSrc, though it requires a bit of hack), so it will not cause recompilation of buildSrc automatically
a
Ok I will check the version catalog, will it replace my use of
subprojects
?
g
No, it only to declare versions and dependencies ids
a
Ok I see, so it's a replacement for
gradle.properties
then, so then would it be fair to say
subprojects
is recommended for dependency management, the version catalog for versions of the dependencies and
buildSrc
for applying plugins, sharing build logic (eg: complex logic or to build a gradle plugin) ?
g
https://kotlinlang.slack.com/archives/C19FD9681/p1654140678437369?thread_ts=1654135429.239839&cid=C19FD9681 It’s correct, but to be honest I’m not quite sure how script change will work for this in terms of recompilation, but also I feel that script (especially written with kotlin) is too limited for configuration, you cannot use plugins extensions or anything from build script classpath
If you change your plugins in buildSrc very often, then even better way to handle it, is to split buildSrc to multiple included builds. buildSrc is essentially just a conventional included build which applied automatically, so you may have 1 project per 1 plugin so on change only modules which use this plugin will be affected
wait, there is a sample project which uses this architecutre from one of ex-Gradle developers
👀 1
If you change your plugins in buildSrc very often
And if you change only versions of dependencies with version catalog (or something like simple Gradle Properties which resolved on runtime), it will not affect buildSrc or script compilation, only affect modules which use this dependencies to recompile code with new libray version
about subprojects, see they also methon it: • No cross-project configuration (subproject / allprojects) is performed
a
I see, so I should look to completely remove
subprojects
and use
buildSrc
+ version catalog then 🤔
g
ah yeah, just ignore part of sample which uses “libraries” module to share dependencies, it’s not relevant anymore with version catalog
🆗 1
a
Thanks, I'll review this tomorrow and try to migrate to
buildSrc
and completely remove
subprojects
then, so in the end, using
buildSrc
is fine for dependency management if we use version catalog yeah?
g
https://kotlinlang.slack.com/archives/C19FD9681/p1654141540590549?thread_ts=1654135429.239839&cid=C19FD9681 Good luck with it! It can be more work initially, but in general it will follow Gradle recommendation and may also be beneficial in future with Gradle updates
👍 1
a
Thanks a lot, I think it's a step in the right direction, you're right.
g
fine for dependency management if we use version catalog yeah?
if you apply dependencies from version catalog, yes You always can try to build a small sample and experiment and see when buildSrc updated
The only real missing part about version catalog and build src is this issue: https://github.com/gradle/gradle/issues/15383 But there is workaround in comment, I use it in a few projects without problems
👍 1