96 lines
4.4 KiB
PowerShell
96 lines
4.4 KiB
PowerShell
|
|
# Builds Pithos for Android with the bare Android SDK: no Gradle, no AGP.
|
||
|
|
# Toolchain: JDK 8 + build-tools 30.0.3 + platform android-30.
|
||
|
|
# The page is Pithos/web, copied into the APK's assets at build time.
|
||
|
|
# Usage: powershell -File build.ps1 -> build\pithos-debug.apk (debug key)
|
||
|
|
# powershell -File build.ps1 -Release -> build\pithos-v<version>.apk (release key)
|
||
|
|
param([switch]$Release)
|
||
|
|
|
||
|
|
$ErrorActionPreference = "Stop"
|
||
|
|
$VERSION = "0.1.0"
|
||
|
|
$VERSION_CODE = 1
|
||
|
|
|
||
|
|
$SDK = "$env:LOCALAPPDATA\Android\Sdk"
|
||
|
|
$BT = "$SDK\build-tools\30.0.3"
|
||
|
|
$PLATFORM = "$SDK\platforms\android-30\android.jar"
|
||
|
|
$JDK = "C:\Program Files\Java\jdk1.8.0_202"
|
||
|
|
$ROOT = $PSScriptRoot
|
||
|
|
$WEB = Resolve-Path "$ROOT\..\..\web"
|
||
|
|
$OUT = "$ROOT\build"
|
||
|
|
|
||
|
|
$env:JAVA_HOME = $JDK
|
||
|
|
$env:Path = "$JDK\bin;$env:Path"
|
||
|
|
|
||
|
|
if (Test-Path $OUT) { Remove-Item -Recurse -Force $OUT }
|
||
|
|
New-Item -ItemType Directory -Force "$OUT\classes", "$OUT\dex", "$OUT\gen", "$OUT\assets\web" | Out-Null
|
||
|
|
|
||
|
|
Write-Host "[0/6] page + version"
|
||
|
|
Copy-Item -Recurse "$WEB\*" "$OUT\assets\web\"
|
||
|
|
@"
|
||
|
|
package st.silentmode.pithos;
|
||
|
|
final class BuildInfo { static final String VERSION = "$VERSION"; private BuildInfo() {} }
|
||
|
|
"@ | Set-Content -Encoding ASCII "$OUT\gen\BuildInfo.java"
|
||
|
|
$manifest = (Get-Content -Raw "$ROOT\AndroidManifest.xml") `
|
||
|
|
-replace 'android:versionCode="\d+"', "android:versionCode=`"$VERSION_CODE`"" `
|
||
|
|
-replace 'android:versionName="[^"]*"', "android:versionName=`"$VERSION`""
|
||
|
|
Set-Content -Encoding UTF8 "$OUT\AndroidManifest.xml" $manifest
|
||
|
|
|
||
|
|
Write-Host "[1/6] aapt2 compile+link"
|
||
|
|
& "$BT\aapt2.exe" compile --dir "$ROOT\res" -o "$OUT\res.zip"
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "aapt2 compile failed" }
|
||
|
|
& "$BT\aapt2.exe" link -o "$OUT\app-unsigned.apk" -I $PLATFORM --manifest "$OUT\AndroidManifest.xml" `
|
||
|
|
--java "$OUT\gen" --min-sdk-version 24 --target-sdk-version 30 -A "$OUT\assets" "$OUT\res.zip"
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "aapt2 link failed" }
|
||
|
|
|
||
|
|
Write-Host "[2/6] javac"
|
||
|
|
$sources = Get-ChildItem "$ROOT\src","$OUT\gen" -Recurse -Filter *.java | ForEach-Object { $_.FullName }
|
||
|
|
& "$JDK\bin\javac.exe" -source 1.8 -target 1.8 -encoding UTF-8 -Xlint:-options `
|
||
|
|
-bootclasspath $PLATFORM -classpath $PLATFORM -d "$OUT\classes" @sources
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "javac failed" }
|
||
|
|
|
||
|
|
Write-Host "[3/6] d8"
|
||
|
|
$classesDir = "$OUT\classes"
|
||
|
|
Push-Location $classesDir
|
||
|
|
$classes = Get-ChildItem -Recurse -Filter *.class | ForEach-Object { $_.FullName.Substring($classesDir.Length + 1) }
|
||
|
|
& "$BT\d8.bat" --release --min-api 24 --lib $PLATFORM --output "$OUT\dex" @classes
|
||
|
|
Pop-Location
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "d8 failed" }
|
||
|
|
|
||
|
|
Write-Host "[4/6] add classes.dex"
|
||
|
|
Push-Location "$OUT\dex"
|
||
|
|
& "$JDK\bin\jar.exe" uf "$OUT\app-unsigned.apk" classes.dex
|
||
|
|
Pop-Location
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "jar failed" }
|
||
|
|
|
||
|
|
Write-Host "[5/6] zipalign"
|
||
|
|
& "$BT\zipalign.exe" -f -p 4 "$OUT\app-unsigned.apk" "$OUT\app-aligned.apk"
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "zipalign failed" }
|
||
|
|
|
||
|
|
Write-Host "[6/6] sign"
|
||
|
|
if ($Release) {
|
||
|
|
# Generated once, then REUSED FOREVER: Android installs updates only when
|
||
|
|
# they are signed by the same key. Keep both files out of git, backed up.
|
||
|
|
$ks = "$ROOT\release.keystore"
|
||
|
|
$passFile = "$ROOT\release-keystore-password.txt"
|
||
|
|
if (-not (Test-Path $passFile)) { throw "missing $passFile (put the keystore password in it first)" }
|
||
|
|
$pass = (Get-Content $passFile -Raw).Trim()
|
||
|
|
if (-not (Test-Path $ks)) {
|
||
|
|
& "$JDK\bin\keytool.exe" -genkeypair -keystore $ks -storepass $pass -keypass $pass `
|
||
|
|
-alias pithos -keyalg RSA -keysize 4096 -validity 14000 -dname "CN=Pithos,O=Silent Mode"
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "keytool failed" }
|
||
|
|
Write-Host "NOTE: new release key created. BACK UP $ks and $passFile."
|
||
|
|
}
|
||
|
|
$apk = "$OUT\pithos-v$VERSION.apk"
|
||
|
|
& "$BT\apksigner.bat" sign --ks $ks --ks-key-alias pithos --ks-pass "pass:$pass" --key-pass "pass:$pass" --out $apk "$OUT\app-aligned.apk"
|
||
|
|
} else {
|
||
|
|
$ks = "$ROOT\debug.keystore"
|
||
|
|
if (-not (Test-Path $ks)) {
|
||
|
|
& "$JDK\bin\keytool.exe" -genkeypair -keystore $ks -storepass android -keypass android `
|
||
|
|
-alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 -dname "CN=Android Debug,O=Android,C=US"
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "keytool failed" }
|
||
|
|
}
|
||
|
|
$apk = "$OUT\pithos-debug.apk"
|
||
|
|
& "$BT\apksigner.bat" sign --ks $ks --ks-pass pass:android --key-pass pass:android --out $apk "$OUT\app-aligned.apk"
|
||
|
|
}
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "apksigner failed" }
|
||
|
|
Write-Host "OK -> $apk"
|