build.gradle.kts 9.0 KB

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