220 lines
7.5 KiB
PowerShell
220 lines
7.5 KiB
PowerShell
|
|
|
||
|
|
[CmdletBinding()]
|
||
|
|
param(
|
||
|
|
[string]$Url = '',
|
||
|
|
[switch]$ForceRefresh
|
||
|
|
)
|
||
|
|
|
||
|
|
$ErrorActionPreference = 'Stop'
|
||
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||
|
|
$MdkVersion = '0.37.0'
|
||
|
|
|
||
|
|
function Test-SevenZipArchive {
|
||
|
|
param([string]$Path)
|
||
|
|
if (-not (Test-Path $Path)) { return $false }
|
||
|
|
$stream = [System.IO.File]::OpenRead($Path)
|
||
|
|
try {
|
||
|
|
if ($stream.Length -lt 6) { return $false }
|
||
|
|
$buffer = New-Object byte[] 6
|
||
|
|
[void]$stream.Read($buffer, 0, 6)
|
||
|
|
} finally {
|
||
|
|
$stream.Dispose()
|
||
|
|
}
|
||
|
|
$magic = 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C
|
||
|
|
for ($i = 0; $i -lt 6; $i++) {
|
||
|
|
if ($buffer[$i] -ne $magic[$i]) { return $false }
|
||
|
|
}
|
||
|
|
return $true
|
||
|
|
}
|
||
|
|
|
||
|
|
function Resolve-CMakeExecutable {
|
||
|
|
$pathCommand = Get-Command 'cmake.exe' -ErrorAction SilentlyContinue
|
||
|
|
if ($pathCommand) {
|
||
|
|
return $pathCommand.Source
|
||
|
|
}
|
||
|
|
|
||
|
|
$visualStudioInstallations = @()
|
||
|
|
$vswherePath = Join-Path ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
|
||
|
|
if (Test-Path $vswherePath) {
|
||
|
|
$visualStudioInstallations += @(
|
||
|
|
& $vswherePath -products '*' -property installationPath 2>$null
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($programFilesRoot in @($Env:ProgramFiles, ${Env:ProgramFiles(x86)})) {
|
||
|
|
if (-not $programFilesRoot) { continue }
|
||
|
|
foreach ($edition in @('BuildTools', 'Community', 'Professional', 'Enterprise')) {
|
||
|
|
$visualStudioInstallations += Join-Path $programFilesRoot "Microsoft Visual Studio\2022\$edition"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($installationPath in $visualStudioInstallations | Select-Object -Unique) {
|
||
|
|
if (-not $installationPath) { continue }
|
||
|
|
$candidate = Join-Path $installationPath 'Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe'
|
||
|
|
if (Test-Path $candidate) {
|
||
|
|
return $candidate
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$androidSdkRoots = @(
|
||
|
|
$Env:ANDROID_SDK_ROOT,
|
||
|
|
$Env:ANDROID_HOME,
|
||
|
|
$(if ($Env:LOCALAPPDATA) { Join-Path $Env:LOCALAPPDATA 'Android\sdk' })
|
||
|
|
) | Where-Object { $_ -and (Test-Path $_) } | Select-Object -Unique
|
||
|
|
|
||
|
|
foreach ($androidSdkRoot in $androidSdkRoots) {
|
||
|
|
$cmakeRoot = Join-Path $androidSdkRoot 'cmake'
|
||
|
|
if (-not (Test-Path $cmakeRoot)) { continue }
|
||
|
|
$candidate = Get-ChildItem $cmakeRoot -Directory -ErrorAction SilentlyContinue |
|
||
|
|
Sort-Object Name -Descending |
|
||
|
|
ForEach-Object { Join-Path $_.FullName 'bin\cmake.exe' } |
|
||
|
|
Where-Object { Test-Path $_ } |
|
||
|
|
Select-Object -First 1
|
||
|
|
if ($candidate) {
|
||
|
|
return $candidate
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $null
|
||
|
|
}
|
||
|
|
|
||
|
|
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
||
|
|
Set-Location $ProjectRoot
|
||
|
|
|
||
|
|
$PackageConfig = Join-Path $ProjectRoot '.dart_tool\package_config.json'
|
||
|
|
if (-not (Test-Path $PackageConfig)) {
|
||
|
|
throw "package_config.json not found: $PackageConfig (run flutter pub get first)"
|
||
|
|
}
|
||
|
|
|
||
|
|
$config = Get-Content $PackageConfig -Raw | ConvertFrom-Json
|
||
|
|
$fvp = $config.packages | Where-Object { $_.name -eq 'fvp' } | Select-Object -First 1
|
||
|
|
if (-not $fvp) {
|
||
|
|
throw 'Package fvp not found in .dart_tool/package_config.json'
|
||
|
|
}
|
||
|
|
|
||
|
|
$fvpRoot = [Uri]$fvp.rootUri
|
||
|
|
if (-not $fvpRoot.IsFile) {
|
||
|
|
throw "Unsupported fvp rootUri: $($fvp.rootUri)"
|
||
|
|
}
|
||
|
|
|
||
|
|
$fvpWindowsDir = Join-Path $fvpRoot.LocalPath 'windows'
|
||
|
|
if (-not (Test-Path $fvpWindowsDir)) {
|
||
|
|
throw "fvp windows directory not found: $fvpWindowsDir"
|
||
|
|
}
|
||
|
|
|
||
|
|
$sdkDir = Join-Path $fvpWindowsDir 'mdk-sdk'
|
||
|
|
$sdkVersionMarkerPath = Join-Path $sdkDir '.smplayer-mdk-version'
|
||
|
|
$archivePath = Join-Path $fvpWindowsDir "mdk-sdk-windows-x64-v$MdkVersion-vs2026.7z"
|
||
|
|
|
||
|
|
if ($ForceRefresh) {
|
||
|
|
Write-Host "==> Force refreshing fvp mdk-sdk v$MdkVersion" -ForegroundColor Yellow
|
||
|
|
if (Test-Path $sdkDir) {
|
||
|
|
Remove-Item $sdkDir -Recurse -Force
|
||
|
|
}
|
||
|
|
if (Test-Path $archivePath) {
|
||
|
|
Remove-Item $archivePath -Force
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Test-Path $sdkDir) {
|
||
|
|
$installedMdkVersion = if (Test-Path $sdkVersionMarkerPath) {
|
||
|
|
(Get-Content $sdkVersionMarkerPath -Raw).Trim()
|
||
|
|
} else {
|
||
|
|
''
|
||
|
|
}
|
||
|
|
if ($installedMdkVersion -eq $MdkVersion) {
|
||
|
|
Write-Host "==> fvp mdk-sdk v$MdkVersion already exists: $sdkDir" -ForegroundColor Green
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
$displayVersion = if ($installedMdkVersion) { $installedMdkVersion } else { 'unknown' }
|
||
|
|
Write-Host "==> Replacing cached mdk-sdk v$displayVersion with v$MdkVersion" -ForegroundColor Yellow
|
||
|
|
Remove-Item $sdkDir -Recurse -Force
|
||
|
|
}
|
||
|
|
|
||
|
|
$candidates = @()
|
||
|
|
if ($Url) {
|
||
|
|
$candidates += $Url
|
||
|
|
} else {
|
||
|
|
$candidates += "https://github.com/wang-bin/mdk-sdk/releases/download/v$MdkVersion/mdk-sdk-windows-x64-vs2026.7z"
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((Test-Path $archivePath) -and -not (Test-SevenZipArchive $archivePath)) {
|
||
|
|
Write-Host "==> Cached archive is not a valid 7z, removing: $archivePath" -ForegroundColor Yellow
|
||
|
|
Remove-Item $archivePath -Force
|
||
|
|
}
|
||
|
|
|
||
|
|
if (-not (Test-Path $archivePath)) {
|
||
|
|
$downloaded = $false
|
||
|
|
:outer foreach ($candidate in $candidates) {
|
||
|
|
$maxAttempts = 3
|
||
|
|
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
|
||
|
|
Write-Host "==> Downloading mdk-sdk (attempt $attempt/$maxAttempts): $candidate" -ForegroundColor Cyan
|
||
|
|
try {
|
||
|
|
Invoke-WebRequest -Uri $candidate -OutFile $archivePath `
|
||
|
|
-UseBasicParsing -MaximumRedirection 10 `
|
||
|
|
-UserAgent 'Mozilla/5.0' -TimeoutSec 120
|
||
|
|
} catch {
|
||
|
|
Write-Host " download failed: $($_.Exception.Message)" -ForegroundColor Yellow
|
||
|
|
if (Test-Path $archivePath) { Remove-Item $archivePath -Force }
|
||
|
|
if ($attempt -lt $maxAttempts) {
|
||
|
|
$delay = $attempt * 10
|
||
|
|
Write-Host " retrying in ${delay}s..." -ForegroundColor Yellow
|
||
|
|
Start-Sleep -Seconds $delay
|
||
|
|
}
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if (Test-SevenZipArchive $archivePath) {
|
||
|
|
$downloaded = $true
|
||
|
|
break outer
|
||
|
|
}
|
||
|
|
$size = (Get-Item $archivePath).Length
|
||
|
|
Write-Host " not a valid 7z archive (size=$size bytes), trying next" -ForegroundColor Yellow
|
||
|
|
Remove-Item $archivePath -Force
|
||
|
|
break # bad content, skip retries for this URL
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (-not $downloaded) {
|
||
|
|
throw "Failed to download a valid mdk-sdk archive from: $($candidates -join ', ')"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host "==> Extracting mdk-sdk to: $fvpWindowsDir" -ForegroundColor Cyan
|
||
|
|
|
||
|
|
$sevenZipCommand = Get-Command '7z.exe' -ErrorAction SilentlyContinue
|
||
|
|
$sevenZip = if ($sevenZipCommand) {
|
||
|
|
$sevenZipCommand.Source
|
||
|
|
} else {
|
||
|
|
@(
|
||
|
|
"$Env:ProgramFiles\7-Zip\7z.exe",
|
||
|
|
"${Env:ProgramFiles(x86)}\7-Zip\7z.exe"
|
||
|
|
) | Where-Object { Test-Path $_ } | Select-Object -First 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($sevenZip) {
|
||
|
|
& $sevenZip x '-y' "-o$fvpWindowsDir" $archivePath
|
||
|
|
} else {
|
||
|
|
$cmakeExecutable = Resolve-CMakeExecutable
|
||
|
|
if (-not $cmakeExecutable) {
|
||
|
|
throw 'Neither 7-Zip nor CMake was found. Install the Visual Studio C++ CMake tools or 7-Zip, then retry.'
|
||
|
|
}
|
||
|
|
Write-Host "==> Using CMake: $cmakeExecutable" -ForegroundColor DarkGray
|
||
|
|
Push-Location $fvpWindowsDir
|
||
|
|
try {
|
||
|
|
& $cmakeExecutable -E tar xvf $archivePath
|
||
|
|
} finally {
|
||
|
|
Pop-Location
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($LASTEXITCODE -ne 0) {
|
||
|
|
throw "Failed to extract mdk-sdk (exit $LASTEXITCODE)"
|
||
|
|
}
|
||
|
|
|
||
|
|
if (-not (Test-Path $sdkDir)) {
|
||
|
|
throw "mdk-sdk not found after extraction: $sdkDir"
|
||
|
|
}
|
||
|
|
|
||
|
|
Set-Content -Path $sdkVersionMarkerPath -Value $MdkVersion -NoNewline
|
||
|
|
Write-Host "==> fvp mdk-sdk v$MdkVersion ready: $sdkDir" -ForegroundColor Green
|