Merge pull request #12183 from t895/gradle-kotlin-dsl

Android: Gradle updates
This commit is contained in:
OatmealDome 2023-12-10 11:17:56 -05:00 committed by GitHub
commit d272b0ef84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 351 additions and 360 deletions

View File

@ -39,4 +39,5 @@ tasks.xml
build/
*.so
*.iml
build.properties
build.properties
baseline-prof.txt

View File

@ -1,221 +0,0 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.serialization' version "1.8.21"
}
task copyProfile (type: Copy) {
description('Copies a generated baseline profile text file from managed device to src/main in the app module.')
from(project(':benchmark').file('build/outputs/managed_device_android_test_additional_output/pixel6Api31'))
into('src/main')
include('BaselineProfileGenerator_generate-baseline-prof.txt')
rename('BaselineProfileGenerator_generate-baseline-prof', 'baseline-prof')
}
android {
compileSdkVersion 33
ndkVersion "25.2.9519653"
viewBinding.enabled = true
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
sourceCompatibility = "17"
targetCompatibility = "17"
}
kotlinOptions {
jvmTarget = '17'
}
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
//Uncomment disable lines for test builds...
//disable 'MissingTranslation'
//disable 'ExtraTranslation'
}
defaultConfig {
applicationId "org.dolphinemu.dolphinemu"
minSdkVersion 21
targetSdkVersion 33
versionCode(getBuildVersionCode())
versionName "${getVersion()}"
buildConfigField "String", "GIT_HASH", "\"${getGitHash()}\""
buildConfigField "String", "BRANCH", "\"${getBranch()}\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
if (project.hasProperty('keystore')) {
storeFile file(project.property('keystore'))
storePassword project.property('storepass')
keyAlias project.property('keyalias')
keyPassword project.property('keypass')
}
}
}
// Define build types, which are orthogonal to product flavors.
buildTypes {
// Signed by release key, allowing for upload to Play Store.
release {
if (project.hasProperty('keystore')) {
signingConfig signingConfigs.release
}
resValue 'string', 'app_name_suffixed', 'Dolphin Emulator'
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
preBuild.dependsOn copyProfile
}
// Signed by debug key disallowing distribution on Play Store.
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
debug {
resValue 'string', 'app_name_suffixed', 'Dolphin Debug'
applicationIdSuffix ".debug"
versionNameSuffix '-debug'
jniDebuggable true
}
benchmark {
resValue 'string', 'app_name_suffixed', 'Dolphin Benchmark'
signingConfig signingConfigs.debug
matchingFallbacks = ['release']
debuggable false
applicationIdSuffix ".benchmark"
versionNameSuffix '-benchmark'
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
minifyEnabled true
shrinkResources true
}
}
externalNativeBuild {
cmake {
path "../../../CMakeLists.txt"
version "3.22.1+"
}
}
namespace 'org.dolphinemu.dolphinemu'
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_static", "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
// , "-DENABLE_GENERIC=ON"
abiFilters "arm64-v8a", "x86_64" //, "armeabi-v7a", "x86"
// Remove the line below if you want to build the C++ unit tests
//targets "main", "hook_impl", "main_hook", "gsl_alloc_hook", "file_redirect_hook"
}
}
}
packagingOptions {
jniLibs.useLegacyPackaging = true
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.exifinterface:exifinterface:1.3.6'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.1'
implementation 'androidx.fragment:fragment:1.6.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.preference:preference:1.2.0'
implementation 'androidx.profileinstaller:profileinstaller:1.3.1'
// Kotlin extensions for lifecycle components
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
// Android TV UI libraries.
implementation 'androidx.leanback:leanback:1.0.0'
implementation 'androidx.tvprovider:tvprovider:1.0.0'
// For REST calls
implementation 'com.android.volley:volley:1.2.1'
// For loading game covers from disk and GameTDB
implementation 'io.coil-kt:coil:2.2.2'
// For loading custom GPU drivers
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation 'com.nononsenseapps:filepicker:4.2.1'
}
def getVersion() {
def versionNumber = '0.0'
try {
versionNumber = 'git describe --always --long'.execute([], project.rootDir).text
.trim()
.replaceAll(/(-0)?-[^-]+$/, "")
} catch (Exception e) {
logger.error(e + ': Cannot find git, defaulting to dummy version number')
}
return versionNumber
}
def getBuildVersionCode() {
try {
def versionNumber = 'git rev-list --first-parent --count HEAD'.execute([], project.rootDir).text
.trim()
return Integer.valueOf(versionNumber)
} catch (Exception e) {
logger.error(e + ': Cannot find git, defaulting to dummy version number')
}
return 1
}
def getGitHash() {
try {
def gitHash = 'git rev-parse HEAD'.execute([], project.rootDir).text.trim()
return gitHash
} catch (Exception e) {
logger.error(e + ': Cannot find git, defaulting to dummy build hash')
}
return 0
}
def getBranch() {
try {
def branch = 'git rev-parse --abbrev-ref HEAD'.execute([], project.rootDir).text.trim()
return branch
} catch (Exception e) {
logger.error(e + ': Cannot find git, defaulting to dummy build hash')
}
return 'master'
}

View File

@ -0,0 +1,217 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.8.21"
id("androidx.baselineprofile")
}
@Suppress("UnstableApiUsage")
android {
compileSdkVersion = "android-34"
ndkVersion = "25.2.9519653"
buildFeatures {
viewBinding = true
}
compileOptions {
// Flag to enable support for the new language APIs
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
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
//Uncomment disable lines for test builds...
//disable "MissingTranslation"
//disable "ExtraTranslation"
}
defaultConfig {
applicationId = "org.dolphinemu.dolphinemu"
minSdk = 21
targetSdk = 34
versionCode = getBuildVersionCode()
versionName = getGitVersion()
buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"")
buildConfigField("String", "BRANCH", "\"${getBranch()}\"")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
create("release") {
if (project.hasProperty("keystore")) {
storeFile = file(project.property("keystore")!!)
storePassword = project.property("storepass").toString()
keyAlias = project.property("keyalias").toString()
keyPassword = project.property("keypass").toString()
}
}
}
// Define build types, which are orthogonal to product flavors.
buildTypes {
// Signed by release key, allowing for upload to Play Store.
release {
if (project.hasProperty("keystore")) {
signingConfig = signingConfigs.getByName("release")
}
resValue("string", "app_name_suffixed", "Dolphin Emulator")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)
}
// Signed by debug key disallowing distribution on Play Store.
// Attaches "debug" suffix to version and package name, allowing installation alongside the release build.
debug {
resValue("string", "app_name_suffixed", "Dolphin Debug")
applicationIdSuffix = ".debug"
versionNameSuffix = "-debug"
isJniDebuggable = true
}
}
externalNativeBuild {
cmake {
path = file("../../../CMakeLists.txt")
version = "3.22.1+"
}
}
namespace = "org.dolphinemu.dolphinemu"
defaultConfig {
externalNativeBuild {
cmake {
arguments("-DANDROID_STL=c++_static", "-DCMAKE_BUILD_TYPE=RelWithDebInfo")
// , "-DENABLE_GENERIC=ON"
abiFilters("arm64-v8a", "x86_64") //, "armeabi-v7a", "x86"
// Remove the line below if you want to build the C++ unit tests
//targets "main", "hook_impl", "main_hook", "gsl_alloc_hook", "file_redirect_hook"
}
}
}
packaging {
jniLibs.useLegacyPackaging = true
}
}
dependencies {
"baselineProfile"(project(":benchmark"))
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.exifinterface:exifinterface:1.3.6")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.fragment:fragment-ktx:1.6.2")
implementation("androidx.slidingpanelayout:slidingpanelayout:1.2.0")
implementation("com.google.android.material:material:1.10.0")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
// Kotlin extensions for lifecycle components
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
// Android TV UI libraries.
implementation("androidx.leanback:leanback:1.0.0")
implementation("androidx.tvprovider:tvprovider:1.0.0")
// For REST calls
implementation("com.android.volley:volley:1.2.1")
// For loading game covers from disk and GameTDB
implementation("io.coil-kt:coil:2.5.0")
// For loading custom GPU drivers
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("com.nononsenseapps:filepicker:4.2.1")
}
fun getGitVersion(): String {
try {
return 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")
}
return "0.0"
}
fun getBuildVersionCode(): Int {
try {
return Integer.valueOf(
ProcessBuilder("git", "rev-list", "--first-parent", "--count", "HEAD")
.directory(project.rootDir)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start().inputStream.bufferedReader().use { it.readText() }
.trim()
)
} catch (e: Exception) {
logger.error("Cannot find git, defaulting to dummy version code")
}
return 1
}
fun getGitHash(): String {
try {
return ProcessBuilder("git", "rev-parse", "HEAD")
.directory(project.rootDir)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start().inputStream.bufferedReader().use { it.readText() }
.trim()
} catch (e: Exception) {
logger.error("Cannot find git, defaulting to dummy git hash")
}
return "0"
}
fun getBranch(): String {
try {
return ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")
.directory(project.rootDir)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start().inputStream.bufferedReader().use { it.readText() }
.trim()
} catch (e: Exception) {
logger.error("Cannot find git, defaulting to dummy git hash")
}
return "master"
}

View File

@ -1 +1 @@
/build
/build

View File

@ -1,71 +0,0 @@
import com.android.build.api.dsl.ManagedVirtualDevice
plugins {
id 'com.android.test'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.dolphin.benchmark'
compileSdk 33
compileOptions {
sourceCompatibility = "11"
targetCompatibility = "11"
}
kotlinOptions {
jvmTarget = "11"
}
defaultConfig {
minSdk 23
targetSdk 33
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
testOptions {
managedDevices {
devices {
pixel6Api31 (ManagedVirtualDevice) {
device = "Pixel 6"
apiLevel = 31
systemImageSource = "aosp"
}
}
}
}
buildTypes {
// This benchmark buildType is used for benchmarking, and should function like your
// release build (for example, with minification on). It's signed with a debug key
// for easy local/CI testing.
benchmark {
signingConfig signingConfigs.debug
matchingFallbacks = ['release']
debuggable true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
minifyEnabled true
shrinkResources true
}
}
targetProjectPath = ":app"
experimentalProperties["android.experimental.self-instrumenting"] = true
}
dependencies {
implementation 'androidx.test.ext:junit:1.1.5'
implementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'androidx.test.uiautomator:uiautomator:2.2.0'
implementation 'androidx.benchmark:benchmark-macro-junit4:1.1.1'
}
androidComponents {
beforeVariants(selector().all()) {
enabled = buildType == "benchmark"
}
}

View File

@ -0,0 +1,52 @@
import com.android.build.api.dsl.ManagedVirtualDevice
plugins {
id("com.android.test")
id("org.jetbrains.kotlin.android")
id("androidx.baselineprofile")
}
android {
namespace = "org.dolphinemu.baselineprofile"
compileSdk = 34
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
defaultConfig {
minSdk = 28
targetSdk = 34
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
targetProjectPath = ":app"
testOptions.managedDevices.devices {
create<ManagedVirtualDevice>("pixel6Api31") {
device = "Pixel 6"
apiLevel = 31
systemImageSource = "google"
}
}
}
// This is the configuration block for the Baseline Profile plugin.
// You can specify to run the generators on a managed devices or connected devices.
baselineProfile {
managedDevices += "pixel6Api31"
useConnectedDevices = false
}
dependencies {
implementation("androidx.test.ext:junit:1.1.5")
implementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("androidx.test.uiautomator:uiautomator:2.2.0")
implementation("androidx.benchmark:benchmark-macro-junit4:1.2.2")
}

View File

@ -1,6 +1 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<queries>
<package android:name="org.dolphinemu.dolphinemu.debug" />
</queries>
</manifest>
<manifest />

View File

@ -1,40 +0,0 @@
package com.dolphin.benchmark
import androidx.benchmark.macro.BaselineProfileMode
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.StartupMode
import androidx.benchmark.macro.StartupTimingMetric
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
@get:Rule
val benchmarkRule = MacrobenchmarkRule()
@Test
fun startupBaselineProfileDisabled() = startup(
CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Disable, warmupIterations = 1)
)
@Test
fun startupBaselineProfile() = startup(
CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require, warmupIterations = 1)
)
private fun startup(compilationMode: CompilationMode) = benchmarkRule.measureRepeated(
packageName = "org.dolphinemu.dolphinemu.benchmark",
metrics = listOf(StartupTimingMetric()),
iterations = 10,
compilationMode = compilationMode,
startupMode = StartupMode.COLD,
setupBlock = {
pressHome()
}
) {
startActivityAndWait()
}
}

View File

@ -1,24 +1,25 @@
package com.dolphin.benchmark
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.baselineprofile
import androidx.benchmark.macro.ExperimentalBaselineProfilesApi
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.uiautomator.UiSelector
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@OptIn(ExperimentalBaselineProfilesApi::class)
@RunWith(AndroidJUnit4ClassRunner::class)
@RunWith(AndroidJUnit4::class)
@LargeTest
class BaselineProfileGenerator {
@get:Rule
val rule = BaselineProfileRule()
@Test
fun generate() = rule.collectBaselineProfile(
packageName = "org.dolphinemu.dolphinemu.benchmark",
profileBlock = {
fun generate() {
rule.collect("org.dolphinemu.dolphinemu") {
pressHome()
startActivityAndWait()
@ -26,7 +27,7 @@ class BaselineProfileGenerator {
device.pressBack()
// Navigate through activities that don't require games
// TODO: Make all activities testable without having games available
// TODO: Make all activities testable without having games available (or use homebrew)
// TODO: Use resource strings to support more languages
// Navigate to the Settings Activity
@ -38,6 +39,6 @@ class BaselineProfileGenerator {
config.click()
val userData = device.findObject(UiSelector().textContains("User Data"))
userData.clickAndWaitForNewWindow(30_000)
},
)
}
}
}

View File

@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.baselineprofile
import androidx.benchmark.macro.BaselineProfileMode
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.StartupMode
import androidx.benchmark.macro.StartupTimingMetric
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@LargeTest
class StartupBenchmarks {
@get:Rule
val rule = MacrobenchmarkRule()
@Test
fun startupCompilationNone() =
benchmark(CompilationMode.None())
@Test
fun startupCompilationBaselineProfiles() =
benchmark(CompilationMode.Partial(BaselineProfileMode.Require))
private fun benchmark(compilationMode: CompilationMode) {
rule.measureRepeated(
packageName = "org.dolphinemu.dolphinemu",
metrics = listOf(StartupTimingMetric()),
compilationMode = compilationMode,
startupMode = StartupMode.COLD,
iterations = 10,
setupBlock = {
pressHome()
},
measureBlock = {
startActivityAndWait()
}
)
}
}

View File

@ -1,6 +0,0 @@
// 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
}

View File

@ -0,0 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.2.0" apply false
id("com.android.library") version "8.2.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.21" apply false
id("com.android.test") version "8.2.0" apply false
id("androidx.baselineprofile") version "1.2.0" apply false
}
buildscript {
repositories {
google()
}
}

View File

@ -1,6 +1,6 @@
#Thu Dec 08 14:08:30 EST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -5,6 +5,8 @@ pluginManagement {
mavenCentral()
}
}
@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
@ -12,5 +14,6 @@ dependencyResolutionManagement {
mavenCentral()
}
}
include ':app'
include ':benchmark'
include(":app")
include(":benchmark")