Files
amnezia-client/client/android/build.gradle.kts
T

202 lines
7.1 KiB
Kotlin
Raw Normal View History

2023-12-05 23:53:49 +03:00
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
2023-11-14 22:58:47 +03:00
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
2024-06-18 20:46:21 +03:00
alias(libs.plugins.kotlin.serialization)
2023-11-14 22:58:47 +03:00
id("property-delegate")
}
kotlin {
jvmToolchain(17)
}
// get values from gradle or local properties
val qtTargetSdkVersion: String by gradleProperties
val qtTargetAbiList: String by gradleProperties
2023-12-05 23:53:49 +03:00
val outputBaseName: String by gradleProperties
2023-11-14 22:58:47 +03:00
android {
namespace = "org.amnezia.vpn"
buildFeatures {
2024-09-17 20:44:19 +03:00
buildConfig = true
2023-11-14 22:58:47 +03:00
viewBinding = true
}
androidResources {
// don't compress Qt binary resources file
noCompress += "rcc"
}
packaging {
// compress .so binary libraries
jniLibs.useLegacyPackaging = true
}
2026-05-14 13:25:08 +03:00
val abiList = qtTargetAbiList.split(",")
2023-11-14 22:58:47 +03:00
defaultConfig {
applicationId = "org.amnezia.vpn"
targetSdk = qtTargetSdkVersion.toInt()
// keeps language resources for only the locales specified below
resourceConfigurations += listOf("en", "ru", "b+zh+Hans")
2026-05-14 13:25:08 +03:00
// ndk.abiFilters is only used for single-ABI builds; multi-ABI uses splits below
if (abiList.size == 1) {
ndk.abiFilters += abiList
}
2023-11-14 22:58:47 +03:00
}
signingConfigs {
register("release") {
2026-06-01 22:53:31 +03:00
storeFile = providers.environmentVariable("QT_ANDROID_KEYSTORE_PATH").orNull?.let { file(it) }
storePassword = providers.environmentVariable("QT_ANDROID_KEYSTORE_STORE_PASS").orNull
keyAlias = providers.environmentVariable("QT_ANDROID_KEYSTORE_ALIAS").orNull
keyPassword = providers.environmentVariable("QT_ANDROID_KEYSTORE_STORE_PASS").orNull
}
}
buildTypes {
release {
// exclude coroutine debug resource from release build
packaging {
resources.excludes += "DebugProbesKt.bin"
}
signingConfig = signingConfigs["release"]
}
create("fdroid") {
initWith(getByName("release"))
signingConfig = null
matchingFallbacks += "release"
}
}
flavorDimensions += "billing"
productFlavors {
create("oss") {
dimension = "billing"
2026-06-02 15:55:20 +03:00
buildConfigField("boolean", "IS_PLAY_BUILD", "false")
}
create("play") {
dimension = "billing"
2026-06-02 15:55:20 +03:00
buildConfigField("boolean", "IS_PLAY_BUILD", "true")
}
}
2023-11-14 22:58:47 +03:00
sourceSets {
getByName("main") {
manifest.srcFile("AndroidManifest.xml")
java.setSrcDirs(listOf("src"))
res.setSrcDirs(listOf("res"))
// androyddeployqt creates the folders below
2023-11-14 22:58:47 +03:00
assets.setSrcDirs(listOf("assets"))
jniLibs.setSrcDirs(listOf("libs"))
}
getByName("oss") {
java.setSrcDirs(listOf("oss"))
}
getByName("play") {
java.setSrcDirs(listOf("play"))
}
2023-11-14 22:58:47 +03:00
}
splits {
abi {
2026-05-14 13:25:08 +03:00
// splits only make sense for multi-ABI builds; single-ABI uses ndk.abiFilters
isEnable = abiList.size > 1
reset()
2026-05-14 13:25:08 +03:00
include(*abiList.toTypedArray())
isUniversalApk = false
}
}
// fix for Qt Creator to allow deploying the application to a device
// to enable this fix, add the line outputBaseName=android-build to local.properties
if (outputBaseName.isNotEmpty()) {
applicationVariants.all {
outputs.map { it as BaseVariantOutputImpl }
.forEach { output ->
if (output.outputFileName.endsWith(".apk")) {
output.outputFileName = "$outputBaseName-${buildType.name}.apk"
}
}
2026-06-02 15:55:20 +03:00
}
}
// androiddeployqt expects:
// APK: build/outputs/apk/{base}-{buildType}[-unsigned].apk (no flavor subdir)
// AAB: build/outputs/bundle/{buildType}/{base}-{buildType}.aab (no flavor subdir)
// where {base} = outputBaseName (set by Qt Creator) or "android-build" (CI fallback).
// Release APK gets -unsigned suffix (Qt cmake signs it); debug does not.
applicationVariants.all {
val flavorName = productFlavors.firstOrNull()?.name ?: ""
val buildTypeName = buildType.name
// Copy play flavor only when invoked explicitly (android_play_apk/aab cmake targets pass -DexplicitRun=1).
// This prevents play from overwriting oss in the flat output dir during normal Qt Creator builds.
val isExplicitRun = project.findProperty("explicitRun") == "1"
val shouldCopy = flavorName == "oss" || (flavorName == "play" && isExplicitRun)
if (shouldCopy) {
val base = outputBaseName.ifEmpty { "android-build" }
val unsignedSuffix = if (buildTypeName == "release") "-unsigned" else ""
// APK: copy to outputs/apk/{base}-{buildType}[-unsigned].apk
packageApplicationProvider.configure {
doLast {
val srcDir = layout.buildDirectory.dir("outputs/apk/$flavorName/$buildTypeName").get().asFile
val dstDir = layout.buildDirectory.dir("outputs/apk").get().asFile
dstDir.mkdirs()
srcDir.listFiles()?.filter { it.name.endsWith(".apk") }?.forEach { apk ->
apk.copyTo(File(dstDir, "$base-$buildTypeName$unsignedSuffix.apk"), overwrite = true)
}
}
}
2026-06-01 23:36:53 +03:00
2026-06-02 15:55:20 +03:00
// AAB: copy to outputs/bundle/{buildType}/{base}-{buildType}.aab
tasks.named("bundle${name.replaceFirstChar { it.uppercase() }}") {
doLast {
val variantBundleDir = "${flavorName}${buildTypeName.replaceFirstChar { it.uppercase() }}"
val srcDir = layout.buildDirectory.dir("outputs/bundle/$variantBundleDir").get().asFile
val dstDir = layout.buildDirectory.dir("outputs/bundle/$buildTypeName").get().asFile
dstDir.mkdirs()
srcDir.listFiles()?.filter { it.name.endsWith(".aab") }?.forEach { aab ->
aab.copyTo(File(dstDir, "$base-$buildTypeName.aab"), overwrite = true)
2026-06-01 23:36:53 +03:00
}
}
}
2023-12-05 23:53:49 +03:00
}
}
2023-11-21 22:48:52 +03:00
lint {
disable += "InvalidFragmentVersionForActivityResult"
}
2023-11-14 22:58:47 +03:00
}
dependencies {
implementation(project(":qt"))
2023-11-16 15:15:02 +03:00
implementation(project(":utils"))
2023-11-23 15:45:55 +03:00
implementation(project(":protocolApi"))
2023-11-23 16:45:15 +03:00
implementation(project(":wireguard"))
2023-11-26 13:07:31 +03:00
implementation(project(":awg"))
2023-11-28 20:07:39 +03:00
implementation(project(":openvpn"))
2024-06-18 20:46:21 +03:00
implementation(project(":xray"))
2023-11-14 22:58:47 +03:00
implementation(libs.androidx.core)
2023-11-21 22:48:52 +03:00
implementation(libs.androidx.activity)
2024-09-09 14:36:33 +03:00
implementation(libs.androidx.fragment)
2023-11-14 22:58:47 +03:00
implementation(libs.kotlinx.coroutines)
2024-06-18 20:46:21 +03:00
implementation(libs.kotlinx.serialization.protobuf)
2023-11-14 22:58:47 +03:00
implementation(libs.bundles.androidx.camera)
implementation(libs.google.mlkit)
2024-03-04 18:08:55 +03:00
implementation(libs.androidx.datastore)
2024-09-09 14:36:33 +03:00
implementation(libs.androidx.biometric)
playImplementation(project(":billing"))
2023-11-14 22:58:47 +03:00
}
fun DependencyHandler.playImplementation(dependency: Any): Dependency? =
add("playImplementation", dependency)