So we have this build where we are using some libraries which have, for whatever reason, been distributed as different jar files for different native operating systems.
And of course, those libraries have arranged it so that if we include all of them at the same time, things blow up.
All good, we just make sure we include exactly the correct ones, like this:
if (isWindows()) {
runtimeOnly(libraries.nd4j.windows)
runtimeOnly(libraries.openblas.windows)
} else if (isMacOS()) {
runtimeOnly(libraries.nd4j.macos)
runtimeOnly(libraries.openblas.macos)
} else if (isLinux()) {
runtimeOnly(libraries.nd4j.linux)
runtimeOnly(libraries.openblas.linux)
}
Now, I can certainly code golf this a little. Bump the condition inside the function call, then move the condition into libraries so nobody sees it, things like that. That isn't the issue, though.
The issue is, when I publish this project, depending on what OS I was sitting at when I ran the build, the published project's POM will say it depended on the Windows variants of those jars. Someone else then tries to build against my project on macOS, and it doesn't work.
Had Gradle recognised the existence of profiles and supported it, those projects could have declared that they have multiple profiles which depend on the platform you're running the build. Our build could have then done the same thing and put that into our POM. Downstream projects would then see that, and everything would be fine.
Gradle, however, does not support Maven profiles for reading or for writing POMs, so the only way to split this seems to be to divide my project into four subprojects - a common part, a windows part, a macos part and a linux part, so that each can have different dependencies. All my code then lives in the common directory, and most dependency declarations live in the common subproject, and then each of the platform-specific subprojects would depend on common and the corresponding platform-specific version of the two nasty dependencies.
And now I'm the one creating the problem, because whoever wants to use my library will hit the same problem, and complain about it. And so on.
Is there no better way to go about this?
I know Kotlin/Multiplatform is a thing and have seen how those builds are structured, but this project isn't yet using Kotlin at all (It's a Java project, though the build scripts are in the process of being rewritten to Kotlin DSL), so it doesn't get to benefit from any of that unless I can somehow twist it to work for our not quite the same use case.