Overview
Wire Android uses two primary build types —debug and release — combined with six product flavors to produce targeted build variants. Additional specialized build types (compat, compatrelease, benchmark) exist for compatibility and performance testing.
Build types and flavors are defined in buildSrc/src/main/kotlin/BuildTypes.kt and flavor/ProductFlavors.kt, with the Gradle configuration applied via buildSrc/src/main/kotlin/scripts/variants.gradle.kts.
Build Types
debug
Non-minified, debuggable build. Includes extra tooling (LeakCanary), adds
.debug suffix to the application ID, and runs slower due to the lack of minification. Suitable for development and profiling.release
Minified and non-debuggable. Runs ProGuard/R8 shrinking and obfuscation. This is the build type used for Play Store and public distribution.
compat
Initialized from
release with minification enabled. Uses its own keystore (compat). Dependency fallback points to release. Used for backward-compatible distribution.compatrelease
Initialized from
release, also minified and non-debuggable. The primary build type for Play Store production releases (Prod and F-Droid flavors). Has its own keystore configuration.benchmark
Initialized from
release and minified, but signed with the debug keystore. Dependency fallback points to release. Used exclusively for Macrobenchmark performance profiling.debug vs release at a glance
| Property | debug | release |
|---|---|---|
isMinifyEnabled | false | true |
isDebuggable | true | false |
| Application ID suffix | .debug appended | No suffix |
| ProGuard/R8 | Not applied | proguard-android-optimize.txt + proguard-rules.pro |
| LeakCanary | Included (debugImplementation) | Excluded |
| Compose UI tooling | Included (debugImplementation) | Excluded |
| Signing | Debug keystore (when signing enabled) | Release keystore |
Debug builds run slower because R8 code shrinking and optimization are disabled. Use
release or benchmark builds when measuring performance.Product Flavors
All six flavors share a singledefault dimension. Each flavor is defined in buildSrc/src/main/kotlin/flavor/ProductFlavors.kt and configured via app/default.json.
| Flavor | App Name | Application ID | Icon Color | Backend | Logging | Analytics |
|---|---|---|---|---|---|---|
dev | Wire Dev | com.waz.zclient.dev | Red | Wire Staging (anta) | Enabled | Disabled |
staging | Wire Staging | com.waz.zclient.dev | Orange | Wire Staging | Enabled | Enabled |
internal | Wire Internal | com.wire.internal | Green | Wire Prod | Enabled | Enabled |
beta | Wire Beta | com.wire.android.internal | Blue | Wire Prod | Enabled | Enabled |
prod | Wire | com.wire | White | Wire Prod | Disabled | Enabled |
fdroid | Wire | com.wire | White | Wire Prod | Disabled | Disabled |
Non-free vs FOSS source sets
Thefdroid flavor uses separate source sets to exclude closed-source dependencies:
- Non-free flavors (
prod,internal,staging,beta,dev): include Firebase FCM, Google Play Services location, and Datadog crash reporting. - FOSS flavor (
fdroid): usessrc/foss/kotlinandsrc/prod/kotlinsource sets; Firebase and Google Play Services dependencies are excluded.
Default flavor and build type resolution
The build variant resolved by Gradle is controlled by environment variables. The defaults when no environment variable is set aredev flavor and debug build type.
Flavor + Build Type Combinations
Gradle task names follow the patternassemble<Flavor><BuildType> (capitalized). Common combinations:
Signing Configuration
Signing is controlled by theENABLE_SIGNING environment variable. When ENABLE_SIGNING=TRUE, each build type reads its keystore from environment variables:
| Build type | Keystore env vars |
|---|---|
debug | KEYSTORE_FILE_PATH_DEBUG, KEYSTOREPWD_DEBUG, KEYSTORE_KEY_NAME_DEBUG, KEYPWD_DEBUG |
release | KEYSTORE_FILE_PATH_RELEASE, KEYSTOREPWD_RELEASE, KEYSTORE_KEY_NAME_RELEASE, KEYPWD_RELEASE |
compat | KEYSTORE_FILE_PATH_COMPAT, KEYSTOREPWD_COMPAT, KEYSTORE_KEY_NAME_COMPAT, KEYPWD_COMPAT |
compatrelease | KEYSTORE_FILE_PATH_COMPAT_RELEASE, KEYSTOREPWD_COMPAT_RELEASE, KEYSTORE_KEY_NAME_COMPAT_RELEASE, KEYPWD_COMPAT_RELEASE |
benchmark | Reuses debug keystore env vars |
debug signing is used as a fallback for release builds.
ProGuard / R8 Rules
All minified build types apply two rule files:app/proguard-rules.pro preserve classes that are accessed reflectively or from native code:
core/media, features/meetings) also has its own proguard-rules.pro. R8 merges all rules at build time.
Baseline Profile
The fileapp/src/main/baseline-prof.txt contains a precompiled baseline profile used by the Android runtime to AOT-compile critical code paths at install time. This reduces startup latency and improves initial frame rendering for release builds.
The profile is compiled from real user interaction traces and lists hot classes and methods in a compact textual format. The androidx.profileinstaller library (added as a dependency in app/build.gradle.kts) installs the profile on devices running Android 9+.
benchmark build type:
SBOM Generation
The project produces a CycloneDX Software Bill of Materials (SBOM) in JSON format, listing all runtime dependencies and their licenses. The SBOM task is defined insbom.gradle.kts and wired to the cyclonedxBom task from the CycloneDX Gradle plugin:
build.gradle.kts:
generateSbom automatically and uploads the output as a 30-day retention artifact named sbom-<Flavor>-<Variant>.
The SBOM step is skipped for Dependabot-triggered builds (
github.actor != 'dependabot[bot]') and is set to continue-on-error: true so a generation failure does not block the release.