import com.android.build.gradle.internal.api.ApkVariantOutputImpl import com.launchers_plugin.renderer.buildscript.RendererConfig import com.launchers_plugin.renderer.buildscript.buildEnvs import com.launchers_plugin.renderer.buildscript.buildJsonValue import com.launchers_plugin.renderer.buildscript.legacyManifest import com.launchers_plugin.renderer.buildscript.nativePath import com.launchers_plugin.renderer.buildscript.renderer buildscript { repositories { maven("https://jitpack.io") } dependencies { classpath("com.github.ZalithLauncher.RendererPlugin-v2:dsl:1.0-alpha6") } } plugins { id("com.android.application") } apply(plugin = "com.launchers_plugin.renderer.dsl") fun Project.mobileGlAbiFilters(): List { val abiList = (findProperty("mobilegl.abis") ?: System.getenv("MOBILEGL_ABIS") ?: "arm64-v8a").toString() return if (abiList.equals("all", ignoreCase = true)) { listOf("arm64-v8a", "x86_64") } else { abiList.split(',').map(String::trim).filter(String::isNotEmpty) } } fun Project.mobileGlCmakeCompilerLauncher(): String = (findProperty("mobilegl.cmakeCompilerLauncher") ?: System.getenv("MOBILEGL_CMAKE_COMPILER_LAUNCHER") ?: "").toString().trim() // Optional application-id suffix, so a development build can sit next to an // already-installed plugin instead of having to replace it - a differently // signed APK cannot upgrade one in place, and uninstalling costs the user their // plugin settings and the launcher's binding to it. fun Project.mobileGlApplicationIdSuffix(): String = (findProperty("mobilegl.applicationIdSuffix") ?: "").toString().trim() fun Project.runGit(vararg arguments: String): String? = runCatching { ProcessBuilder("git", *arguments) .directory(rootDir) .redirectErrorStream(true) .start() .let { process -> val output = process.inputStream.bufferedReader().use { it.readText().trim() } output.takeIf { process.waitFor() == 0 && it.isNotEmpty() } } }.getOrNull() val signingStoreFile = file("../keystore.jks") val signingStorePassword = System.getenv("SIGNING_STORE_PASSWORD") val signingKeyAlias = System.getenv("SIGNING_KEY_ALIAS") val signingKeyPassword = System.getenv("SIGNING_KEY_PASSWORD") val releaseSigningReady = signingStoreFile.exists() && !signingStorePassword.isNullOrEmpty() && !signingKeyAlias.isNullOrEmpty() && !signingKeyPassword.isNullOrEmpty() val debuggableRelease = (findProperty("mobilegl.debuggableRelease") ?: "false").toString().toBoolean() val mobileGlVersionMajor = 26 val mobileGlVersionMinor = 8 val mobileGlGitShortHash = runGit("rev-parse", "--short=7", "HEAD") ?: "nogit" val mobileGlMonthlyRevision = runGit( "rev-list", "--count", "--since=${String.format("%d-%02d-01T00:00:00", 2000 + mobileGlVersionMajor, mobileGlVersionMinor)}", "HEAD", )?.toIntOrNull() ?: 0 val mobileGlApkSuffix = (findProperty("mobilegl.apkSuffix") ?: System.getenv("MOBILEGL_APK_SUFFIX") ?: mobileGlGitShortHash) .toString() .ifBlank { "nogit" } val pluginRendererConfig = buildJsonValue { renderer( displayName = "MobileGL", rendererId = "opengles3", rendererGLPath = nativePath("libMobileGL.so"), rendererEGLPath = nativePath("libMobileGL.so"), dlopenLibPaths = emptyList(), env = buildEnvs { normal("LIBGL_ES", "3") selectable( key = "MOBILEGL_BACKEND_TYPE", title = RendererConfig.MetaString("mobilegl_backend_type_title"), items = RendererConfig.EnvItems("DirectGLES", listOf("DirectVulkan")), ) toggleable("MOBILEGL_DISABLE_TIMERQUERY", "1", false, RendererConfig.MetaString("mobilegl_disable_timerquery_title")) toggleable("MOBILEGL_MAGMA_DISABLE_SUBGROUP", "1", false, RendererConfig.MetaString("mobilegl_disable_subgroup_title")) toggleable("MOBILEGL_MAGMA_R11G11B10F_FALLBACK", "1", false, RendererConfig.MetaString("mobilegl_magma_r11g11b10f_fallback_title")) customizable("MOBILEGL_MAGMA_FRAMESINFLIGHT", "3", RendererConfig.MetaString("mobilegl_magma_frames_inflight_title")) toggleable("MOBILEGL_ESPRYT_AVOID_SAMPLER_MIPMAP_MIN_FILTER", "1", false, RendererConfig.MetaString("mobilegl_avoid_sampler_mipmap_min_filter_title")) toggleable("MOBILEGL_COHERENT_AS_FLUSH", "1", false, RendererConfig.MetaString("mobilegl_coherent_as_flush_title")) toggleable("MOBILEGL_RELAXED_SEMANTICS", "1", false, RendererConfig.MetaString("mobilegl_relaxed_semantics_title")) toggleable("MOBILEGL_ESPRYT_USE_ANGLE", "1", false, RendererConfig.MetaString("mobilegl_use_angle_title")) }, minMCVer = null, maxMCVer = null, ) } android { namespace = "top.mobilegl.plugin" compileSdk = 34 ndkVersion = "27.3.13750724" defaultConfig { applicationId = "top.mobilegl.plugin" mobileGlApplicationIdSuffix().takeIf { it.isNotEmpty() }?.let { applicationIdSuffix = it } minSdk = 26 targetSdk = 34 versionCode = mobileGlVersionMajor * 1_000_000 + mobileGlVersionMinor * 10_000 + mobileGlMonthlyRevision versionName = "%d.%02d.%s".format(mobileGlVersionMajor, mobileGlVersionMinor, mobileGlGitShortHash) resValue("string", "config", pluginRendererConfig) manifestPlaceholders.putAll(legacyManifest { displayName = "MobileGL" rendererName = "MobileGL" rendererLib = "libMobileGL.so" eglLib = "/libMobileGL.so" minMCVer = "" maxMCVer = "" boatEnv { put("LIBGL_ES", "3") put("POJAV_RENDERER", "opengles3") put("MOBILEGL_BACKEND_TYPE", "DirectGLES") } pojavEnv { put("LIBGL_ES", "3") put("POJAV_RENDERER", "opengles3") put("MOBILEGL_BACKEND_TYPE", "DirectGLES") } }) manifestPlaceholders["appLabel"] = "MobileGL" ndk { abiFilters += mobileGlAbiFilters() } externalNativeBuild { cmake { mobileGlCmakeCompilerLauncher().takeIf(String::isNotEmpty)?.let { compilerLauncher -> arguments += listOf( "-DCMAKE_C_COMPILER_LAUNCHER=$compilerLauncher", "-DCMAKE_CXX_COMPILER_LAUNCHER=$compilerLauncher", ) } } } } buildFeatures { resValues = true } flavorDimensions += "profile" productFlavors { create("plugin") { dimension = "profile" } create("trace") { dimension = "profile" applicationIdSuffix = ".trace" versionNameSuffix = "-trace" } } if (releaseSigningReady) { signingConfigs { create("release") { storeFile = signingStoreFile storePassword = signingStorePassword keyAlias = signingKeyAlias keyPassword = signingKeyPassword } } } buildTypes { getByName("release") { isDebuggable = debuggableRelease isMinifyEnabled = false if (releaseSigningReady) { signingConfig = signingConfigs.getByName("release") } } } externalNativeBuild { cmake { path = file("src/trace/cpp/CMakeLists.txt") version = "3.22.1" } } packaging { jniLibs { useLegacyPackaging = true excludes += "**/libSPIRV-Tools-shared.so" } } } android.applicationVariants.configureEach { outputs.configureEach { (this as ApkVariantOutputImpl).outputFileName = when (flavorName) { "plugin" -> "MobileGL-plugin-release-$mobileGlApkSuffix.apk" "trace" -> "MobileGL-plugin-trace-release-$mobileGlApkSuffix.apk" else -> outputFileName } } } androidComponents { onVariants(selector().withFlavor("profile" to "plugin")) { variant -> variant.packaging.jniLibs.excludes.add("**/libtrace_replay_runner.so") } } dependencies { implementation(project(":MobileGL")) }