fa2160104c
Le Build depose a plat dans Android64\<Config>\ les ressources d'Android - styles.xml, strings.xml, les variantes -v21/-v31, l'icone adaptative - et c'est le Deploy qui devrait les ranger dans res\. Il le fait en DEBUG et pas en RELEASE, alors que les proprietes Android_* du .dproj sont communes aux deux configurations et qu'aucune entree de deploiement ne les nomme. Sans elles, aapt refuse le paquet sur "@style/AppTheme" introuvable : le manifeste reference un theme que plus rien ne definit. Le script les range donc lui-meme, avant nos propres ressources pour que notre colors.xml garde le dernier mot. La correspondance nom-fichier vers sous-dossier est transcrite explicitement : un fichier nouveau se signalera au lieu d'etre range au hasard. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
140 lines
7.2 KiB
PowerShell
140 lines
7.2 KiB
PowerShell
# Refait les trois dernieres etapes de l'empaquetage Android, sur le dossier
|
|
# deja prepare - sans le vider au prealable.
|
|
#
|
|
# POURQUOI : la cible Deploy de MSBuild reconstruit library\lib avant d'appeler
|
|
# aapt, ce qui efface toute bibliotheque native ajoutee a la main. Or ce projet
|
|
# n'a pas d'entrees de deploiement fonctionnelles (voir README), donc nos icones
|
|
# ne peuvent y arriver autrement. On laisse Deploy faire son travail, puis on
|
|
# remet ce qu'il a efface et on refait aapt / zipalign / signature.
|
|
#
|
|
# A lancer depuis la racine du depot, apres un Deploy reussi.
|
|
#
|
|
# -Config Release empaquette la sortie Release au lieu de Debug
|
|
# -Keystore <chemin> -Alias signe avec CETTE cle au lieu de celle de debogage
|
|
#
|
|
# LE MOT DE PASSE NE PASSE PAS PAR LA LIGNE DE COMMANDE. paclient --apksign
|
|
# l'y met en clair, ou n'importe quel processus de la machine peut le lire.
|
|
# apksigner sait lire une variable d'environnement ; on l'appelle donc en
|
|
# direct pour une vraie cle, et on ne garde paclient que pour la cle de
|
|
# debogage, dont le mot de passe est public et vaut "android".
|
|
|
|
param(
|
|
[ValidateSet('Debug', 'Release')] [string]$Config = 'Debug',
|
|
[string]$Keystore,
|
|
[string]$Alias
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$sdk = 'C:\Users\Public\Documents\Embarcadero\Studio\23.0\CatalogRepository\AndroidSDK-2525-23.0.51511.6924'
|
|
$bds = 'C:\Program Files (x86)\Embarcadero\Studio\23.0'
|
|
$jdk = 'C:\Program Files\Eclipse Adoptium\jdk-11.0.15.10-hotspot'
|
|
$pac = "$bds\bin\paclient.exe"
|
|
$p = ".\Android64\$Config\pmserverApk"
|
|
|
|
# 0. LES RESSOURCES QUE LA COMPILATION GENERE, MISES EN PLACE A LA MAIN.
|
|
#
|
|
# Le Build les depose a plat dans Android64\<Config>\ - styles.xml,
|
|
# strings.xml, les variantes -v21/-v31, l'icone adaptative - et c'est le Deploy
|
|
# qui devrait les ranger dans res\. Il le fait en DEBUG et pas en RELEASE,
|
|
# raison inconnue : les proprietes Android_* du .dproj sont communes aux deux
|
|
# configurations, et aucune entree de deploiement ne les nomme.
|
|
#
|
|
# Sans elles, aapt refuse le paquet sur "@style/AppTheme" introuvable - le
|
|
# manifeste reference un theme que plus rien ne definit.
|
|
#
|
|
# Le nommage porte la destination : un fichier "nom-qualificatif.xml" va dans
|
|
# le sous-dossier "seau-qualificatif" sous le nom "nom.xml". On transcrit cette
|
|
# regle plutot que de la deviner, pour qu'un fichier nouveau se signale au lieu
|
|
# d'etre range au hasard.
|
|
#
|
|
# AVANT nos propres ressources, pour que celles-ci gardent le dernier mot -
|
|
# notre colors.xml doit l'emporter sur celui de Delphi.
|
|
$genRes = @{
|
|
'strings.xml' = 'values\strings.xml'
|
|
'styles.xml' = 'values\styles.xml'
|
|
'styles-v21.xml' = 'values-v21\styles.xml'
|
|
'styles-v31.xml' = 'values-v31\styles.xml'
|
|
'colors.xml' = 'values\colors.xml'
|
|
'colors-night-v21.xml' = 'values-night-v21\colors.xml'
|
|
'ic_launcher.xml' = 'drawable-anydpi-v26\ic_launcher.xml'
|
|
'ic_launcher-v33.xml' = 'drawable-anydpi-v33\ic_launcher.xml'
|
|
'splash_image_def.xml' = 'drawable\splash_image_def.xml'
|
|
'splash_image_def-v21.xml'= 'drawable-anydpi-v21\splash_image_def.xml'
|
|
}
|
|
$outDir = ".\Android64\$Config"
|
|
foreach ($k in $genRes.Keys) {
|
|
$src = "$outDir\$k"
|
|
if (-not (Test-Path $src)) { continue } # Delphi ne genere pas tout partout
|
|
$dst = Join-Path $p "res\$($genRes[$k])"
|
|
New-Item -ItemType Directory -Force -Path (Split-Path $dst) | Out-Null
|
|
Copy-Item $src $dst -Force
|
|
}
|
|
|
|
# 1. Nos icones par-dessus celles de Delphi :
|
|
# les proprietes Android_LauncherIcon* et Android_AdaptiveIcon* du .dproj
|
|
# devraient suffire, mais rien ne les deploie ici.
|
|
Copy-Item "$PSScriptRoot\android-res\*" "$p\res\" -Recurse -Force
|
|
|
|
# 1 ter. L'ecran de demarrage existe en plusieurs variantes de densite et de
|
|
# theme, toutes identiques chez nous. Une seule source, recopiee : quatre
|
|
# fichiers identiques dans le depot finiraient par diverger.
|
|
$splash = "$p\res\drawable\splash_vector.xml"
|
|
foreach ($v in 'drawable-anydpi-v31', 'drawable-night-anydpi-v21', 'drawable-night-anydpi-v31') {
|
|
if (Test-Path "$p\res\$v") { Copy-Item $splash "$p\res\$v\splash_vector.xml" -Force }
|
|
}
|
|
if (Test-Path "$p\res\drawable-anydpi-v21") {
|
|
Copy-Item "$p\res\drawable\splash_image_def.xml" "$p\res\drawable-anydpi-v21\splash_image_def.xml" -Force
|
|
}
|
|
# Le fond sombre vaut aussi en theme clair : l'application n'a qu'un theme.
|
|
if (Test-Path "$p\res\values-night-v21") {
|
|
Copy-Item "$PSScriptRoot\android-res\values\colors.xml" "$p\res\values-night-v21\colors.xml" -Force
|
|
}
|
|
|
|
# 1 quater. AAPT N'ACCEPTE QUE DES DOSSIERS A LA RACINE DE res\.
|
|
#
|
|
# Le deploiement de Delphi y depose aussi une copie a plat de cinq de ses
|
|
# ressources - ic_launcher_*, splash_* - alors que les vraies sont dans
|
|
# res\drawable\. aapt refuse alors le paquet entier : "invalid resource
|
|
# directory name", une fois par fichier. On les retire, et rien n'est perdu :
|
|
# ce sont des doublons, verifies presents dans drawable.
|
|
#
|
|
# Ne se voyait pas en debogage, ou l'arbre traine depuis longtemps et ou ces
|
|
# fichiers n'y avaient jamais ete deposes. C'est la premiere release qui l'a
|
|
# montre, comme le dossier de mise en scene absent juste avant.
|
|
Get-ChildItem "$p\res" -File -ErrorAction SilentlyContinue | Remove-Item -Force
|
|
|
|
# 2. aapt : reconstruit l'archive non alignee depuis library, classes, res.
|
|
& $pac -u8 --aaptpackage="$sdk\build-tools\33.0.2\Aapt.exe,$p\library,$p\classes,$p\res,$p\assets,$p\AndroidManifest.xml,$sdk\platforms\android-33\android.jar,$p\bin\pmserverApk-unaligned.apk"
|
|
if ($LASTEXITCODE -ne 0) { throw "aapt a echoue" }
|
|
|
|
# 3. zipalign refuse d'ecraser sa sortie : l'APK precedent doit disparaitre.
|
|
Remove-Item "$p\bin\pmserverApk.apk" -Force -ErrorAction SilentlyContinue
|
|
& $pac -u8 --zipalign="$sdk\build-tools\33.0.2\ZipAlign.exe,$p\bin\pmserverApk-unaligned.apk,$p\bin\pmserverApk.apk,4"
|
|
if ($LASTEXITCODE -ne 0) { throw "zipalign a echoue" }
|
|
|
|
if ($Keystore) {
|
|
# LA CLE DE L'UTILISATEUR. Le mot de passe arrive par PM_KS_PASS, pose par
|
|
# l'appelant juste avant et retire juste apres : il ne figure ni dans le
|
|
# depot, ni dans le .dproj, ni dans une ligne de commande.
|
|
if (-not $env:PM_KS_PASS) { throw 'PM_KS_PASS absent - mot de passe du magasin' }
|
|
& "$jdk\bin\java.exe" -jar "$sdk\build-tools\33.0.2\lib\apksigner.jar" sign `
|
|
--ks "$Keystore" --ks-key-alias "$Alias" `
|
|
--ks-pass env:PM_KS_PASS --key-pass env:PM_KS_PASS `
|
|
"$p\bin\pmserverApk.apk"
|
|
if ($LASTEXITCODE -ne 0) { throw "signature echouee" }
|
|
# DIRE AVEC QUOI ON A SIGNE. Une release signee par megarde avec la cle de
|
|
# debogage s'installe et fonctionne : rien ne la distingue a l'usage, et on
|
|
# ne s'en apercoit qu'au refus de la premiere mise a jour.
|
|
& "$jdk\bin\java.exe" -jar "$sdk\build-tools\33.0.2\lib\apksigner.jar" `
|
|
verify --print-certs "$p\bin\pmserverApk.apk" |
|
|
Select-String -Pattern 'Signer #1 certificate DN|SHA-256 digest' |
|
|
ForEach-Object { $_.Line.Trim() }
|
|
} else {
|
|
& $pac -u8 --apksign="$jdk\bin\java.exe,$sdk\build-tools\33.0.2\lib\apksigner.jar,$p\bin\pmserverApk.apk,androiddebugkey,$env:APPDATA\Embarcadero\BDS\23.0\debug.keystore,android,android"
|
|
if ($LASTEXITCODE -ne 0) { throw "signature echouee" }
|
|
}
|
|
|
|
$apk = Get-Item "$p\bin\pmserverApk.apk"
|
|
"APK {0:N1} Mo" -f ($apk.Length / 1MB)
|