FabricMC / fabric-loom

Gradle build system plugin used to automate the setup of a minecraft mod development environment.
MIT License
241 stars 211 forks source link

modImplementation has trouble handling transitive dependencies with multiple classifiers #756

Open Igrium opened 1 year ago

Igrium commented 1 year ago

For context, I'm working on a framework for making JavaFX applications on top of Fabric and Minecraft.

In order to ensure JavaFX classes are properly packed into the library, I am not using the JavaFX Gradle plugin, and am instead manually including the dependencies as follows. The problem, however, still presents itself if I use the plugin.

def currentOS = org.gradle.internal.os.OperatingSystem.current()
def platform
if (currentOS.isWindows()) {
    platform = 'win'
} else if (currentOS.isLinux()) {
    platform = 'linux'
} else if (currentOS.isMacOsX()) {
    platform = 'mac'
}

dependencies {
    // ...
    api(include("org.openjfx:javafx-base:${project.javaFX_version}:${platform}"))
    api(include("org.openjfx:javafx-controls:${project.javaFX_version}:${platform}"))
    api(include("org.openjfx:javafx-graphics:${project.javaFX_version}:${platform}"))
    api(include("org.openjfx:javafx-fxml:${project.javaFX_version}:${platform}"))
    api(include("org.openjfx:javafx-web:${project.javaFX_version}:${platform}"))
}

This works as expected, both in a development environment and a standalone environment. However, when I try to include my library in a mod using modImplementation (and Maven Local), the build fails:

modImplementation "com.igrium:craftfx:0.1.0-${platform}"
* What went wrong:
Execution failed for task ':compileJava'.
> Could not resolve all dependencies for configuration ':compileClasspath'.
   > org.openjfx:javafx-controls:17-ea+13 has more than one client module definitions.

If I change modImplementation to implementation, the dependencies resolve properly, but the build fails due to mapping issues (obviously).

I'm pretty sure this is a problem with Loom, but I'm not the best with Gradle, so I could be doing something wrong. I would like it to be as simple as possible for users of my library.

modmuss50 commented 1 year ago

This error is always fun.

https://discuss.gradle.org/t/has-more-than-one-client-module-definitions-when-trying-to-use-dependencies-module-more-than-once-with-different-classifiers/39534/2 may help, but im not sure as there seems to be little to no doucmentation on this...

Although as you said implementation works as expected so its quite possible something is up with loom. As for what im not quite sure without diving into this rabbit hole.

One thing I did notice is the way your are including the platform natives, it will only include the natives for the platform it was built on, I expect you really want to include all of the win/lin/mac natives as well.

Igrium commented 1 year ago

The intent when it comes to the natives is to distribute three builds of the library: one for each platform. Mod developers should use their own platform in their build script so that the code can run, but the compiled jar is platform-independent so that users can install the correct version for their platform.