summaryrefslogtreecommitdiff
path: root/src/android/app/build.gradle.kts
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/build.gradle.kts')
-rw-r--r--src/android/app/build.gradle.kts270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
new file mode 100644
index 000000000..bab4f4d0f
--- /dev/null
+++ b/src/android/app/build.gradle.kts
@@ -0,0 +1,270 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4import android.annotation.SuppressLint
5import kotlin.collections.setOf
6import org.jetbrains.kotlin.konan.properties.Properties
7import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
8
9plugins {
10 id("com.android.application")
11 id("org.jetbrains.kotlin.android")
12 id("kotlin-parcelize")
13 kotlin("plugin.serialization") version "1.8.21"
14 id("androidx.navigation.safeargs.kotlin")
15 id("org.jlleitschuh.gradle.ktlint") version "11.4.0"
16}
17
18/**
19 * Use the number of seconds/10 since Jan 1 2016 as the versionCode.
20 * This lets us upload a new build at most every 10 seconds for the
21 * next 680 years.
22 */
23val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toInt()
24
25@Suppress("UnstableApiUsage")
26android {
27 namespace = "org.yuzu.yuzu_emu"
28
29 compileSdkVersion = "android-33"
30 ndkVersion = "25.2.9519653"
31
32 buildFeatures {
33 viewBinding = true
34 }
35
36 compileOptions {
37 sourceCompatibility = JavaVersion.VERSION_17
38 targetCompatibility = JavaVersion.VERSION_17
39 }
40
41 kotlinOptions {
42 jvmTarget = "17"
43 }
44
45 packaging {
46 // This is necessary for libadrenotools custom driver loading
47 jniLibs.useLegacyPackaging = true
48 }
49
50 defaultConfig {
51 // TODO If this is ever modified, change application_id in strings.xml
52 applicationId = "org.yuzu.yuzu_emu"
53 minSdk = 30
54 targetSdk = 33
55 versionName = getGitVersion()
56
57 // If you want to use autoVersion for the versionCode, create a property in local.properties
58 // named "autoVersioned" and set it to "true"
59 val properties = Properties()
60 val versionProperty = try {
61 properties.load(project.rootProject.file("local.properties").inputStream())
62 properties.getProperty("autoVersioned") ?: ""
63 } catch (e: Exception) { "" }
64
65 versionCode = if (versionProperty == "true") {
66 autoVersion
67 } else {
68 1
69 }
70
71 ndk {
72 @SuppressLint("ChromeOsAbiSupport")
73 abiFilters += listOf("arm64-v8a")
74 }
75
76 buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"")
77 buildConfigField("String", "BRANCH", "\"${getBranch()}\"")
78 }
79
80 // Define build types, which are orthogonal to product flavors.
81 buildTypes {
82
83 // Signed by release key, allowing for upload to Play Store.
84 release {
85 resValue("string", "app_name_suffixed", "yuzu")
86 signingConfig = signingConfigs.getByName("debug")
87 isMinifyEnabled = true
88 isDebuggable = false
89 proguardFiles(
90 getDefaultProguardFile("proguard-android.txt"),
91 "proguard-rules.pro"
92 )
93 }
94
95 // builds a release build that doesn't need signing
96 // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
97 register("relWithDebInfo") {
98 resValue("string", "app_name_suffixed", "yuzu Debug Release")
99 signingConfig = signingConfigs.getByName("debug")
100 isMinifyEnabled = true
101 isDebuggable = true
102 proguardFiles(
103 getDefaultProguardFile("proguard-android.txt"),
104 "proguard-rules.pro"
105 )
106 versionNameSuffix = "-relWithDebInfo"
107 applicationIdSuffix = ".relWithDebInfo"
108 isJniDebuggable = true
109 }
110
111 // Signed by debug key disallowing distribution on Play Store.
112 // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
113 debug {
114 resValue("string", "app_name_suffixed", "yuzu Debug")
115 isDebuggable = true
116 isJniDebuggable = true
117 versionNameSuffix = "-debug"
118 applicationIdSuffix = ".debug"
119 }
120 }
121
122 flavorDimensions.add("version")
123 productFlavors {
124 create("mainline") {
125 dimension = "version"
126 buildConfigField("Boolean", "PREMIUM", "false")
127 }
128
129 create("ea") {
130 dimension = "version"
131 buildConfigField("Boolean", "PREMIUM", "true")
132 applicationIdSuffix = ".ea"
133 }
134 }
135
136 externalNativeBuild {
137 cmake {
138 version = "3.22.1"
139 path = file("../../../CMakeLists.txt")
140 }
141 }
142
143 defaultConfig {
144 externalNativeBuild {
145 cmake {
146 arguments(
147 "-DENABLE_QT=0", // Don't use QT
148 "-DENABLE_SDL2=0", // Don't use SDL
149 "-DENABLE_WEB_SERVICE=0", // Don't use telemetry
150 "-DBUNDLE_SPEEX=ON",
151 "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
152 "-DYUZU_USE_BUNDLED_VCPKG=ON",
153 "-DYUZU_USE_BUNDLED_FFMPEG=ON",
154 "-DYUZU_ENABLE_LTO=ON"
155 )
156
157 abiFilters("arm64-v8a", "x86_64")
158 }
159 }
160 }
161}
162
163tasks.getByPath("preBuild").dependsOn("ktlintCheck")
164
165ktlint {
166 version.set("0.47.1")
167 android.set(true)
168 ignoreFailures.set(false)
169 disabledRules.set(
170 setOf(
171 "no-wildcard-imports",
172 "package-name",
173 "import-ordering"
174 )
175 )
176 reporters {
177 reporter(ReporterType.CHECKSTYLE)
178 }
179}
180
181dependencies {
182 implementation("androidx.core:core-ktx:1.10.1")
183 implementation("androidx.appcompat:appcompat:1.6.1")
184 implementation("androidx.recyclerview:recyclerview:1.3.0")
185 implementation("androidx.constraintlayout:constraintlayout:2.1.4")
186 implementation("androidx.fragment:fragment-ktx:1.6.0")
187 implementation("androidx.documentfile:documentfile:1.0.1")
188 implementation("com.google.android.material:material:1.9.0")
189 implementation("androidx.preference:preference:1.2.0")
190 implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
191 implementation("io.coil-kt:coil:2.2.2")
192 implementation("androidx.core:core-splashscreen:1.0.1")
193 implementation("androidx.window:window:1.1.0")
194 implementation("org.ini4j:ini4j:0.5.4")
195 implementation("androidx.constraintlayout:constraintlayout:2.1.4")
196 implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
197 implementation("androidx.navigation:navigation-fragment-ktx:2.6.0")
198 implementation("androidx.navigation:navigation-ui-ktx:2.6.0")
199 implementation("info.debatty:java-string-similarity:2.0.0")
200 implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
201}
202
203fun getGitVersion(): String {
204 var versionName = "0.0"
205
206 try {
207 versionName = ProcessBuilder("git", "describe", "--always", "--long")
208 .directory(project.rootDir)
209 .redirectOutput(ProcessBuilder.Redirect.PIPE)
210 .redirectError(ProcessBuilder.Redirect.PIPE)
211 .start().inputStream.bufferedReader().use { it.readText() }
212 .trim()
213 .replace(Regex("(-0)?-[^-]+$"), "")
214 } catch (e: Exception) {
215 logger.error("Cannot find git, defaulting to dummy version number")
216 }
217
218 if (System.getenv("GITHUB_ACTIONS") != null) {
219 val gitTag = System.getenv("GIT_TAG_NAME")
220 versionName = gitTag ?: versionName
221 }
222
223 return versionName
224}
225
226fun getGitHash(): String {
227 try {
228 val processBuilder = ProcessBuilder("git", "rev-parse", "--short", "HEAD")
229 processBuilder.directory(project.rootDir)
230 val process = processBuilder.start()
231 val inputStream = process.inputStream
232 val errorStream = process.errorStream
233 process.waitFor()
234
235 return if (process.exitValue() == 0) {
236 inputStream.bufferedReader()
237 .use { it.readText().trim() } // return the value of gitHash
238 } else {
239 val errorMessage = errorStream.bufferedReader().use { it.readText().trim() }
240 logger.error("Error running git command: $errorMessage")
241 "dummy-hash" // return a dummy hash value in case of an error
242 }
243 } catch (e: Exception) {
244 logger.error("$e: Cannot find git, defaulting to dummy build hash")
245 return "dummy-hash" // return a dummy hash value in case of an error
246 }
247}
248
249fun getBranch(): String {
250 try {
251 val processBuilder = ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")
252 processBuilder.directory(project.rootDir)
253 val process = processBuilder.start()
254 val inputStream = process.inputStream
255 val errorStream = process.errorStream
256 process.waitFor()
257
258 return if (process.exitValue() == 0) {
259 inputStream.bufferedReader()
260 .use { it.readText().trim() } // return the value of gitHash
261 } else {
262 val errorMessage = errorStream.bufferedReader().use { it.readText().trim() }
263 logger.error("Error running git command: $errorMessage")
264 "dummy-hash" // return a dummy hash value in case of an error
265 }
266 } catch (e: Exception) {
267 logger.error("$e: Cannot find git, defaulting to dummy build hash")
268 return "dummy-hash" // return a dummy hash value in case of an error
269 }
270}