| | |
| | |
| | |
| |
|
| | import android.databinding.tool.ext.capitalizeUS |
| | import de.undercouch.gradle.tasks.download.Download |
| |
|
| | plugins { |
| | id("com.android.application") |
| | id("org.jetbrains.kotlin.android") |
| | id("de.undercouch.download") version "5.5.0" |
| | id("kotlin-parcelize") |
| | kotlin("plugin.serialization") version "1.9.22" |
| | id("androidx.navigation.safeargs.kotlin") |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toInt() |
| | val abiFilter = listOf("arm64-v8a", "x86_64") |
| |
|
| | val downloadedJniLibsPath = "${buildDir}/downloadedJniLibs" |
| |
|
| | @Suppress("UnstableApiUsage") |
| | android { |
| | namespace = "org.citra.citra_emu" |
| |
|
| | compileSdkVersion = "android-34" |
| | ndkVersion = "26.1.10909125" |
| |
|
| | compileOptions { |
| | sourceCompatibility = JavaVersion.VERSION_17 |
| | targetCompatibility = JavaVersion.VERSION_17 |
| | } |
| |
|
| | kotlinOptions { |
| | jvmTarget = "17" |
| | } |
| |
|
| | androidResources { |
| | generateLocaleConfig = true |
| | } |
| |
|
| | packaging { |
| | |
| | jniLibs.useLegacyPackaging = true |
| | } |
| |
|
| | buildFeatures { |
| | viewBinding = true |
| | } |
| |
|
| | lint { |
| | |
| | |
| | abortOnError = false |
| | } |
| |
|
| | defaultConfig { |
| | |
| | applicationId = "org.citra.citra_emu" |
| | minSdk = 28 |
| | targetSdk = 34 |
| | versionCode = autoVersion |
| | versionName = getGitVersion() |
| |
|
| | ndk { |
| | |
| | abiFilters += abiFilter |
| | } |
| |
|
| | externalNativeBuild { |
| | cmake { |
| | arguments( |
| | "-DENABLE_QT=0", |
| | "-DENABLE_SDL2=0", |
| | "-DANDROID_ARM_NEON=true" |
| | ) |
| | } |
| | } |
| |
|
| | buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"") |
| | buildConfigField("String", "BRANCH", "\"${getBranch()}\"") |
| | } |
| |
|
| | val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE") |
| | if (keystoreFile != null) { |
| | signingConfigs { |
| | create("release") { |
| | storeFile = file(keystoreFile) |
| | storePassword = System.getenv("ANDROID_KEYSTORE_PASS") |
| | keyAlias = System.getenv("ANDROID_KEY_ALIAS") |
| | keyPassword = System.getenv("ANDROID_KEYSTORE_PASS") |
| | } |
| | } |
| | } |
| |
|
| | |
| | buildTypes { |
| | |
| | release { |
| | signingConfig = if (keystoreFile != null) { |
| | signingConfigs.getByName("release") |
| | } else { |
| | signingConfigs.getByName("debug") |
| | } |
| | isMinifyEnabled = true |
| | isShrinkResources = true |
| | proguardFiles( |
| | getDefaultProguardFile("proguard-android.txt"), |
| | "proguard-rules.pro" |
| | ) |
| | } |
| |
|
| | |
| | |
| | register("relWithDebInfo") { |
| | initWith(getByName("release")) |
| | applicationIdSuffix = ".debug" |
| | versionNameSuffix = "-debug" |
| | signingConfig = signingConfigs.getByName("debug") |
| | isMinifyEnabled = true |
| | isShrinkResources = true |
| | isDebuggable = true |
| | isJniDebuggable = true |
| | proguardFiles( |
| | getDefaultProguardFile("proguard-android.txt"), |
| | "proguard-rules.pro" |
| | ) |
| | isDefault = true |
| | } |
| |
|
| | |
| | |
| | debug { |
| | |
| | applicationIdSuffix = ".debug" |
| | versionNameSuffix = "-debug" |
| | isDebuggable = true |
| | isJniDebuggable = true |
| | } |
| | } |
| |
|
| | flavorDimensions.add("version") |
| | productFlavors { |
| | create("canary") { |
| | dimension = "version" |
| | applicationIdSuffix = ".canary" |
| | } |
| |
|
| | create("nightly") { |
| | dimension = "version" |
| | } |
| | } |
| |
|
| | externalNativeBuild { |
| | cmake { |
| | version = "3.22.1" |
| | path = file("../../../CMakeLists.txt") |
| | } |
| | } |
| |
|
| | sourceSets { |
| | named("main") { |
| | |
| | jniLibs.srcDir(downloadedJniLibsPath) |
| | } |
| | } |
| | } |
| |
|
| | dependencies { |
| | implementation("androidx.recyclerview:recyclerview:1.3.2") |
| | implementation("androidx.activity:activity-ktx:1.8.2") |
| | implementation("androidx.fragment:fragment-ktx:1.6.2") |
| | implementation("androidx.appcompat:appcompat:1.6.1") |
| | implementation("androidx.documentfile:documentfile:1.0.1") |
| | implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") |
| | implementation("androidx.slidingpanelayout:slidingpanelayout:1.2.0") |
| | implementation("com.google.android.material:material:1.9.0") |
| | implementation("androidx.core:core-splashscreen:1.0.1") |
| | implementation("androidx.work:work-runtime:2.9.0") |
| | implementation("org.ini4j:ini4j:0.5.4") |
| | implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") |
| | implementation("androidx.navigation:navigation-fragment-ktx:2.7.6") |
| | implementation("androidx.navigation:navigation-ui-ktx:2.7.6") |
| | implementation("info.debatty:java-string-similarity:2.0.0") |
| | implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2") |
| | implementation("androidx.preference:preference-ktx:1.2.1") |
| | implementation("io.coil-kt:coil:2.5.0") |
| | } |
| |
|
| | |
| | val downloadVulkanValidationLayers = tasks.register<Download>("downloadVulkanValidationLayers") { |
| | src("https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/sdk-1.3.261.1/android-binaries-sdk-1.3.261.1-android.zip") |
| | dest(file("${buildDir}/tmp/Vulkan-ValidationLayers.zip")) |
| | onlyIfModified(true) |
| | } |
| |
|
| | |
| | val unzipVulkanValidationLayers = tasks.register<Copy>("unzipVulkanValidationLayers") { |
| | dependsOn(downloadVulkanValidationLayers) |
| | from(zipTree(downloadVulkanValidationLayers.get().dest)) { |
| | |
| | eachFile { |
| | relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) |
| | } |
| | includeEmptyDirs = false |
| | } |
| | into(downloadedJniLibsPath) |
| | } |
| |
|
| | tasks.named("preBuild") { |
| | dependsOn(unzipVulkanValidationLayers) |
| | } |
| |
|
| | fun getGitVersion(): String { |
| | var versionName = "0.0" |
| |
|
| | try { |
| | versionName = ProcessBuilder("git", "describe", "--always", "--long") |
| | .directory(project.rootDir) |
| | .redirectOutput(ProcessBuilder.Redirect.PIPE) |
| | .redirectError(ProcessBuilder.Redirect.PIPE) |
| | .start().inputStream.bufferedReader().use { it.readText() } |
| | .trim() |
| | .replace(Regex("(-0)?-[^-]+$"), "") |
| | } catch (e: Exception) { |
| | logger.error("Cannot find git, defaulting to dummy version number") |
| | } |
| |
|
| | if (System.getenv("GITHUB_ACTIONS") != null) { |
| | val gitTag = System.getenv("GIT_TAG_NAME") |
| | versionName = gitTag ?: versionName |
| | } |
| |
|
| | return versionName |
| | } |
| |
|
| | fun getGitHash(): String = |
| | runGitCommand(ProcessBuilder("git", "rev-parse", "--short", "HEAD")) ?: "dummy-hash" |
| |
|
| | fun getBranch(): String = |
| | runGitCommand(ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")) ?: "dummy-branch" |
| |
|
| | fun runGitCommand(command: ProcessBuilder) : String? { |
| | try { |
| | command.directory(project.rootDir) |
| | val process = command.start() |
| | val inputStream = process.inputStream |
| | val errorStream = process.errorStream |
| | process.waitFor() |
| |
|
| | return if (process.exitValue() == 0) { |
| | inputStream.bufferedReader() |
| | .use { it.readText().trim() } |
| | } else { |
| | val errorMessage = errorStream.bufferedReader().use { it.readText().trim() } |
| | logger.error("Error running git command: $errorMessage") |
| | return null |
| | } |
| | } catch (e: Exception) { |
| | logger.error("$e: Cannot find git") |
| | return null |
| | } |
| | } |
| |
|
| | android.applicationVariants.configureEach { |
| | val variant = this |
| | val capitalizedName = variant.name.capitalizeUS() |
| |
|
| | val copyTask = tasks.register("copyBundle${capitalizedName}") { |
| | doLast { |
| | project.copy { |
| | from(variant.outputs.first().outputFile.parentFile) |
| | include("*.apk") |
| | into(layout.buildDirectory.dir("bundle")) |
| | } |
| | project.copy { |
| | from(layout.buildDirectory.dir("outputs/bundle/${variant.name}")) |
| | include("*.aab") |
| | into(layout.buildDirectory.dir("bundle")) |
| | } |
| | } |
| | } |
| | tasks.named("bundle${capitalizedName}").configure { finalizedBy(copyTask) } |
| | } |
| |
|