It seems that it is really related to the way the kotlin plugin compiles kotlin code and uses the mo...
b
It seems that it is really related to the way the kotlin plugin compiles kotlin code and uses the module information.
t
Kotlin plugin will support Gradle 7 starting from
1.5.0-M2
release
b
oh great, thanks for the heads up
t
if you will something not working, please add a comment to this issue: https://youtrack.jetbrains.com/issue/KT-44949
b
I think we (or just I) may want to document how to make modular programs with Kotlin, many of the tricks are not limited to Kotlin but I'm sure that would be helpful.
I got everything to work with 7.0 I just had to use a module-info.java generator plugin.
t
I think we (or just I) may want to document how to make modular programs with Kotlin, many of the tricks are not limited to Kotlin but I'm sure that would be helpful.
Would be nice 👍 If you will found something is missing in Kotlin for better modules support - please open a new issue.
j
I am using Gradle 7.0 since Kotlin... 1.4.20 I think, with no issues.
What should not work @tapchicoma?
t
@Javier 1.4.20 was released before G7-milestone-1 🤔 Anyway KGP will try to use several removed configurations, removed old workers api and few other things that should break the build with Kotlin
👍 1
b
The other thing I need to do all the time with modular builds is to put the kotlin and java destination dirs to the same one. If not, I have to declare all the packages manually in java using empty classes…
Let me know if there are ways to avoid doing that or if there is something I am doing wrong here
@Javier If you don't use modular builds, yes Gradle 7.0 works well. Just that there are a few things that changed regarding the way modules are handled and I was not using them properly so it started to break in Gradle 7.0
j
what do you mean which modular builds?
having multiple modules?
b
Java modular build system
👍 1
j
Well, in my case I am using multiple modules which Kotlin Multiplatform, so it is not the same and that can be the reason I had no problems
b
not the same "modules"
Java is moving slowly to a new way to manage libraries, that allows to build "JREs" that are tailored to your application. So your distributed applications are much smaller.
👍 1
and this is brittle with libraries that didn't move to that new way to advertise themselves (it really mostly take a module-info.java file). So you need plugins that create that for you during the build.
v
The other thing I need to do all the time with modular builds is to put the kotlin and java destination dirs to the same one. If not, I have to declare all the packages manually in java using empty classes…
You should not do that. Tasks should not have overlapping outputs or you f*** up proper up-to-date checks and build output caching. "Just" patch your Kotlin output directory into the java compilation task using
--patch-module
Something like this should do it properly I think:
Copy code
tasks.compileJava {
    options.compilerArgumentProviders.add(
        object : CommandLineArgumentProvider {
            @get:Optional
            @get:Classpath
            protected val compileKotlinOutputClasses =
                tasks.compileKotlin.flatMap { it.destinationDirectory }
            override fun asArguments() = listOf(
                "--patch-module",
                "my.foo=${tasks.compileKotlin.get().destinationDir.absolutePath}"
            )
        }
    )
}
t
@Vampire wow,
--patch-modules
is not exposed as compileJava task input?
v
Where
my.foo
is the module you are trying to build
I don't think so
t
b
@Vampire why would that break anything cache related if I don't have any java code?
v
But you have Java code
b
I have two options A) make java/kotlin output dir the same and put module-info.java in my kotlin dir B) create empty packages (which yes I agree will mess everything that's why I don't use it)
v
Or option C which I just told you how
No matter where you put the Java file, it is compiled by the java compile task
And the kotlin files are compiled by the kotlin compile task
b
Yes but I don't see the advantage compared to option A
v
You don't break things?
b
That's a good reason 😉
v
If both tasks have output directory "foo", taskA generates "foo/module-info.class" and taskB generates "foo/my/other/clazz/from/kotlin/Bar.class", then if you run both tasks, the second sees the output of the first as own output. Which might make it delete it on full recompilation, store it into the build cache and also restore it from the build cache, be out-of-date if the file changed or was deleted, ...
In ancient versions Groovy and Java compile tasks compiled to the same destination directory, until the Gradle guys have observed they hit these problems and properly separated the output directories.
The simple rule is to never have overlapping outputs for multiple tasks.
b
Oh that make sense… Your version seems to work.
That's always the thing with gradle… You have to find the people that know the right incantations…
thanks!