winget 裝的 Inno Setup 6 在 'C:\Program Files (x86)\Inno Setup 6\', 不在 PATH 裡,MSYS2 bash 找不到 iscc.exe 導致 make exe 失敗。 改由 bootstrap 主動偵測安裝路徑並 export 進 bash session PATH。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
156 lines
5.5 KiB
PowerShell
156 lines
5.5 KiB
PowerShell
# visionA-local — Windows 10/11 x86_64 一鍵 build
|
||
#
|
||
# 使用方式(PowerShell 以「系統管理員」開啟):
|
||
# git clone https://github.com/jim800121/visionA.git
|
||
# cd visionA\local-tool
|
||
# powershell -ExecutionPolicy Bypass -File scripts\bootstrap-windows.ps1
|
||
#
|
||
# 環境變數:
|
||
# $env:VISIONA_TARGET 預設 exe,可設 wails-windows / payload-windows
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
|
||
$Target = if ($env:VISIONA_TARGET) { $env:VISIONA_TARGET } else { 'exe' }
|
||
|
||
function Log($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
|
||
function Fail($msg) { Write-Host "!!! $msg" -ForegroundColor Red; exit 1 }
|
||
|
||
# 必須以系統管理員身份執行(winget 需要)
|
||
$isAdmin = ([Security.Principal.WindowsPrincipal] `
|
||
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
|
||
[Security.Principal.WindowsBuiltInRole] 'Administrator')
|
||
if (-not $isAdmin) { Fail '請以系統管理員身份執行 PowerShell 再跑此腳本' }
|
||
|
||
if (-not (Test-Path 'Makefile') -or -not (Test-Path 'visiona-local')) {
|
||
Fail '請先 cd 到 local-tool\ 目錄再執行此腳本'
|
||
}
|
||
|
||
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
|
||
Fail 'winget 未安裝。請先從 Microsoft Store 安裝「App Installer」'
|
||
}
|
||
|
||
function Ensure-Winget($id) {
|
||
$installed = winget list --id $id -e 2>$null | Select-String $id
|
||
if (-not $installed) {
|
||
Log "安裝 $id"
|
||
winget install -e --id $id --accept-source-agreements --accept-package-agreements
|
||
} else {
|
||
Log "$id 已安裝,跳過"
|
||
}
|
||
}
|
||
|
||
Log '[1/4] 安裝系統套件'
|
||
Ensure-Winget 'Git.Git'
|
||
Ensure-Winget 'GoLang.Go'
|
||
Ensure-Winget 'OpenJS.NodeJS.LTS'
|
||
Ensure-Winget 'Python.Python.3.12'
|
||
Ensure-Winget 'JRSoftware.InnoSetup'
|
||
Ensure-Winget 'MSYS2.MSYS2'
|
||
|
||
# 重新載入 PATH(winget 裝完目前 session 拿不到)
|
||
$env:Path = [System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + `
|
||
[System.Environment]::GetEnvironmentVariable('Path','User')
|
||
$env:Path += ";$HOME\go\bin;C:\msys64\usr\bin;C:\msys64\mingw64\bin"
|
||
|
||
Log '[2/4] 安裝 pnpm'
|
||
if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) {
|
||
npm i -g pnpm
|
||
}
|
||
|
||
Log '[3/4] 安裝 Wails CLI + 確認 MSYS2 make'
|
||
if (-not (Get-Command wails -ErrorAction SilentlyContinue)) {
|
||
go install github.com/wailsapp/wails/v2/cmd/wails@latest
|
||
}
|
||
wails doctor
|
||
if (-not (Test-Path 'C:\msys64\usr\bin\make.exe')) {
|
||
Log '安裝 MSYS2 make'
|
||
& 'C:\msys64\usr\bin\bash.exe' -lc 'pacman -Sy --noconfirm make'
|
||
}
|
||
|
||
Log "[4/4] 開始 build(target=$Target)"
|
||
Log '⚠️ ffmpeg 使用 GPL build,需設定 VISIONA_ALLOW_GPL_FFMPEG=1'
|
||
|
||
# 讓 MSYS2 bash 繼承 Windows PATH(才找得到 go / pnpm / python / wails)
|
||
$env:MSYS2_PATH_TYPE = 'inherit'
|
||
$env:CHERE_INVOKING = '1'
|
||
|
||
# 找真實的 Python(避開 Microsoft Store 的 WindowsApps stub)
|
||
$realPython = $null
|
||
$pyCandidates = @(
|
||
"$env:LOCALAPPDATA\Programs\Python\Python312\python.exe",
|
||
"$env:LOCALAPPDATA\Programs\Python\Python313\python.exe",
|
||
"$env:ProgramFiles\Python312\python.exe",
|
||
"$env:ProgramFiles\Python313\python.exe"
|
||
)
|
||
foreach ($p in $pyCandidates) {
|
||
if (Test-Path $p) { $realPython = $p; break }
|
||
}
|
||
if (-not $realPython) {
|
||
# 試 py launcher
|
||
$pyLauncher = Get-Command py -ErrorAction SilentlyContinue
|
||
if ($pyLauncher) { $realPython = 'py -3' }
|
||
}
|
||
if (-not $realPython) {
|
||
Fail '找不到真實 Python(winget 可能沒裝成功,或 PATH 沒更新)。請重開 PowerShell 再試一次'
|
||
}
|
||
Log "偵測到 Python: $realPython"
|
||
|
||
# 把 Windows 路徑轉成 MSYS2 bash 能吃的格式
|
||
function Convert-ToMsysPath($winPath) {
|
||
if ($winPath -match '^[A-Za-z]:\\') {
|
||
return '/' + $winPath.Substring(0,1).ToLower() + '/' + ($winPath.Substring(3) -replace '\\','/')
|
||
}
|
||
return $winPath
|
||
}
|
||
$msysPython = Convert-ToMsysPath $realPython
|
||
|
||
# 找 Inno Setup Compiler (iscc.exe),winget 裝在 Program Files (x86) 不在 PATH 裡
|
||
$isccCandidates = @(
|
||
"${env:ProgramFiles(x86)}\Inno Setup 6\iscc.exe",
|
||
"$env:ProgramFiles\Inno Setup 6\iscc.exe",
|
||
"${env:ProgramFiles(x86)}\Inno Setup 5\iscc.exe"
|
||
)
|
||
$isccPath = $null
|
||
foreach ($p in $isccCandidates) {
|
||
if ($p -and (Test-Path $p)) { $isccPath = $p; break }
|
||
}
|
||
if ($isccPath) {
|
||
Log "偵測到 Inno Setup: $isccPath"
|
||
$msysIsccDir = Convert-ToMsysPath (Split-Path $isccPath -Parent)
|
||
} else {
|
||
Log 'WARN: 找不到 Inno Setup(iscc.exe),make exe 步驟會失敗'
|
||
$msysIsccDir = $null
|
||
}
|
||
|
||
# Makefile 需要 bash + make,透過 MSYS2 bash 執行
|
||
# 將 Windows 路徑 C:\foo\bar 轉成 MSYS2 路徑 /c/foo/bar
|
||
$projectPath = (Get-Location).Path
|
||
$msysPath = '/' + $projectPath.Substring(0,1).ToLower() + '/' + `
|
||
($projectPath.Substring(3) -replace '\\','/')
|
||
|
||
$bashParts = @(
|
||
"cd '$msysPath'",
|
||
'export VISIONA_ALLOW_GPL_FFMPEG=1',
|
||
"export VISIONA_PYTHON='$msysPython'"
|
||
)
|
||
if ($msysIsccDir) {
|
||
$bashParts += "export PATH=`"$msysIsccDir`":`$PATH"
|
||
}
|
||
$bashParts += 'make vendor-python-windows vendor-wheels-windows vendor-ffmpeg-windows vendor-ytdlp-windows'
|
||
$bashParts += 'make payload-windows'
|
||
|
||
switch ($Target) {
|
||
'payload-windows' { }
|
||
'wails-windows' { $bashParts += 'make wails-windows' }
|
||
default { $bashParts += 'make wails-windows'; $bashParts += 'make exe' }
|
||
}
|
||
|
||
$bashCmd = $bashParts -join ' && '
|
||
|
||
& 'C:\msys64\usr\bin\bash.exe' -lc $bashCmd
|
||
if ($LASTEXITCODE -ne 0) { Fail "build 失敗,exit code=$LASTEXITCODE" }
|
||
|
||
Log '完成 ✅'
|
||
Log "產出位置:$(Join-Path (Get-Location) 'dist')"
|
||
Get-ChildItem dist -ErrorAction SilentlyContinue | Format-Table Name, Length
|