Tamed’s build system is driven by the Gradle wrapper and a Kotlin DSL build script (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/calmerism/Tamed/llms.txt
Use this file to discover all available pages before exploring further.
app/build.gradle.kts). All dependency versions are locked via a Version Catalog (libs.versions.toml), which means a freshly cloned repository produces a deterministic build without any manual dependency management. This page walks you through every step from prerequisites to producing a signed APK.
Prerequisites
The following tools must be installed and available on yourPATH before opening the project.
| Tool | Version | Notes |
|---|---|---|
| Android Studio | Ladybug 2024.2.1+ | Official IDE; earlier versions may not support compileSdk 37 |
| JDK | 17 | Amazon Corretto or Azul Zulu recommended for deterministic builds |
| Android SDK | API 34+ (Upside Down Cake) | Target SDK is 36; compile SDK is 37 |
| Kotlin | 2.0 | Configured via Gradle Version Catalog — no manual install needed |
| Git | 2.40+ | Required for version control and submodule handling |
The JVM toolchain is pinned to JVM 21 inside
app/build.gradle.kts via kotlin { jvmToolchain(21) }, so the compiler output targets JVM 21 class files. Your local JDK only needs to be 17 or newer to run Gradle itself.Clone and Open
Open in Android Studio
Launch Android Studio and choose File → Open, then select the
Tamed folder. Do not use Import Project — opening the folder directly preserves the Gradle wrapper configuration.Wait for Gradle sync
Android Studio automatically triggers a Gradle sync on first open. This downloads all dependencies declared in
libs.versions.toml, including Media3, Hilt, Compose, Ktor, Room, and all multi-module project dependencies (:innertube, :kugou, :lrclib, etc.). Sync time varies by connection speed; expect 3–8 minutes on a fresh machine.local.properties Reference
Theapp/build.gradle.kts reads local.properties at configuration time and injects values into BuildConfig fields. All keys are optional — the build will succeed without them, but the corresponding features will be disabled or degraded.
Build Commands
Use the Gradle wrapper (./gradlew on macOS/Linux, gradlew.bat on Windows) for all build operations. Do not rely on a system-wide Gradle installation — only the wrapper version is tested against this codebase.
| Gradle Task | Output | Purpose |
|---|---|---|
./gradlew assembleDebug | app/build/outputs/apk/*/debug/app-*-debug.apk | Local testing and feature development |
./gradlew assembleRelease | app/build/outputs/apk/*/release/app-*-release.apk | All ABI flavors, R8-optimized |
./gradlew :app:assembleArm64Release | app/build/outputs/apk/arm64/release/app-arm64-release.apk | arm64-v8a only |
./gradlew buildReleaseApk | release/Tamed.apk | Universal release APK renamed to Tamed.apk in release/ |
./gradlew bundleRelease | app/build/outputs/bundle/*/release/app-*-release.aab | Play Store distribution bundle |
./gradlew clean | — | Clears the build cache; run before re-syncing after dependency changes |
ABI Product Flavors
The build defines two ABI flavors in theabi flavor dimension:
arm64
Packages only
arm64-v8a native libraries. This produces the smallest APK and is the flavor used for the official GitHub release binary (Tamed.apk). Use assembleArm64Release to build it.universal
Packages
armeabi-v7a, arm64-v8a, x86, and x86_64 native libraries. Use this flavor when distributing to emulators or 32-bit devices. Use assembleUniversalRelease or buildReleaseApk (which renames the output to Tamed.apk in the release/ folder).Release Signing
The signing configuration inapp/build.gradle.kts resolves at configuration time using the following priority order:
RELEASE_STORE_FILEpath fromlocal.propertiesor environment variable- If that file does not exist, falls back to
~/.android/debug.keystoreautomatically
password: android, alias: androiddebugkey) so a release build can be signed without any manual configuration. This means assembleRelease works out of the box on any developer machine.
Gradle Performance Settings
The committedgradle.properties already includes optimized JVM settings for building Tamed on typical developer hardware:
ksp.incremental=false) to avoid stale code generation issues with Room and Hilt.
Troubleshooting
Heap memory: GC overhead limit exceeded
Heap memory: GC overhead limit exceeded
If Gradle exits with an out-of-memory error during compilation, the Gradle daemon needs more heap. Add or update the following line in your local The committed value is already 6 GB (
gradle.properties:-Xmx6144M), but on machines with less RAM you may need to reduce it while also raising the system-level limit.Compose compiler: version mismatch error
Compose compiler: version mismatch error
If the build fails with a message about the Compose compiler extension version, verify that the
compose.compiler plugin version in libs.versions.toml is compatible with Kotlin 2.0. Tamed uses the standalone alias(libs.plugins.compose.compiler) plugin rather than inline configuration, so the version is managed entirely through the catalog.Gradle sync failures or dependency resolution errors
Gradle sync failures or dependency resolution errors
Run Re-run the sync after a brief wait if the JitPack CDN is slow.
./gradlew clean to clear stale build outputs, then trigger a re-sync from Android Studio via File → Sync Project with Gradle Files. If JitPack dependencies time out, the committed gradle.properties already extends connection and socket timeouts to 180 seconds:Room schema export errors
Room schema export errors
Room is configured to export schemas via the KSP argument
room.schemaLocation=$projectDir/schemas. If you see an error about schema export during compilation, ensure the app/schemas/ directory exists and is writable. The exported JSON files should be committed alongside code changes that modify the database schema.