Files
story/firmware/echoear-platform-agent/tools/flash-app/build-app.ps1
T

48 lines
3.2 KiB
PowerShell
Raw Normal View History

param(
[string]$OutputDirectory = (Join-Path $PSScriptRoot 'dist'),
[string]$BuildDirectory = (Join-Path $PSScriptRoot '..\..\build')
)
$ErrorActionPreference = 'Stop'
$firmwareRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..'))
$sourcePath = Join-Path $PSScriptRoot 'EchoEarFlasher.cs'
$compiler = Join-Path $env:WINDIR 'Microsoft.NET\Framework64\v4.0.30319\csc.exe'
if (-not (Test-Path -LiteralPath $compiler)) { throw 'Windows .NET Framework C# compiler is required.' }
$outputPath = [IO.Path]::GetFullPath($OutputDirectory)
$buildPath = (Resolve-Path -LiteralPath $BuildDirectory).Path
$manifestPath = Join-Path $buildPath 'flasher_args.json'
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
if ($manifest.extra_esptool_args.chip -ne 'esp32s3') { throw 'The build must target ESP32-S3.' }
$null = New-Item -ItemType Directory -Path $outputPath -Force
$enginePath = Join-Path $outputPath 'engine'
$packageBuild = Join-Path $outputPath 'firmware-build'
$null = New-Item -ItemType Directory -Path $enginePath -Force
$null = New-Item -ItemType Directory -Path $packageBuild -Force
# Allowlist only application code; never copy private credentials or backups.
foreach ($name in @('ble_factory.py', 'device_prepare.py', 'device_flash.py', 'flash_app_bridge.py')) {
Copy-Item -LiteralPath (Join-Path $firmwareRoot "tools\$name") -Destination (Join-Path $enginePath $name) -Force
}
Copy-Item -LiteralPath $manifestPath -Destination (Join-Path $packageBuild 'flasher_args.json') -Force
foreach ($entry in $manifest.flash_files.PSObject.Properties) {
$relative = [string]$entry.Value
if ([IO.Path]::IsPathRooted($relative) -or ($relative -split '[/\\]') -contains '..') { throw 'Unsafe image path.' }
$imagePath = [IO.Path]::GetFullPath((Join-Path $buildPath $relative))
if (-not $imagePath.StartsWith($buildPath.TrimEnd('\') + '\', [StringComparison]::OrdinalIgnoreCase)) { throw 'Image escapes build directory.' }
$target = Join-Path $packageBuild $relative
$null = New-Item -ItemType Directory -Path (Split-Path -Parent $target) -Force
Copy-Item -LiteralPath $imagePath -Destination $target -Force
}
$executable = Join-Path $outputPath 'EchoEarFlasher.exe'
& $compiler /nologo /target:winexe /platform:x64 /optimize+ /codepage:65001 `
/r:System.dll /r:System.Core.dll /r:System.Drawing.dll /r:System.Windows.Forms.dll /r:System.Web.Extensions.dll `
"/out:$executable" $sourcePath
if ($LASTEXITCODE -ne 0) { throw 'Application compilation failed.' }
$guide = Join-Path $PSScriptRoot '使用说明.txt'
if (Test-Path -LiteralPath $guide) { Copy-Item -LiteralPath $guide -Destination $outputPath -Force }
$records = Get-ChildItem -LiteralPath $outputPath -File -Recurse | Where-Object { $_.FullName -ne (Join-Path $outputPath 'package-files.json') } | ForEach-Object {
[ordered]@{ file = $_.FullName.Substring($outputPath.Length + 1); size = $_.Length; sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() }
}
[ordered]@{ application = 'EchoEar 烧录助手'; hardware = 'ESP32-S3 / 16MB'; built_at = (Get-Date).ToString('o'); files = @($records) } |
ConvertTo-Json -Depth 6 | Set-Content -LiteralPath (Join-Path $outputPath 'package-files.json') -Encoding UTF8
Write-Output "Built: $executable"