Corregge i simboli nativi AAB in formato .so.sym per Play Console.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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 symbolsZip = workDir.resolve("native-debug-symbols.zip")
|
val symbolsRoot = workDir.resolve("symbols")
|
||||||
ZipOutputStream(symbolsZip.outputStream().buffered()).use { zos ->
|
symbolsRoot.mkdirs()
|
||||||
|
|
||||||
|
var count = 0
|
||||||
libsDir.walkTopDown().filter { it.isFile && it.extension == "so" }.forEach { so ->
|
libsDir.walkTopDown().filter { it.isFile && it.extension == "so" }.forEach { so ->
|
||||||
val rel = so.relativeTo(libsDir).invariantSeparatorsPath
|
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")
|
||||||
|
ZipOutputStream(symbolsZip.outputStream().buffered()).use { zos ->
|
||||||
|
symbolsRoot.walkTopDown().filter { it.isFile }.forEach { f ->
|
||||||
|
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}",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user