mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-21 02:01:03 +07:00
198 lines
6.7 KiB
Kotlin
198 lines
6.7 KiB
Kotlin
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
|
|
|
plugins {
|
|
alias(libs.plugins.android.application)
|
|
alias(libs.plugins.kotlin.android)
|
|
alias(libs.plugins.kotlin.serialization)
|
|
id("property-delegate")
|
|
}
|
|
|
|
kotlin {
|
|
jvmToolchain(17)
|
|
}
|
|
|
|
// get values from gradle or local properties
|
|
val qtTargetSdkVersion: String by gradleProperties
|
|
val qtTargetAbiList: String by gradleProperties
|
|
val outputBaseName: String by gradleProperties
|
|
|
|
android {
|
|
namespace = "org.amnezia.vpn"
|
|
|
|
buildFeatures {
|
|
buildConfig = true
|
|
viewBinding = true
|
|
}
|
|
|
|
androidResources {
|
|
// don't compress Qt binary resources file
|
|
noCompress += "rcc"
|
|
}
|
|
|
|
packaging {
|
|
// compress .so binary libraries
|
|
jniLibs.useLegacyPackaging = true
|
|
}
|
|
|
|
val abiList = qtTargetAbiList.split(",")
|
|
|
|
defaultConfig {
|
|
applicationId = "org.amnezia.vpn"
|
|
targetSdk = qtTargetSdkVersion.toInt()
|
|
|
|
// keeps language resources for only the locales specified below
|
|
resourceConfigurations += listOf("en", "ru", "b+zh+Hans")
|
|
// ndk.abiFilters is only used for single-ABI builds; multi-ABI uses splits below
|
|
if (abiList.size == 1) {
|
|
ndk.abiFilters += abiList
|
|
}
|
|
}
|
|
|
|
signingConfigs {
|
|
register("release") {
|
|
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"
|
|
buildConfigField("boolean", "IS_PLAY_BUILD", "false")
|
|
}
|
|
create("play") {
|
|
dimension = "billing"
|
|
buildConfigField("boolean", "IS_PLAY_BUILD", "true")
|
|
}
|
|
}
|
|
|
|
sourceSets {
|
|
getByName("main") {
|
|
manifest.srcFile("AndroidManifest.xml")
|
|
java.setSrcDirs(listOf("src"))
|
|
res.setSrcDirs(listOf("res"))
|
|
// androyddeployqt creates the folders below
|
|
assets.setSrcDirs(listOf("assets"))
|
|
jniLibs.setSrcDirs(listOf("libs"))
|
|
}
|
|
|
|
getByName("oss") {
|
|
java.setSrcDirs(listOf("oss"))
|
|
}
|
|
|
|
getByName("play") {
|
|
java.setSrcDirs(listOf("play"))
|
|
}
|
|
}
|
|
|
|
splits {
|
|
abi {
|
|
// splits only make sense for multi-ABI builds; single-ABI uses ndk.abiFilters
|
|
isEnable = abiList.size > 1
|
|
reset()
|
|
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"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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.
|
|
// Copy only oss flavor to the flat output dir that androiddeployqt/Qt Creator expect.
|
|
// Play flavor is built via android_play_apk/android_play_aab cmake targets and uses
|
|
// its native Gradle output paths directly.
|
|
applicationVariants.all {
|
|
val flavorName = productFlavors.firstOrNull()?.name ?: ""
|
|
val buildTypeName = buildType.name
|
|
if (flavorName == "oss") {
|
|
val base = outputBaseName.ifEmpty { "android-build" }
|
|
val unsignedSuffix = if (buildTypeName == "release") "-unsigned" else ""
|
|
|
|
packageApplicationProvider.configure {
|
|
doLast {
|
|
val srcDir = layout.buildDirectory.dir("outputs/apk/oss/$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)
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.named("bundle${name.replaceFirstChar { it.uppercase() }}") {
|
|
doLast {
|
|
val srcDir = layout.buildDirectory.dir("outputs/bundle/ossRelease").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)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lint {
|
|
disable += "InvalidFragmentVersionForActivityResult"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation(project(":qt"))
|
|
implementation(project(":utils"))
|
|
implementation(project(":protocolApi"))
|
|
implementation(project(":wireguard"))
|
|
implementation(project(":awg"))
|
|
implementation(project(":openvpn"))
|
|
implementation(project(":xray"))
|
|
implementation(libs.androidx.core)
|
|
implementation(libs.androidx.activity)
|
|
implementation(libs.androidx.fragment)
|
|
implementation(libs.kotlinx.coroutines)
|
|
implementation(libs.kotlinx.serialization.protobuf)
|
|
implementation(libs.bundles.androidx.camera)
|
|
implementation(libs.google.mlkit)
|
|
implementation(libs.androidx.datastore)
|
|
implementation(libs.androidx.biometric)
|
|
|
|
playImplementation(project(":billing"))
|
|
}
|
|
|
|
fun DependencyHandler.playImplementation(dependency: Any): Dependency? =
|
|
add("playImplementation", dependency)
|