Install latest Android SDK toolchain packages

This commit is contained in:
2026-06-05 13:12:30 +02:00
parent e731c06330
commit 8a4ca331cb
7 changed files with 313 additions and 29 deletions

View File

@@ -41,10 +41,154 @@ function Get-LatestAndroidSdkPackageDirectory {
return $packages[0]
}
function Get-AndroidSdkManagerCommand {
param([Parameter(Mandatory=$true)][string]$SdkRoot)
$candidates = @(
(Join-Path $SdkRoot "cmdline-tools\latest\bin\sdkmanager.bat"),
(Join-Path $SdkRoot "cmdline-tools\latest\bin\sdkmanager.exe"),
(Join-Path $SdkRoot "tools\bin\sdkmanager.bat"),
(Join-Path $SdkRoot "tools\bin\sdkmanager.exe")
)
$cmdlineToolsRoot = Join-Path $SdkRoot "cmdline-tools"
if (Test-Path -LiteralPath $cmdlineToolsRoot -PathType Container) {
$toolVersions = @(Get-ChildItem -LiteralPath $cmdlineToolsRoot -Directory |
Where-Object { $_.Name -ne "latest" } |
Sort-Object {
try { [version]$_.Name } catch { [version]"0.0" }
} -Descending)
foreach ($toolVersion in $toolVersions) {
$candidates += (Join-Path $toolVersion.FullName "bin\sdkmanager.bat")
$candidates += (Join-Path $toolVersion.FullName "bin\sdkmanager.exe")
}
}
foreach ($candidate in $candidates) {
if ($candidate -and (Test-Path -LiteralPath $candidate -PathType Leaf)) {
return (Resolve-Path -LiteralPath $candidate).Path
}
}
$pathCommand = Get-Command "sdkmanager" -ErrorAction SilentlyContinue
if ($pathCommand) {
return $pathCommand.Source
}
return $null
}
function Get-LatestAvailableAndroidSdkPackageVersion {
param(
[Parameter(Mandatory=$true)][string]$SdkRoot,
[Parameter(Mandatory=$true)][string]$SdkManagerCommand,
[Parameter(Mandatory=$true)][string]$PackageName
)
$output = @(& $SdkManagerCommand "--sdk_root=$SdkRoot" "--list" 2>&1)
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) {
throw "sdkmanager --list failed while checking $PackageName packages: $($output -join [Environment]::NewLine)"
}
$versions = @()
$pattern = "^\s*$([regex]::Escape($PackageName));([0-9]+(?:\.[0-9]+)*)\s*\|"
foreach ($line in $output) {
$text = $line.ToString()
if ($text -match $pattern) {
$versions += $Matches[1]
}
}
if ($versions.Count -eq 0) {
return $null
}
return @($versions | Sort-Object { [version]$_ } -Descending | Select-Object -First 1)[0]
}
function Install-AndroidSdkPackage {
param(
[Parameter(Mandatory=$true)][string]$SdkRoot,
[Parameter(Mandatory=$true)][string]$SdkManagerCommand,
[Parameter(Mandatory=$true)][string]$PackageId
)
$licenseInput = ("y`n" * 100)
$output = @($licenseInput | & $SdkManagerCommand "--sdk_root=$SdkRoot" "--install" $PackageId 2>&1)
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) {
throw "sdkmanager failed to install $PackageId with exit code ${exitCode}: $($output -join [Environment]::NewLine)"
}
}
function Ensure-LatestAndroidSdkPackageDirectory {
param(
[Parameter(Mandatory=$true)][string]$SdkRoot,
[Parameter(Mandatory=$true)][string]$PackageName,
[string]$SdkManagerCommand
)
$installedBefore = $null
try {
$installedBefore = Get-LatestAndroidSdkPackageDirectory -SdkRoot $SdkRoot -PackageName $PackageName
} catch {
$installedBefore = $null
}
$availableVersion = $null
$action = "using-installed"
if ($SdkManagerCommand) {
$availableVersion = Get-LatestAvailableAndroidSdkPackageVersion `
-SdkRoot $SdkRoot `
-SdkManagerCommand $SdkManagerCommand `
-PackageName $PackageName
$installedVersion = if ($installedBefore) { [version]$installedBefore.Name } else { $null }
$availableParsed = if ($availableVersion) { [version]$availableVersion } else { $null }
if ($availableParsed -and (!$installedVersion -or $availableParsed -gt $installedVersion)) {
Install-AndroidSdkPackage `
-SdkRoot $SdkRoot `
-SdkManagerCommand $SdkManagerCommand `
-PackageId "$PackageName;$availableVersion"
$action = "installed-latest-available"
} elseif ($availableParsed) {
$action = "already-latest-available"
} else {
$action = "available-version-not-listed"
}
} elseif (!$installedBefore) {
throw "No installed Android SDK package versions found under $(Join-Path $SdkRoot $PackageName), and sdkmanager was not found."
}
$selected = Get-LatestAndroidSdkPackageDirectory -SdkRoot $SdkRoot -PackageName $PackageName
return [ordered]@{
directory = $selected
update = [ordered]@{
package = $PackageName
installedVersionBefore = if ($installedBefore) { $installedBefore.Name } else { $null }
availableVersion = $availableVersion
selectedVersion = $selected.Name
action = $action
}
}
}
function Set-AndroidSdkToolchainEnvironment {
$sdkRoot = Get-AndroidSdkRoot
$ndk = Get-LatestAndroidSdkPackageDirectory -SdkRoot $sdkRoot -PackageName "ndk"
$cmake = Get-LatestAndroidSdkPackageDirectory -SdkRoot $sdkRoot -PackageName "cmake"
$sdkManagerCommand = Get-AndroidSdkManagerCommand -SdkRoot $sdkRoot
$ndkSelection = Ensure-LatestAndroidSdkPackageDirectory `
-SdkRoot $sdkRoot `
-PackageName "ndk" `
-SdkManagerCommand $sdkManagerCommand
$cmakeSelection = Ensure-LatestAndroidSdkPackageDirectory `
-SdkRoot $sdkRoot `
-PackageName "cmake" `
-SdkManagerCommand $sdkManagerCommand
$ndk = $ndkSelection.directory
$cmake = $cmakeSelection.directory
$cmakeCommand = Join-Path $cmake.FullName "bin\cmake.exe"
if (!(Test-Path -LiteralPath $cmakeCommand -PathType Leaf)) {
@@ -58,6 +202,8 @@ function Set-AndroidSdkToolchainEnvironment {
return [ordered]@{
sdkRoot = $sdkRoot
sdkManagerCommand = $sdkManagerCommand
packageUpdates = @($ndkSelection.update, $cmakeSelection.update)
ndkVersion = $ndk.Name
ndkPath = $ndk.FullName
cmakeVersion = $cmake.Name