Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/android/build.gradle.kts
5768 views
import com.google.protobuf.gradle.*
import org.gradle.process.ExecOperations
import java.io.ByteArrayOutputStream

plugins {
	id("com.android.application")
	id("com.google.protobuf")
}

// Utility function used to get the git version
// All the below replaces the following "gladed.androidgitversion" config:
// configure<com.gladed.androidgitversion.AndroidGitVersionExtension> {
//   codeFormat = "MNNPPBBBB"
//   format = "%tag%%-count%%-branch%%-dirty%"
//   prefix = "v"  // Only tags beginning with v are considered.
//   untrackedIsDirty = false
// }

fun ProviderFactory.git(vararg args: String): String {
	val result = exec {
		commandLine("git", *args)
		isIgnoreExitValue = true
	}
	return result.standardOutput.asText.get().trim()
}

val gitTag = providers.git("describe", "--tags", "--match", "v*", "--abbrev=0")
	.ifEmpty { "v0.0.0" }
val commitsSinceTag = providers.git(
	"rev-list", "$gitTag..HEAD", "--count"
).toIntOrNull() ?: 0
val branchName = providers.git(
	"rev-parse", "--abbrev-ref", "HEAD"
).replace("/", "-")
val isDirty = providers.git("status", "--porcelain")
	.lineSequence()
	.any { it.isNotBlank() && !it.startsWith("??") } // untrackedIsDirty = false

val (major, minor, patch) = gitTag
	.removePrefix("v")
	.split(".")
	.map { it.toInt() }

val gitVersionName = buildString {
	append(gitTag)
	append("-")
	append(commitsSinceTag)
	append("-")
	append(branchName)
	if (isDirty) append("-dirty")
}

val gitVersionCode =
	major * 100_000_000 +
		minor * 1000_000 +
		patch * 10_000 +
		commitsSinceTag

dependencies {
	// 1.6.1 is the newest version we can use that won't complain about minSdk version,
	// and also doesn't collide kotlin versions with com.gladed.androidgitversion.
	// Will replace with a different plugin soon.
	implementation("androidx.appcompat:appcompat:1.7.1")
	implementation("androidx.documentfile:documentfile:1.1.0")
	implementation("com.google.protobuf:protobuf-javalite:4.33.4")
}

protobuf {
	protoc {
		artifact = "com.google.protobuf:protoc:3.25.3"
	}

	generateProtoTasks {
		all().forEach { task ->
			task.builtins {
				register("java") {
					option("lite")
				}
			}
		}
	}
}

android {
	flavorDimensions.add("variant")
	namespace = "org.ppsspp.ppsspp"
	signingConfigs {
		getByName("debug") {
			storeFile = file("debug.keystore")
		}
		create("optimized") {
			storeFile = file("debug.keystore")
		}
		if (project.hasProperty("RELEASE_STORE_FILE")) {
			create("release") {
				storeFile = file(project.property("RELEASE_STORE_FILE") as String)
				storePassword = project.property("RELEASE_STORE_PASSWORD") as String
				keyAlias = project.property("RELEASE_KEY_ALIAS") as String
				keyPassword = project.property("RELEASE_KEY_PASSWORD") as String
			}
		}
	}

	compileSdk = 36
	ndkVersion = "29.0.14206865"

	compileOptions {
		sourceCompatibility = JavaVersion.VERSION_11
		targetCompatibility = JavaVersion.VERSION_11
	}

	lint {
		baseline = file("lint-baseline.xml")
	}

	defaultConfig {
		applicationId = "org.ppsspp.ppsspp"
		// Access the git version info via the extension
		if (gitVersionName != "unknown") {
			println("INFO: Overriding Android Version Name, Code: $gitVersionName $gitVersionCode")
			versionName = gitVersionName
			versionCode = gitVersionCode
		} else {
			println("(not using these:) Android Version Name, Code: $gitVersionName $gitVersionCode")
		}
		file("versionname.txt").writeText(gitVersionName)
		file("versioncode.txt").writeText(gitVersionCode.toString())

		minSdk = 21
		targetSdk = 36
		if (project.hasProperty("ANDROID_VERSION_CODE") && project.hasProperty("ANDROID_VERSION_NAME")) {
			versionCode = (project.property("ANDROID_VERSION_CODE") as String).toInt()
			versionName = project.property("ANDROID_VERSION_NAME") as String
		}
	}
	buildTypes {
		getByName("debug") {
			isMinifyEnabled = false
			isJniDebuggable = true
			signingConfig = signingConfigs.getByName("debug")
		}
		create("optimized") {
			isMinifyEnabled = false
			isJniDebuggable = true
			signingConfig = signingConfigs.getByName("debug")
		}
		getByName("release") {
			isMinifyEnabled = false
			if (project.hasProperty("RELEASE_STORE_FILE")) {
				signingConfig = signingConfigs.getByName("release")
			} else {
				println("WARNING: RELEASE_STORE_FILE is missing. Release builds will be unusable.")
			}
		}
	}
	externalNativeBuild {
		cmake {
			path = file("../CMakeLists.txt")
		}
	}
	packaging {
		jniLibs.useLegacyPackaging = true
	}
	sourceSets {
		getByName("main") {
			manifest.srcFile("AndroidManifest.xml")
			res.directories.add("res")
			java.directories.add("src")
			aidl.directories.add("src")
			resources.directories.add("src")
			assets.directories.add("../assets")
		}
		create("normal") {
			res.directories.add("normal/res")
		}
		create("gold") {
			res.directories.add("gold/res")
		}
		create("vr") {
			res.directories.add("normal/res")
			manifest.srcFile("VRManifest.xml")
		}
		create("legacy") {
			res.directories.add("legacy/res")
		}
	}
	productFlavors {
		create("normal") {
			applicationId = "org.ppsspp.ppsspp"
			dimension = "variant"
			externalNativeBuild {
				cmake {
					// **FIXED**: Using simple "listOf"
					arguments.addAll(listOf(
						"-DANDROID=true",
						"-DANDROID_PLATFORM=android-21",
						"-DANDROID_TOOLCHAIN=clang",
						"-DANDROID_CPP_FEATURES=",
						"-DANDROID_STL=c++_shared"
					))
				}
			}
			ndk {
				abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86_64"))
				// debugSymbolLevel = "FULL"  // These don't actually help much in the Google Play crash report. We do still have symbols locally.
			}
		}
		create("gold") {
			applicationId = "org.ppsspp.ppssppgold"
			dimension = "variant"
			externalNativeBuild {
				cmake {
					arguments.addAll(listOf(
						"-DANDROID=true",
						"-DANDROID_PLATFORM=android-21",
						"-DANDROID_TOOLCHAIN=clang",
						"-DANDROID_CPP_FEATURES=",
						"-DANDROID_STL=c++_shared",
						"-DGOLD=TRUE"
					))
				}
			}
			ndk {
				abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86_64"))
				// debugSymbolLevel = "FULL"
			}
		}
		create("legacy") {
			applicationId = "org.ppsspp.ppsspplegacy"
			dimension = "variant"
			targetSdk = 29  // To avoid scoped storage, which is the point of the legacy APK
			externalNativeBuild {
				cmake {
					arguments.addAll(listOf(
						"-DANDROID=true",
						"-DANDROID_PLATFORM=android-21",
						"-DANDROID_TOOLCHAIN=clang",
						"-DANDROID_CPP_FEATURES=",
						"-DANDROID_STL=c++_shared",
						"-DANDROID_LEGACY=TRUE"
					))
				}
			}
			ndk {
				abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
				// debugSymbolLevel = "FULL"
			}
		}
		create("vr") {
			applicationId = "org.ppsspp.ppssppvr"
			dimension = "variant"
			targetSdk = 29  // To avoid scoped storage, which doesn't work properly on Oculus
			externalNativeBuild {
				cmake {
					arguments.addAll(listOf(
						"-DANDROID=true",
						"-DANDROID_PLATFORM=android-21",
						"-DANDROID_TOOLCHAIN=clang",
						"-DANDROID_CPP_FEATURES=",
						"-DANDROID_STL=c++_shared",
						"-DOPENXR=TRUE",
						"-DANDROID_LEGACY=TRUE"
					))
				}
			}
			ndk {
				abiFilters.addAll(listOf("arm64-v8a"))
			}
		}
	}
	buildFeatures {
		aidl = true
		buildConfig = true
	}
}
androidComponents {
	beforeVariants(selector().all()) { variantBuilder ->
		// **FIXED**: Using simple "setOf"
		val enabledVariants = setOf(
			"normalDebug", "normalOptimized", "normalRelease",
			"goldDebug", "goldRelease",
			"vrDebug", "vrOptimized", "vrRelease",
			"legacyDebug", "legacyOptimized", "legacyRelease"
		)
		variantBuilder.enable = variantBuilder.name in enabledVariants
	}
}

/*
afterEvaluate {
	android.sourceSets.getByName("main").assets.srcDirs.forEach {
		println(it)
	}
}*/