mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Android: Gradle updates (#6653)
* android: Migrate to Kotlin DSL Includes updates to all android dependencies/ndk (minus billing) and adds support for Kotlin, Android 13, and view binding. * android: Remove unused tests * android: Remove unused dependencies
This commit is contained in:
		
							parent
							
								
									71aea7e571
								
							
						
					
					
						commit
						c88acf7405
					
				
					 9 changed files with 241 additions and 266 deletions
				
			
		|  | @ -1,192 +0,0 @@ | |||
| apply plugin: 'com.android.application' | ||||
| 
 | ||||
| /** | ||||
|  * Use the number of seconds/10 since Jan 1 2016 as the versionCode. | ||||
|  * This lets us upload a new build at most every 10 seconds for the | ||||
|  * next 680 years. | ||||
|  */ | ||||
| def autoVersion = (int) (((new Date().getTime() / 1000) - 1451606400) / 10) | ||||
| def buildType | ||||
| def abiFilter = "arm64-v8a" //, "x86" | ||||
| 
 | ||||
| android { | ||||
|     compileSdkVersion 33 | ||||
|     ndkVersion "25.1.8937393" | ||||
| 
 | ||||
|     compileOptions { | ||||
|         sourceCompatibility JavaVersion.VERSION_1_8 | ||||
|         targetCompatibility JavaVersion.VERSION_1_8 | ||||
|     } | ||||
| 
 | ||||
|     lintOptions { | ||||
|         // This is important as it will run lint but not abort on error | ||||
|         // Lint has some overly obnoxious "errors" that should really be warnings | ||||
|         abortOnError false | ||||
| 
 | ||||
|         //Uncomment disable lines for test builds... | ||||
|         //disable 'MissingTranslation'bin | ||||
|         //disable 'ExtraTranslation' | ||||
|     } | ||||
| 
 | ||||
|     defaultConfig { | ||||
|         // TODO If this is ever modified, change application_id in strings.xml | ||||
|         applicationId "org.citra.citra_emu" | ||||
|         minSdkVersion 28 | ||||
|         targetSdkVersion 31 | ||||
|         versionCode autoVersion | ||||
|         versionName getVersion() | ||||
|         ndk.abiFilters abiFilter | ||||
|     } | ||||
| 
 | ||||
|     def keystoreFile = System.getenv('ANDROID_KEYSTORE_FILE') | ||||
|     if (keystoreFile != null) { | ||||
|         signingConfigs { | ||||
|             release { | ||||
|                 storeFile file(keystoreFile) | ||||
|                 storePassword System.getenv('ANDROID_KEYSTORE_PASS') | ||||
|                 keyAlias System.getenv('ANDROID_KEY_ALIAS') | ||||
|                 keyPassword System.getenv('ANDROID_KEYSTORE_PASS') | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     applicationVariants.all { variant -> | ||||
|         buildType = variant.buildType.name // sets the current build type | ||||
|     } | ||||
| 
 | ||||
|     // Define build types, which are orthogonal to product flavors. | ||||
|     buildTypes { | ||||
| 
 | ||||
|         // Signed by release key, allowing for upload to Play Store. | ||||
|         release { | ||||
|             signingConfig keystoreFile != null ? signingConfigs.release : signingConfigs.debug | ||||
|         } | ||||
| 
 | ||||
|         // builds a release build that doesn't need signing | ||||
|         // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. | ||||
|         relWithDebInfo { | ||||
|             initWith release | ||||
|             applicationIdSuffix ".debug" | ||||
|             versionNameSuffix '-debug' | ||||
|             signingConfig signingConfigs.debug | ||||
|             minifyEnabled false | ||||
|             testCoverageEnabled false | ||||
|             debuggable true | ||||
|             jniDebuggable true | ||||
|         } | ||||
| 
 | ||||
|         // Signed by debug key disallowing distribution on Play Store. | ||||
|         // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. | ||||
|         debug { | ||||
|             // TODO If this is ever modified, change application_id in debug/strings.xml | ||||
|             applicationIdSuffix ".debug" | ||||
|             versionNameSuffix '-debug' | ||||
|             debuggable true | ||||
|             jniDebuggable true | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     flavorDimensions "version" | ||||
|     productFlavors { | ||||
|         canary { | ||||
|             dimension "version" | ||||
|             applicationIdSuffix ".canary" | ||||
|         } | ||||
|         nightly { | ||||
|             dimension "version" | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     externalNativeBuild { | ||||
|         cmake { | ||||
|             version "3.22.1" | ||||
|             path "../../../CMakeLists.txt" | ||||
|         } | ||||
|     } | ||||
|     namespace 'org.citra.citra_emu' | ||||
| 
 | ||||
|     defaultConfig { | ||||
|         externalNativeBuild { | ||||
|             cmake { | ||||
|                 arguments "-DENABLE_QT=0", // Don't use QT | ||||
|                         "-DENABLE_SDL2=0", // Don't use SDL | ||||
|                         "-DANDROID_ARM_NEON=true" // cryptopp requires Neon to work | ||||
| 
 | ||||
|                 abiFilters abiFilter | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation "androidx.activity:activity:1.5.1" | ||||
|     implementation "androidx.fragment:fragment:1.5.5" | ||||
|     implementation 'androidx.appcompat:appcompat:1.5.1' | ||||
|     implementation 'androidx.exifinterface:exifinterface:1.3.4' | ||||
|     implementation 'androidx.cardview:cardview:1.0.0' | ||||
|     implementation 'androidx.recyclerview:recyclerview:1.2.1' | ||||
|     implementation "androidx.documentfile:documentfile:1.0.1" | ||||
|     implementation 'androidx.constraintlayout:constraintlayout:2.1.4' | ||||
|     implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1' | ||||
|     implementation 'androidx.fragment:fragment:1.5.3' | ||||
|     implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0" | ||||
|     implementation 'com.google.android.material:material:1.6.1' | ||||
|     implementation 'androidx.core:core-splashscreen:1.0.0' | ||||
|     implementation "androidx.work:work-runtime:2.8.1" | ||||
| 
 | ||||
|     // For loading huge screenshots from the disk. | ||||
|     implementation 'com.squareup.picasso:picasso:2.71828' | ||||
| 
 | ||||
|     // Allows FRP-style asynchronous operations in Android. | ||||
|     implementation 'io.reactivex:rxandroid:1.2.1' | ||||
|     implementation 'org.ini4j:ini4j:0.5.4' | ||||
|     implementation 'androidx.constraintlayout:constraintlayout:2.1.4' | ||||
|     implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' | ||||
|     implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' | ||||
| 
 | ||||
|     // Please don't upgrade the billing library as the newer version is not GPL-compatible | ||||
|     implementation 'com.android.billingclient:billing:2.0.3' | ||||
| 
 | ||||
|     // To use the androidx.test.core APIs | ||||
|     androidTestImplementation "androidx.test:core:1.5.0" | ||||
|     androidTestImplementation "androidx.test.ext:junit:1.1.5" | ||||
| } | ||||
| 
 | ||||
| def getVersion() { | ||||
|     def versionName = '0.0' | ||||
| 
 | ||||
|     try { | ||||
|         versionName = 'git describe --always --long'.execute([], project.rootDir).text | ||||
|                 .trim() | ||||
|                 .replaceAll(/(-0)?-[^-]+$/, "") | ||||
|     } catch (Exception) { | ||||
|         logger.error('Cannot find git, defaulting to dummy version number') | ||||
|     } | ||||
| 
 | ||||
|     if (System.getenv("GITHUB_ACTIONS") != null) { | ||||
|         def gitTag = System.getenv("GIT_TAG_NAME") | ||||
|         versionName = gitTag ?: versionName | ||||
|     } | ||||
| 
 | ||||
|     return versionName | ||||
| } | ||||
| 
 | ||||
| // Add task to each variant for copying output APKs to bundle directory. | ||||
| android.applicationVariants.all { variant -> | ||||
|     def capitalizedName = variant.name.capitalize() | ||||
|     def copyTask = tasks.register("copyBundle${capitalizedName}") { | ||||
|         doLast { | ||||
|             project.copy { | ||||
|                 from variant.outputs[0].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}").get().configure { finalizedBy copyTask } | ||||
| } | ||||
							
								
								
									
										203
									
								
								src/android/app/build.gradle.kts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								src/android/app/build.gradle.kts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,203 @@ | |||
| // Copyright 2023 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| import android.databinding.tool.ext.capitalizeUS | ||||
| 
 | ||||
| plugins { | ||||
|     id("com.android.application") | ||||
|     id("org.jetbrains.kotlin.android") | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Use the number of seconds/10 since Jan 1 2016 as the versionCode. | ||||
|  * This lets us upload a new build at most every 10 seconds for the | ||||
|  * next 680 years. | ||||
|  */ | ||||
| val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toInt() | ||||
| val abiFilter = listOf("arm64-v8a"/*, "x86", "x86_64"*/) | ||||
| 
 | ||||
| @Suppress("UnstableApiUsage") | ||||
| android { | ||||
|     namespace = "org.citra.citra_emu" | ||||
| 
 | ||||
|     compileSdkVersion = "android-33" | ||||
|     ndkVersion = "25.2.9519653" | ||||
| 
 | ||||
|     compileOptions { | ||||
|         sourceCompatibility = JavaVersion.VERSION_17 | ||||
|         targetCompatibility = JavaVersion.VERSION_17 | ||||
|     } | ||||
| 
 | ||||
|     kotlinOptions { | ||||
|         jvmTarget = "17" | ||||
|     } | ||||
| 
 | ||||
|     buildFeatures { | ||||
|         viewBinding = true | ||||
|     } | ||||
| 
 | ||||
|     lint { | ||||
|         // This is important as it will run lint but not abort on error | ||||
|         // Lint has some overly obnoxious "errors" that should really be warnings | ||||
|         abortOnError = false | ||||
|     } | ||||
| 
 | ||||
|     defaultConfig { | ||||
|         // TODO If this is ever modified, change application_id in strings.xml | ||||
|         applicationId = "org.citra.citra_emu" | ||||
|         minSdk = 28 | ||||
|         targetSdk = 33 | ||||
|         versionCode = autoVersion | ||||
|         versionName = getGitVersion() | ||||
| 
 | ||||
|         ndk { | ||||
|             //noinspection ChromeOsAbiSupport | ||||
|             abiFilters += abiFilter | ||||
|         } | ||||
| 
 | ||||
|         externalNativeBuild { | ||||
|             cmake { | ||||
|                 arguments( | ||||
|                     "-DENABLE_QT=0", // Don't use QT | ||||
|                     "-DENABLE_SDL2=0", // Don't use SDL | ||||
|                     "-DANDROID_ARM_NEON=true" // cryptopp requires Neon to work | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     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") | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Define build types, which are orthogonal to product flavors. | ||||
|     buildTypes { | ||||
|         // Signed by release key, allowing for upload to Play Store. | ||||
|         release { | ||||
|             signingConfig = if (keystoreFile != null) { | ||||
|                 signingConfigs.getByName("release") | ||||
|             } else { | ||||
|                 signingConfigs.getByName("debug") | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // builds a release build that doesn't need signing | ||||
|         // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. | ||||
|         register("relWithDebInfo") { | ||||
|             initWith(getByName("release")) | ||||
|             applicationIdSuffix = ".debug" | ||||
|             versionNameSuffix = "-debug" | ||||
|             signingConfig = signingConfigs.getByName("debug") | ||||
|             isMinifyEnabled = false | ||||
|             isDebuggable = true | ||||
|             isJniDebuggable = true | ||||
|         } | ||||
| 
 | ||||
|         // Signed by debug key disallowing distribution on Play Store. | ||||
|         // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. | ||||
|         debug { | ||||
|             // TODO If this is ever modified, change application_id in debug/strings.xml | ||||
|             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") | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation("androidx.activity:activity-ktx:1.7.2") | ||||
|     implementation("androidx.fragment:fragment-ktx:1.6.0") | ||||
|     implementation("androidx.appcompat:appcompat:1.6.1") | ||||
|     implementation("androidx.documentfile:documentfile:1.0.1") | ||||
|     implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1") | ||||
|     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.8.1") | ||||
| 
 | ||||
|     // For loading huge screenshots from the disk. | ||||
|     implementation("com.squareup.picasso:picasso:2.71828") | ||||
| 
 | ||||
|     // Allows FRP-style asynchronous operations in Android. | ||||
|     implementation("io.reactivex:rxandroid:1.2.1") | ||||
| 
 | ||||
|     implementation("org.ini4j:ini4j:0.5.4") | ||||
|     implementation("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0") | ||||
|     implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") | ||||
| 
 | ||||
|     // Please don't upgrade the billing library as the newer version is not GPL-compatible | ||||
|     implementation("com.android.billingclient:billing:2.0.3") | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| } | ||||
| 
 | ||||
| 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) } | ||||
| } | ||||
|  | @ -1,26 +0,0 @@ | |||
| package org.citra.citra_emu; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import androidx.test.core.app.ApplicationProvider; | ||||
| import androidx.test.ext.junit.runners.AndroidJUnit4; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| 
 | ||||
| import static org.junit.Assert.*; | ||||
| 
 | ||||
| /** | ||||
|  * Instrumented test, which will execute on an Android device. | ||||
|  * | ||||
|  * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | ||||
|  */ | ||||
| @RunWith(AndroidJUnit4.class) | ||||
| public class ExampleInstrumentedTest { | ||||
|     @Test | ||||
|     public void useAppContext() { | ||||
|         // Context of the app under test. | ||||
|         Context appContext = ApplicationProvider.getApplicationContext(); | ||||
| 
 | ||||
|         assertEquals("org.citra.citra_emu", appContext.getPackageName()); | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +1,5 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="org.citra.citra_emu"> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <uses-feature | ||||
|         android:name="android.hardware.touchscreen" | ||||
|         android:required="false"/> | ||||
|  |  | |||
|  | @ -1,17 +0,0 @@ | |||
| package org.citra.citra_emu; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import static org.junit.Assert.*; | ||||
| 
 | ||||
| /** | ||||
|  * Example local unit test, which will execute on the development machine (host). | ||||
|  * | ||||
|  * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | ||||
|  */ | ||||
| public class ExampleUnitTest { | ||||
|     @Test | ||||
|     public void addition_isCorrect() { | ||||
|         assertEquals(4, 2 + 2); | ||||
|     } | ||||
| } | ||||
|  | @ -1,28 +0,0 @@ | |||
| // Top-level build file where you can add configuration options common to all sub-projects/modules. | ||||
| 
 | ||||
| buildscript { | ||||
| 
 | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|         jcenter() | ||||
|     } | ||||
|     dependencies { | ||||
|         classpath 'com.android.tools.build:gradle:8.0.2' | ||||
| 
 | ||||
|         // NOTE: Do not place your application dependencies here; they belong | ||||
|         // in the individual module build.gradle files | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| allprojects { | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|         jcenter() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| task clean(type: Delete) { | ||||
|     delete rootProject.buildDir | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/android/build.gradle.kts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/android/build.gradle.kts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| // Copyright 2023 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| // Top-level build file where you can add configuration options common to all sub-projects/modules. | ||||
| plugins { | ||||
|     id("com.android.application") version "8.0.2" apply false | ||||
|     id("com.android.library") version "8.0.2" apply false | ||||
|     id("org.jetbrains.kotlin.android") version "1.8.21" apply false | ||||
| } | ||||
| 
 | ||||
| tasks.register("clean").configure { | ||||
|     delete(rootProject.buildDir) | ||||
| } | ||||
|  | @ -1 +0,0 @@ | |||
| include ':app' | ||||
							
								
								
									
										23
									
								
								src/android/settings.gradle.kts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/android/settings.gradle.kts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| // Copyright 2023 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| pluginManagement { | ||||
|     repositories { | ||||
|         gradlePluginPortal() | ||||
|         google() | ||||
|         mavenCentral() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @Suppress("UnstableApiUsage") | ||||
| dependencyResolutionManagement { | ||||
|     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|         jcenter() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| include(":app") | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue