Corregge i simboli nativi AAB in formato .so.sym per Play Console.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 19:45:29 +02:00
co-authored by Cursor
parent 5daada81b0
commit b8694a6b7b
+48 -10
View File
@@ -1,3 +1,4 @@
import java.io.File
import java.util.Properties import java.util.Properties
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipFile import java.util.zip.ZipFile
@@ -23,8 +24,8 @@ android {
applicationId = "com.matchlivetv.match_live_tv" applicationId = "com.matchlivetv.match_live_tv"
minSdk = 24 minSdk = 24
targetSdk = 36 targetSdk = 36
versionCode = 30 versionCode = 31
versionName = "2.0.9-native" versionName = "2.0.10-native"
val apiBaseUrl = project.findProperty("API_BASE_URL") as String? val apiBaseUrl = project.findProperty("API_BASE_URL") as String?
?: "https://www.matchlivetv.it" ?: "https://www.matchlivetv.it"
@@ -122,11 +123,21 @@ dependencies {
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0") androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
} }
// Play Console: le .so prebuilt (AndroidX) sono già stripped → AGP non aggiunge // Play Console: le .so prebuilt (AndroidX) sono già stripped → AGP salta l'estrazione
// BUNDLE-METADATA/com.android.tools.build.debugsymbols. Incorporiamo un zip ABI/.so // (niente BUNDLE-METADATA/com.android.tools.build.debugsymbols). Generiamo i .so.sym
// nell'intermediary bundle prima della firma. // come fa AGP (llvm-objcopy --strip-debug) e li iniettiamo nell'intermediary AAB.
fun findLlvmObjcopy(): File {
val ndkRoot = File(android.sdkDirectory, "ndk")
val ndkDirs = ndkRoot.listFiles()?.filter { it.isDirectory }?.sortedByDescending { it.name }.orEmpty()
for (ndk in ndkDirs) {
val candidate = ndk.resolve("toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy")
if (candidate.isFile) return candidate
}
error("llvm-objcopy non trovato sotto ${ndkRoot.absolutePath}")
}
val injectNativeDebugSymbolsInReleaseBundle by tasks.registering { val injectNativeDebugSymbolsInReleaseBundle by tasks.registering {
description = "Embed native-debug-symbols.zip into the release AAB intermediary" description = "Embed native-debug-symbols.zip (.so.sym) into the release AAB intermediary"
val mergeNative = tasks.named("mergeReleaseNativeLibs") val mergeNative = tasks.named("mergeReleaseNativeLibs")
val packageBundle = tasks.named("packageReleaseBundle") val packageBundle = tasks.named("packageReleaseBundle")
dependsOn(mergeNative, packageBundle) dependsOn(mergeNative, packageBundle)
@@ -157,15 +168,40 @@ val injectNativeDebugSymbolsInReleaseBundle by tasks.registering {
require(libsDir.isDirectory) { "Native libs missing: $libsDir" } require(libsDir.isDirectory) { "Native libs missing: $libsDir" }
require(aabFile.isFile) { "Intermediary AAB missing: $aabFile" } require(aabFile.isFile) { "Intermediary AAB missing: $aabFile" }
val objcopy = findLlvmObjcopy()
val workDir = layout.buildDirectory.dir("tmp/native-debug-symbols-inject").get().asFile val workDir = layout.buildDirectory.dir("tmp/native-debug-symbols-inject").get().asFile
workDir.deleteRecursively() workDir.deleteRecursively()
workDir.mkdirs() workDir.mkdirs()
val symbolsRoot = workDir.resolve("symbols")
symbolsRoot.mkdirs()
var count = 0
libsDir.walkTopDown().filter { it.isFile && it.extension == "so" }.forEach { so ->
val rel = so.relativeTo(libsDir).invariantSeparatorsPath
val outRel = "$rel.sym"
val outFile = symbolsRoot.resolve(outRel)
outFile.parentFile.mkdirs()
// Allineato ad AGP SYMBOL_TABLE: llvm-objcopy --strip-debug → *.so.sym
val proc = ProcessBuilder(
objcopy.absolutePath,
"--strip-debug",
so.absolutePath,
outFile.absolutePath,
).redirectErrorStream(true).start()
val out = proc.inputStream.bufferedReader().readText()
check(proc.waitFor() == 0) {
"objcopy failed for $rel: $out"
}
count++
}
check(count > 0) { "Nessuna .so da cui generare simboli in $libsDir" }
val symbolsZip = workDir.resolve("native-debug-symbols.zip") val symbolsZip = workDir.resolve("native-debug-symbols.zip")
ZipOutputStream(symbolsZip.outputStream().buffered()).use { zos -> ZipOutputStream(symbolsZip.outputStream().buffered()).use { zos ->
libsDir.walkTopDown().filter { it.isFile && it.extension == "so" }.forEach { so -> symbolsRoot.walkTopDown().filter { it.isFile }.forEach { f ->
val rel = so.relativeTo(libsDir).invariantSeparatorsPath val rel = f.relativeTo(symbolsRoot).invariantSeparatorsPath
zos.putNextEntry(ZipEntry(rel)) zos.putNextEntry(ZipEntry(rel))
so.inputStream().use { it.copyTo(zos) } f.inputStream().use { it.copyTo(zos) }
zos.closeEntry() zos.closeEntry()
} }
} }
@@ -192,7 +228,9 @@ val injectNativeDebugSymbolsInReleaseBundle by tasks.registering {
} }
} }
outAab.copyTo(aabFile, overwrite = true) outAab.copyTo(aabFile, overwrite = true)
logger.lifecycle("Injected $metaPath (${symbolsZip.length()} bytes) into ${aabFile.name}") logger.lifecycle(
"Injected $metaPath ($count .so.sym, ${symbolsZip.length()} bytes) into ${aabFile.name} via ${objcopy.name}",
)
} }
} }