发布多平台库

You can publish a multiplatform library to a Maven repository with the maven-publish Gradle plugin. Specify the group, version, and the repositories where the library should be published. The plugin creates publications automatically.

  1. plugins {
  2. //...
  3. id("maven-publish")
  4. }
  5. group = "com.example"
  6. version = "1.0"
  7. publishing {
  8. repositories {
  9. maven {
  10. //...
  11. }
  12. }
  13. }

You can also use gradle-bintray-plugin for publishing multiplatform libraries. However, this plugin does not support publishing Gradle module metadata required for hierarchical structure support. Use this workaround to enable metadata publishing or migrate to the maven-publish plugin.

Structure of publications

When used with maven-publish, the Kotlin plugin automatically creates publications for each target that can be built on the current host, except for the Android target, which needs an additional step to configure publishing.

Publications of a multiplatform library include an additional root publication kotlinMultiplatform that stands for the whole library and is automatically resolved to the appropriate platform-specific artifacts when added as a dependency to the common source set. Learn more about adding dependencies.

This kotlinMultiplatform publication includes metadata artifacts and references the other publications as its variants.

You must not add an empty artifact without a classifier to the root module of your library to meet the requirements of repositories such as Maven Central, as this will result in a conflict with metadata artifacts that are included in this module.

The kotlinMultiplatform publication may also need the sources and documentation artifacts if that is required by the repository. In that case, add those artifacts by using artifact(...) in the publication’s scope.

Avoid duplicate publications

To avoid duplicate publications of modules that can be built on several platforms (like JVM and JS), configure the publishing tasks for these modules to run conditionally.

You can detect the platform in the script, introduce a flag such as isMainHost and set it to true for the main target platform. Alternatively, you can pass the flag from an external source, for example, from CI configuration.

This simplified example ensures that publications are only uploaded when isMainHost=true is passed. This means that a publication that can be published from multiple platforms will be published only once – from the main host.

  1. kotlin {
  2. jvm()
  3. js()
  4. mingwX64()
  5. linuxX64()
  6. def publicationsFromMainHost =
  7. [jvm(), js()].collect { it.name } + "kotlinMultiplatform"
  8. publishing {
  9. publications {
  10. matching { it.name in publicationsFromMainHost }.all { targetPublication ->
  11. tasks.withType(AbstractPublishToMaven)
  12. .matching { it.publication == targetPublication }
  13. .configureEach { onlyIf { findProperty("isMainHost") == "true" } }
  14. }
  15. }
  16. }
  17. }
  1. kotlin {
  2. jvm()
  3. js()
  4. mingwX64()
  5. linuxX64()
  6. val publicationsFromMainHost =
  7. listOf(jvm(), js()).map { it.name } + "kotlinMultiplatform"
  8. publishing {
  9. publications {
  10. matching { it.name in publicationsFromMainHost }.all {
  11. val targetPublication = [email protected]
  12. tasks.withType<AbstractPublishToMaven>()
  13. .matching { it.publication == targetPublication }
  14. .configureEach { onlyIf { findProperty("isMainHost") == "true" } }
  15. }
  16. }
  17. }
  18. }

By default, each publication includes a sources JAR that contains the sources used by the main compilation of the target.

发布 Android 库

To publish an Android library, you need to provide additional configuration.

By default, no artifacts of an Android library are published. To publish artifacts produced by a set of Android variants, specify the variant names in the Android target block:

  1. kotlin {
  2. android {
  3. publishLibraryVariants("release", "debug")
  4. }
  5. }

The example works for Android libraries without product flavors. For a library with product flavors, the variant names also contain the flavors, like fooBarDebug or fooBazRelease.

If a library consumer defines variants that are missing in the library, they need to provide matching fallbacks. For example, if a library does not have or does not publish a staging build type, the library consumer must provide a fallback for the consumers who have such a build type, specifying at least one of the build types that the library publishes:

  1. android {
  2. buildTypes {
  3. staging {
  4. // ...
  5. matchingFallbacks = ['release', 'debug']
  6. }
  7. }
  8. }
  1. android {
  2. buildTypes {
  3. val staging by creating {
  4. // ...
  5. matchingFallbacks = listOf("release", "debug")
  6. }
  7. }
  8. }

Similarly, a library consumer needs to provide matching fallbacks for custom product flavors if some are missing in the library publications.

You can also publish variants grouped by the product flavor, so that the outputs of the different build types are placed in a single module, with the build type becoming a classifier for the artifacts (the release build type is still published with no classifier). This mode is disabled by default and can be enabled as follows:

  1. kotlin {
  2. android {
  3. publishLibraryVariantsGroupedByFlavor = true
  4. }
  5. }

It is not recommended that you publish variants grouped by the product flavor in case they have different dependencies, as those will be merged into one dependencies list.