Configuring publication variants allows you to publish different build variants, each with their own attributes. Publishing multiple build variants of your library allows your user to choose the appropriate features for their needs. For example, you can publish different artifacts for the debug versus release build types. The debug publication artifact might have extra logging code, and different dependencies to enable this extra logging. Publication variants allow you to create a more customized experience for your users.
Before you proceed, make sure you have prepared your library for release.
Use Gradle Module Metadata
In order to publish variants of your library, you must use Gradle Module Metadata (GMM) GMM is used to describe your publication and maintain variant-aware dependency management. It is published with your library by default. To summarize the benefits of using GMM:
- If you use GMM with Gradle 6.0 or higher, you can publish multiple publication variants, or multiple artifacts—each with their own attributes and dependencies. If you use Maven’s POM file instead of GMM, you can only publish one artifact. If you use a POM file, you can publish additional artifacts using classifiers, but the additional artifacts cannot have their own dependencies.
- You might publish one variant for compilation and one for runtime, so the
consumer can choose based on when they are using your library. Gradle
automatically creates one variant for compilation and one for runtime, each with
their own dependencies. This is what allows consumers to see different
dependencies for compile and runtime, based on the published library’s usage of
api
,implementation
, orcompileOnly
/runtimeOnly
(see Dependency configurations for a full list). This is available even if you publish a single publication variant. - When using test fixtures, you can publish an additional variant with special metadata (or capabilities) that allows the consumer to select it. This is available even if you publish a single publication variant.
Understanding publication variants
To understand how publication variants work, it is helpful to be familiar with Gradle’s basic publishing steps. Here are some key concepts:
- Build variant: The configuration Gradle uses to build your library; the cross product of build type and product flavor. To learn more, see the Android build glossary.
- Artifact: A file or directory produced by a build. In the context of library publishing, an artifact is usually a JAR or AAR file.
- Publication variant: An artifact with its associated attributes, features, and dependencies. Note that Gradle calls publication variants variants; however, they are called publication variants in these docs to distinguish them from the concept of build variants.
- Attribute:
Used by Gradle to identify and select publication variants when there are
multiple options. For example,
org.gradle.usage=java-api
andorg.gradle.jvm.version=11
are variant attributes. - Software component:
A Gradle object that can hold one or more publication variants, and is published
to a single set of Maven coordinates (
groupdId:artifactId:version
). It is exposed in Gradle's DSL throughProject.getComponents()
. - Publication:
What gets published to the repository and used by consumers; consists of one
software component and its metadata, for instance its identity
(
groupId:artifactId:version
).
AGP 7.1 introduces a domain-specific language (DSL) to control which build
variants are used during publication and which are ignored. The DSL allows you
to create instances of SoftwareComponent
that contain either of the following:
- One publication variant from one build variant.
- Several publication variants from several build variants.
When creating a software component with multiple publication variants, AGP sets up attributes on each variant that allows the consumer to select the right variant they need. These attributes come directly from the build type and flavors that were used to create the build variant. When creating a component with a single publication variant, no attributes are used because there is no need for disambiguation.
Create a software component with a single publication variant
The following snippet configures a software component with a single publication
variant created from the release
build variant, and adds the source JAR as a
secondary artifact:
Groovy
android { publishing { singleVariant('release') { withSourcesJar() } } }
Kotlin
android { publishing { singleVariant("release") { withSourcesJar() } } }
You can create several components, each with a single publication variant, and distribute them under different Maven coordinates.
In this case, no attributes are set on the publication variant. So, you can’t
tell that this publication variant is from the release
build variant by
looking at the publication metadata. This is okay because there is only one
publication variant involved, and there is no need for disambiguation.
Create a software component with multiple publication variants
You can select all or a subset of build variants to put in a single software component. AGP automatically uses the build type names, product flavor names, and product flavor dimension names to create attributes so that the consuming project can tell them apart.
To publish all build variants in a single component, specify allVariants()
in the multipleVariants{}
block in the module-level build.gradle
file:
Groovy
android { publishing { multipleVariants { allVariants() withJavadocs() } } }
Kotlin
android { publishing { multipleVariants { allVariants() withJavadocs() } } }
This creates a single component called default
. To name your component
something else, use multipleVariants({name})
.
In this case, all build type and product flavor dimensions are used as
attributes.
It is also possible to select which variants are published by using
includeBuildTypeValues()
and includeFlavorDimensionAndValues()
:
Groovy
android { publishing { multipleVariants('custom') { includeBuildTypeValues('debug', 'release') includeFlavorDimensionAndValues( /*dimension =*/ 'color', /*values =*/ 'blue', 'pink' ) includeFlavorDimensionAndValues( /*dimension =*/ 'shape', /*values =*/ 'square' ) } } }
Kotlin
android { publishing { multipleVariants("custom") { includeBuildTypeValues("debug", "release") includeFlavorDimensionAndValues( dimension = "color", values = arrayOf("blue", "pink") ) includeFlavorDimensionAndValues( dimension = "shape", values = arrayOf("square") ) } } }
In this example, the custom component contains all the combinations of
(debug
, release
) for build type, (blue
, pink
) for the dimension color
,
and (square
) for the dimension shape
.
All flavor dimensions must be listed, even if you are only publishing one value from a dimension. This is so AGP knows which value to use for every dimension.
The following table lists the resulting publication variants and their
associated attributes. Note that, as specified in the build file, build variants
that use values of shape
other than square
are not included in the publication.
Because of this, the attribute for the product flavor dimension shape
is not
included; the consumer does not need to select a value for this dimension. For
more information on how Gradle prioritizes product flavors and dimensions when
naming build variants, see Combine multiple product flavors with flavor
dimensions.
Variant | Attributes |
---|---|
blueSquareDebug | com.android.build.api.attributes.BuildTypeAttr ="debug"
com.android.build.api.attributes.ProductFlavorAttr:color ="blue" |
blueSquareRelease |
com.android.build.api.attributes.BuildTypeAttr="release"
|
pinkSquareDebug |
com.android.build.api.attributes.BuildTypeAttr="debug"
|
pinkSquareRelease |
com.android.build.api.attributes.BuildTypeAttr="release"
|
Note that in practice, there are more variants that get published. For instance,
each of the above variants is published twice, one for compilation and one for
runtime, with different dependencies (based on whether the declared dependencies
use implementation or api), and with a different value for attribute
org.gradle.Usage
. However, the artifacts (AAR file) for these two variants are
the same.
For more information, see the
publishing
API documentation.