# Compile, empaquette, installe et lance le client Android. # # POURQUOI CE SCRIPT. La chaine a quatre etapes qui ne s'appellent pas entre # elles, et en sauter une donne un APK qui s'installe sans porter la # modification - le symptome se lit alors comme un bug applicatif. La premiere, # web.res, s'est deja fait oublier une fois : la page embarquee etait celle # d'avant l'edition, et le pont echouait pour une raison qui n'existait plus. # # -NoInstall compile et empaquette sans toucher au telephone. # -Release configuration Release, signee avec VOTRE magasin de cles. # # LA RELEASE NE S'INSTALLE PAS PAR-DESSUS LE DEBOGAGE. Android refuse une # signature differente sur un paquet deja installe ; il faut desinstaller # d'abord, ce qui EFFACE le cache local et les reglages de l'appareil. Le # script ne le fait donc pas a votre place - il produit l'APK et s'arrete. # # .\android-client\build-apk.ps1 -Release ` # -Keystore C:\cles\pmserver-release.jks -Alias pmserver param( [switch]$NoInstall, [switch]$Release, [string]$Keystore, [string]$Alias = 'pmserver' ) $ErrorActionPreference = 'Stop' $root = Split-Path $PSScriptRoot -Parent $bin = 'C:\Program Files (x86)\Embarcadero\Studio\23.0\bin' $sdk = 'C:\Users\Public\Documents\Embarcadero\Studio\23.0\CatalogRepository' $adb = "$sdk\AndroidSDK-2525-23.0.51511.6924\platform-tools\Adb.exe" $strip = "$sdk\AndroidNDK-21-23.0.51511.6924\android-ndk-r21\toolchains\" + 'aarch64-linux-android-4.9\prebuilt\windows-x86_64\aarch64-linux-android\bin\strip.exe' $cfg = if ($Release) { 'Release' } else { 'Debug' } $out = "$root\Android64\$cfg" $stage = "$out\pmserverApk" if ($Release) { if (-not $Keystore) { throw 'Chemin du magasin de cles requis : -Keystore' } if (-not (Test-Path $Keystore)) { throw "Magasin introuvable : $Keystore" } # LU ICI ET NULLE PART AILLEURS. Read-Host -AsSecureString n'affiche rien et # ne laisse pas la frappe dans l'historique de la console. $sec = Read-Host "Mot de passe du magasin $([IO.Path]::GetFileName($Keystore))" -AsSecureString $env:PM_KS_PASS = [Runtime.InteropServices.Marshal]::PtrToStringBSTR( [Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)) } # 1. La page HTML -> ressource liee dans l'executable. Push-Location "$PSScriptRoot\web" & "$bin\brcc32.exe" web.rc -foweb.res | Out-Null Pop-Location # 2. Compilation Delphi. $msbuild = "`"$bin\rsvars.bat`" && msbuild `"$root\pmserverApk.dproj`"" $log = cmd /c "$msbuild /p:Platform=Android64 /p:Config=$cfg /t:Build /v:minimal /nologo" 2>&1 $err = $log | Select-String -Pattern 'error' if ($err) { $err | ForEach-Object { $_.Line }; throw 'compilation echouee' } $log | Select-String -Pattern 'lines,' | ForEach-Object { $_.Line.Trim() } # 3. Mise en place a la main de ce que le deploiement ne place pas : manifeste, # .dex, et la bibliotheque native ALLEGEE - la version de debogage pese # 91 Mo, plus que la place libre sur ce volume. # # LES DOSSIERS D'ABORD, ET C'EST LA PREMIERE RELEASE QUI L'A APPRIS. Cet arbre # est normalement creuse par l'etape Deploy - qui vient APRES celle-ci. En # debogage il existait deja, laisse par un deploiement anterieur, et personne ne # s'en apercevait ; pour une configuration jamais empaquetee, les trois copies # ci-dessous tombaient sur un chemin absent. Les creer ne coute rien quand elles # existent, et evite qu'une configuration neuve echoue sur sa premiere ligne. New-Item -ItemType Directory -Force -Path "$stage", "$stage\classes", "$stage\library\lib\arm64-v8a" | Out-Null Copy-Item "$out\AndroidManifest.xml" "$stage\AndroidManifest.xml" -Force # DELPHI MET android:debuggable="true" MEME EN RELEASE, et l'APK livre le # portait. Sur un telephone ou le debogage USB est actif, `adb run-as` ouvre # alors le dossier prive de l'application - donc vault.bin et les reglages - # sans acces root. On le force a faux pour une release, et seulement la. if ($Release) { $mf = Get-Content "$stage\AndroidManifest.xml" -Raw $mf = $mf -replace 'android:debuggable="true"', 'android:debuggable="false"' Set-Content "$stage\AndroidManifest.xml" -Value $mf -Encoding utf8 } Copy-Item "$out\pmserverApk.classes\*.dex" "$stage\classes\" -Force & $strip --strip-debug -o "$stage\library\lib\arm64-v8a\libpmserverApk.so" "$out\libpmserverApk.so" # L'AAPT DE DEPLOY ECHOUE, ET C'EST ATTENDU. Le manifeste reference # @xml/network_security_config, que la generation de ressources de Delphi ne # contient pas ; poser le fichier avant Deploy ne sert a rien, Deploy reconstruit # res\ juste avant d'appeler aapt. L'etape suivante repose nos ressources et # refait l'archive entiere, donc l'APK livre est complet - verifie a # "aapt list" : res/xml/network_security_config.xml y est, et l'attribut du # manifeste resout vers un identifiant reel. # # On ne masque donc que CETTE erreur, nommement, et tout autre message remonte. $deploy = cmd /c "$msbuild /p:Platform=Android64 /p:Config=$cfg /t:Deploy /v:minimal /nologo" 2>&1 $deploy | Select-String -Pattern 'error' | Where-Object { $_.Line -notmatch 'network_security_config|Unable to execute.*Aapt\.exe' } | ForEach-Object { $_.Line } # 4. aapt + zipalign + apksigner, et remise en place de ce que Deploy efface. try { if ($Release) { & "$PSScriptRoot\repack-apk.ps1" -Config Release -Keystore $Keystore -Alias $Alias } else { & "$PSScriptRoot\repack-apk.ps1" | Select-Object -Last 1 } } finally { # Le mot de passe ne survit pas au script, meme si celui-ci echoue. Remove-Item Env:PM_KS_PASS -ErrorAction SilentlyContinue } if ($Release) { "APK signe : $stage\bin\pmserverApk.apk" 'Non installe : desinstaller d''abord la version de debogage effacerait le' + ' coffre local et les reglages.' return } if ($NoInstall) { return } # adb ecrit sa progression sur la sortie d'erreur, ce que PowerShell prend pour # un echec. Sans ce relachement, une installation reussie interrompt le script. $ErrorActionPreference = 'Continue' & $adb install -r "$stage\bin\pmserverApk.apk" 2>&1 | Select-String -Pattern 'Success|Failure' | ForEach-Object { $_.Line } # Le telephone voit le poste comme 127.0.0.1 par ce renvoi. & $adb reverse tcp:8080 tcp:80 | Out-Null & $adb shell am force-stop com.embarcadero.pmserverApk & $adb shell am start -n com.embarcadero.pmserverApk/com.embarcadero.firemonkey.FMXNativeActivity | Out-Null