fix(local-tool): 繞過 Windows Store 的 python stub

- Makefile:vendor-wheels-windows / vendor-ffmpeg-windows 改用迴圈偵測真實 python
  排除 WindowsApps 路徑下的 Store alias stub,優先使用 VISIONA_PYTHON 環境變數
- Makefile:vendor-ffmpeg-windows 解壓完驗證檔案存在,失敗時 exit 1 而非靜默
- bootstrap-windows.ps1:主動找 winget 裝的真實 python.exe(LOCALAPPDATA / Program Files / py launcher),
  轉成 MSYS2 路徑後以 VISIONA_PYTHON 傳給 Makefile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jim800121chen 2026-04-12 02:11:16 +08:00
parent 071964bddd
commit a66fd5665b
2 changed files with 54 additions and 13 deletions

View File

@ -234,16 +234,18 @@ vendor-wheels-windows: ## 同步 Windows wheels → vendor/wheels/windows/
cp visiona-local/wheels/windows/*.whl vendor/wheels/windows/ 2>/dev/null || true; \
fi
@echo "==> 從 PyPI 下載公開相依 wheels (cp312, win_amd64)..."
@PIP_CMD=$$(command -v pip3 || command -v pip); \
if [ -z "$$PIP_CMD" ]; then \
PY=$$(command -v python3 || command -v python || command -v py); \
if [ -n "$$PY" ]; then PIP_CMD="$$PY -m pip"; fi; \
fi; \
if [ -z "$$PIP_CMD" ]; then \
echo "WARN: 找不到 pip / python跳過 PyPI 下載(僅使用內部 wheels"; \
@PY=""; \
for candidate in "$$VISIONA_PYTHON" "py -3" python3 python; do \
[ -z "$$candidate" ] && continue; \
resolved=$$(command -v $${candidate%% *} 2>/dev/null || true); \
case "$$resolved" in *WindowsApps*) continue ;; esac; \
if $$candidate --version >/dev/null 2>&1; then PY="$$candidate"; break; fi; \
done; \
if [ -z "$$PY" ]; then \
echo "WARN: 找不到真實 pythonWindowsApps stub 不算),跳過 PyPI 下載(僅使用內部 wheels"; \
else \
echo "==> 使用 $$PIP_CMD"; \
$$PIP_CMD download \
echo "==> 使用 $$PY -m pip"; \
$$PY -m pip download \
--only-binary=:all: \
--platform win_amd64 \
--python-version 3.12 \
@ -263,14 +265,22 @@ vendor-ffmpeg-windows: ## 下載 ffmpeg Windows static build → vendor/ffmpeg/w
echo "==> 下載 ffmpeg Windows build from BtbN..."; \
echo "!! WARNING: BtbN 為 GPL buildlicense 由 PM 最終確認 !!"; \
curl -fL -o /tmp/ffmpeg-win.zip "$(FFMPEG_URL_WINDOWS)"; \
PY=$$(command -v python3 || command -v python || command -v py); \
if [ -z "$$PY" ]; then echo "ERROR: 需要 python 來解壓 zip"; exit 1; fi; \
$$PY -c "import zipfile, os, shutil; z=zipfile.ZipFile('/tmp/ffmpeg-win.zip'); \
PY=""; \
for candidate in "$$VISIONA_PYTHON" "py -3" python3 python; do \
[ -z "$$candidate" ] && continue; \
resolved=$$(command -v $${candidate%% *} 2>/dev/null || true); \
case "$$resolved" in *WindowsApps*) continue ;; esac; \
if $$candidate --version >/dev/null 2>&1; then PY="$$candidate"; break; fi; \
done; \
if [ -z "$$PY" ]; then echo "ERROR: 需要真實 python 來解壓 zipWindowsApps stub 無法使用)"; exit 1; fi; \
echo "==> 使用 $$PY 解壓 ffmpeg zip"; \
$$PY -c "import zipfile, shutil; z=zipfile.ZipFile('/tmp/ffmpeg-win.zip'); \
members=[n for n in z.namelist() if n.endswith('/bin/ffmpeg.exe')]; \
assert members, 'ffmpeg.exe not found in zip'; \
src=z.open(members[0]); dst=open('vendor/ffmpeg/windows/ffmpeg.exe','wb'); \
shutil.copyfileobj(src, dst); src.close(); dst.close(); z.close()"; \
shutil.copyfileobj(src, dst); src.close(); dst.close(); z.close()" || { echo "ERROR: python 解壓失敗"; exit 1; }; \
rm -f /tmp/ffmpeg-win.zip; \
[ -f vendor/ffmpeg/windows/ffmpeg.exe ] || { echo "ERROR: ffmpeg.exe 沒被寫出"; exit 1; }; \
echo "==> ffmpeg.exe 大小:$$(du -sh vendor/ffmpeg/windows/ffmpeg.exe | cut -f1)"; \
fi

View File

@ -74,6 +74,36 @@ Log '⚠️ ffmpeg 使用 GPL build需設定 VISIONA_ALLOW_GPL_FFMPEG=1'
$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 '找不到真實 Pythonwinget 可能沒裝成功,或 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
# Makefile 需要 bash + make透過 MSYS2 bash 執行
# 將 Windows 路徑 C:\foo\bar 轉成 MSYS2 路徑 /c/foo/bar
$projectPath = (Get-Location).Path
@ -83,6 +113,7 @@ $msysPath = '/' + $projectPath.Substring(0,1).ToLower() + '/' + `
$bashParts = @(
"cd '$msysPath'",
'export VISIONA_ALLOW_GPL_FFMPEG=1',
"export VISIONA_PYTHON='$msysPython'",
'make vendor-python-windows vendor-wheels-windows vendor-ffmpeg-windows vendor-ytdlp-windows',
'make payload-windows'
)