I am trying to learn how to use “platforms” to align dependency versions between projects in a multi-project setup. So far I’ve seen:
- https://docs.gradle.org/6.2.1/userguide/platforms.html
- https://docs.gradle.org/6.2.1/userguide/dependency_management_terminology.html#sub::terminology_platform
- https://docs.gradle.org/6.2.1/userguide/dependency_version_alignment.html#sec:virtual_platform
- https://docs.gradle.org/6.2.1/userguide/dependency_constraints.html#sec:adding-constraints-transitive-deps
- https://docs.gradle.org/6.2.1/userguide/java_platform_plugin.html
- … and some more external sites trying to find examples, such as https://dzone.com/articles/gradle-goodness-use-bill-of-materials-bom-as-depen
I understand how I can declare constraints within a project. I think I also understand how to use BOMs for this purpose. However, I would like to use an “enforced platform project” for this purpose and I don’t understand a number of things here:
- Do I have to use a “java platform” plugin or not? We have non-Java projects. Our configurations don’t quite fit into the “api” and “runtime” buckets.
- Even if we were all Java, for any one project, we can’t have separate versions for its “api” and for its “runtime”. While I do understand the level of control this may offer in some cases, I do not understand how are these meant to work together, to make sure that the project gets the specified dependency.
- How does Gradle know which configurations’ constraints to match between the project using the platform and the platform specifications? I think I saw the examples defining “api” and other constraints in the platform and I “understand” that the projects would reference this by declaring api platform(project(':platform')). I hope Gradle isn’t trying to match “api” to “api” by simple name matching. I’d need multiple different dependency configurations to all be aligned against the same single platform “configuration” whatever it is called.
In general, I didn’t find enough information to feel confident about what this does or how it works. Can someone fill in the blanks or point me to some document showing more examples and details than the above? At this time I don't understand what should I actually write for that platform project (its build.gradle
) and/or how would I correctly reference it from the current projects we have.
Thanks!
UPDATE 1: Posted a minimal experiment to test my (lack of) understanding of this at https://discuss.gradle.org/t/can-someone-tell-me-what-i-am-doing-wrong-to-align-dependency-versions-across-projects/35601 ...
No. If you have non-Java projects then you should not use the Java platform plugin. As the plugin name indicates, it's for Java projects.
Gradle offers an official platform plugin for Java projects, but anything outside of that such as C++/Swift, you will need to roll your own plugin/implementation of a platform. You can refer to the source code to help with your implementation.
You don't need to have separate versions for each configuration.
api
extendsimplementation
andruntimeClasspath
(runtimeOnly
) extends fromimplementation
. So declaring dependencies forapi
should be sufficient enough. Refer to the dependency diagram here.By how you specify it in your project and the Java platform plugin's implementation of a platform. For example, given the following platform:
I can do any of the following in a project:
Matching is done based on the usage. See this line and these lines.
api
is just the configuration name Gradle chosen for their plugin, see here. They literally could have chosen any name, but more likely choseapi
/runtime
to keep things similar with what they have.Most of the documentation you will find on platforms is geared toward Java developers. I believe this primarily due to the concept of platform being heavily inspired by Maven's BOM
If you really want to know how Gradle is doing things with the platform, then either painfully examine the source code or write a simple Gradle plugin that uses the platform, and then write a test using the GradleRunner and debug with breakpoints. Example plugin could be: