fix(audio): offline mix limiter -3dBFS, 2-stage normalize (-14 LUFS + hard peak -1 dBTP), OGG export
This commit is contained in:
+152
-76
@@ -1,95 +1,171 @@
|
||||
# build_windows.ps1 - ONE-COMMAND build: daw_engine.exe (PyInstaller) + Tauri v2 (NSIS + MSI)
|
||||
# Chay tren Windows: powershell -ExecutionPolicy Bypass -File build_windows.ps1
|
||||
# LUU Y: file nay chi dung ky tu ASCII (khong dau, khong em-dash) - PowerShell 5.1
|
||||
# doc .ps1 khong BOM theo ANSI, ky tu Unicode bi hong -> "String is missing terminator".
|
||||
# build_windows.ps1 - ONE-COMMAND build: frontend + native bridge + engine + Tauri (NSIS + MSI)
|
||||
#
|
||||
# powershell -ExecutionPolicy Bypass -File build_windows.ps1 # FULL (tat ca)
|
||||
# powershell -ExecutionPolicy Bypass -File build_windows.ps1 -Frontend # chi bundle JS + sync static
|
||||
# powershell -ExecutionPolicy Bypass -File build_windows.ps1 -Bridge # chi build native bridge + sync binaries
|
||||
# powershell -ExecutionPolicy Bypass -File build_windows.ps1 -Engine # chi build engine + sync resources
|
||||
# powershell -ExecutionPolicy Bypass -File build_windows.ps1 -Tauri # chi build installer Tauri
|
||||
# ... -SkipPip -SkipNpm # bo qua cai dependency
|
||||
#
|
||||
# Moi mode TU DONG copy output vao dung vi tri (dist/, src-tauri/resources/,
|
||||
# src-tauri/binaries/) va TU DONG bump cache-buster (?v=) -> khong the miss
|
||||
# buoc copy nao du build theo cach nao. Bridge chi rebuild khi source moi hon.
|
||||
# LUU Y: file nay chi dung ky tu ASCII (khong dau) - PowerShell 5.1 doc an toan.
|
||||
param(
|
||||
[switch]$Frontend,
|
||||
[switch]$Bridge,
|
||||
[switch]$Engine,
|
||||
[switch]$Tauri,
|
||||
[switch]$SkipPip,
|
||||
[switch]$SkipNpm
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-Location $PSScriptRoot
|
||||
|
||||
# Kill moi daw_engine con song tu build/truoc (windowed, khong console ->
|
||||
# de quen -> file exe dang chay bi khoa -> Tauri build loi PermissionDenied
|
||||
# khi doc externalBin). Stop-Process im lang neu khong co tien trinh nao.
|
||||
Write-Host "== [0/6] Kill daw_engine.exe cu (neu dang chay) =="
|
||||
Get-Process -Name "daw_engine" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Milliseconds 500
|
||||
$any = $Frontend -or $Bridge -or $Engine -or $Tauri
|
||||
$doFrontend = $Frontend -or $Engine -or (-not $any) # Engine can bundle frontend moi truoc
|
||||
$doBridge = $Bridge -or (-not $any)
|
||||
$doEngine = $Engine -or (-not $any)
|
||||
$doTauri = $Tauri -or (-not $any)
|
||||
|
||||
Write-Host "== [1/6] Python dependencies =="
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements.txt pyinstaller pywin32
|
||||
$Stamp = Get-Date -Format "yyyyMMddHHmm"
|
||||
|
||||
Write-Host "== [2/6] Frontend bundle (app.jsx -> app.precompiled.js) =="
|
||||
npm install
|
||||
# Dam bao @babel/standalone co (build.mjs import truc tiep - da gap
|
||||
# ERR_MODULE_NOT_FOUND tren may Windows khi package.json cu thieu dep).
|
||||
if (-not (Test-Path "node_modules\@babel\standalone")) {
|
||||
Write-Host "Thieu @babel/standalone - dang cai them..."
|
||||
npm install @babel/standalone --no-audit --no-fund
|
||||
}
|
||||
if (-not (Test-Path "node_modules\@babel\standalone")) {
|
||||
Write-Host "ERROR: Khong cai duoc @babel/standalone. Kiem tra ket noi npm!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
node build.mjs # @babel/standalone; thay cho 'npm run build' (Babel 8 ESM-only CLI conflict)
|
||||
function Fail([string]$msg) { Write-Host "ERROR: $msg" -ForegroundColor Red; exit 1 }
|
||||
|
||||
Write-Host "== [3/6] Build daw_engine.exe (PyInstaller) =="
|
||||
pyinstaller engine.spec --clean --noconfirm
|
||||
|
||||
Write-Host "== [3.5/6] Verify bundle contents (app/static, app/templates phai co) =="
|
||||
# Bat loi bundle NGAY tai build (da gap 2 lan: chay pyinstaller tu noi khac
|
||||
# -> static/templates thieu -> exe crash 'Directory ...\app\static does not exist').
|
||||
# Dung tools/verify_bundle.py (parse TOC bang ast, chap nhan ca / va \) thay
|
||||
# vi regex thong thuong (TOC Windows co the dung backslash -> false positive).
|
||||
# Truoc tien kiem tra engine.spec phai la ban moi (collect_data_files).
|
||||
$specContent = Get-Content "engine.spec" -Raw -ErrorAction SilentlyContinue
|
||||
if ($specContent -notmatch "collect_data_files\('app'") {
|
||||
Write-Host "ERROR: engine.spec CU (thieu collect_data_files('app')). Pull code moi truoc khi build!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
python tools\verify_bundle.py
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: Bundle thieu asset - dung build, kiem tra engine.spec datas!" -ForegroundColor Red
|
||||
exit 1
|
||||
if ($doEngine -or $doTauri) {
|
||||
Write-Host "== [0] Kill daw_engine.exe cu (neu dang chay - tranh khoa exe khi build) =="
|
||||
Get-Process -Name "daw_engine" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
|
||||
Write-Host "== [4/6] ONEDIR engine -> src-tauri/resources/daw_engine (Tauri resources) =="
|
||||
# ONEDIR: copy ca thu muc dist\daw_engine\ (exe + _internal) vao resources.
|
||||
# Tauri bundle resources -> resource_dir()/daw_engine/daw_engine.exe luc runtime.
|
||||
if (-not (Test-Path "dist\daw_engine\daw_engine.exe")) {
|
||||
Write-Host "ERROR: dist\daw_engine\daw_engine.exe khong ton tai (onedir build loi?)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
if (Test-Path "src-tauri\resources\daw_engine") {
|
||||
Remove-Item -Recurse -Force "src-tauri\resources\daw_engine"
|
||||
}
|
||||
New-Item -ItemType Directory -Force "src-tauri\resources\daw_engine" | Out-Null
|
||||
Copy-Item "dist\daw_engine\*" "src-tauri\resources\daw_engine\" -Recurse -Force
|
||||
Write-Host "Copied onedir engine -> src-tauri\resources\daw_engine"
|
||||
# ---- [1] Frontend bundle + sync static -------------------------------------
|
||||
if ($doFrontend) {
|
||||
Write-Host "== [1] Frontend bundle (app.jsx -> app.precompiled.js, cache-buster v=$Stamp) =="
|
||||
if (-not $SkipNpm) { npm install }
|
||||
if (-not (Test-Path "node_modules\@babel\standalone")) {
|
||||
Write-Host "Thieu @babel/standalone - dang cai them..."
|
||||
npm install @babel/standalone --no-audit --no-fund
|
||||
}
|
||||
if (-not (Test-Path "node_modules\@babel\standalone")) { Fail "Khong cai duoc @babel/standalone. Kiem tra ket noi npm!" }
|
||||
node build.mjs $Stamp
|
||||
if ($LASTEXITCODE -ne 0) { Fail "build.mjs that bai" }
|
||||
|
||||
Write-Host "== [5/6] VC++ Redistributable cho hooks.nsh =="
|
||||
if (-not (Test-Path src-tauri\vc_redist.x64.exe)) {
|
||||
Invoke-WebRequest -Uri "https://aka.ms/vs/17/release/vc_redist.x64.exe" -OutFile src-tauri\vc_redist.x64.exe
|
||||
# Stamp cache-buster vao index.html source (no-cache HTML, bundle ?v= phai moi)
|
||||
$idx = "app\templates\index.html"
|
||||
$utf8 = New-Object System.Text.UTF8Encoding($false)
|
||||
$html = [IO.File]::ReadAllText($idx, $utf8)
|
||||
[IO.File]::WriteAllText($idx, [regex]::Replace($html, "app\.precompiled\.js\?v=\d+", "app.precompiled.js?v=$Stamp"), $utf8)
|
||||
|
||||
# Sync 3 file static -> dist + src-tauri/resources (ban packaged engine doc tu day)
|
||||
$pairs = @(
|
||||
@("static\js\app.precompiled.js", "_internal\app\static\js\app.precompiled.js"),
|
||||
@("static\js\sf-fx-realtime.js", "_internal\app\static\js\sf-fx-realtime.js"),
|
||||
@("templates\index.html", "_internal\app\templates\index.html")
|
||||
)
|
||||
$roots = @("dist\daw_engine", "src-tauri\resources\daw_engine")
|
||||
foreach ($p in $pairs) {
|
||||
$src = Join-Path "app" $p[0]
|
||||
foreach ($r in $roots) {
|
||||
$dst = Join-Path $r $p[1]
|
||||
New-Item -ItemType Directory -Force (Split-Path $dst) | Out-Null
|
||||
Copy-Item $src $dst -Force
|
||||
}
|
||||
}
|
||||
# Verify hash source == copy (bat loi "copy sai / thieu")
|
||||
foreach ($p in $pairs) {
|
||||
$srcHash = (Get-FileHash (Join-Path "app" $p[0]) -Algorithm SHA256).Hash
|
||||
foreach ($r in $roots) {
|
||||
$dst = Join-Path $r $p[1]
|
||||
if (-not (Test-Path $dst)) { Fail "Thieu file sau sync: $dst" }
|
||||
if ((Get-FileHash $dst -Algorithm SHA256).Hash -ne $srcHash) { Fail "Hash khac nhau sau sync: $dst" }
|
||||
}
|
||||
}
|
||||
Write-Host "Sync static OK (dist + src-tauri/resources)"
|
||||
}
|
||||
|
||||
Write-Host "== [6/6] Tauri build (NSIS .exe + MSI) =="
|
||||
# Guard: resources/daw_engine PHAI co exe + _internal truoc khi tauri build
|
||||
# (glob trong tauri.conf.json fail ngay "path not found" neu thieu).
|
||||
if (-not (Test-Path "src-tauri\resources\daw_engine\daw_engine.exe")) {
|
||||
Write-Host "ERROR: src-tauri\resources\daw_engine\daw_engine.exe khong co - buoc [4/6] that bai?" -ForegroundColor Red
|
||||
exit 1
|
||||
# ---- [2] Native bridge (MSBuild Release x64) --------------------------------
|
||||
if ($doBridge) {
|
||||
Write-Host "== [2] Native bridge (MSBuild Release x64 -> src-tauri/binaries) =="
|
||||
$msbuildCandidates = @(
|
||||
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
||||
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
||||
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
||||
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\MSBuild.exe"
|
||||
)
|
||||
$msbuild = $msbuildCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
|
||||
if (-not $msbuild) { Fail "Khong tim thay MSBuild.exe. Cai VS Build Tools 2019/2022 (workload C++) va chay CMake native_bridge truoc." }
|
||||
|
||||
foreach ($name in @("daw_vst_bridge", "fx_vst_bridge", "plugin_host")) {
|
||||
$proj = "native_bridge\build\$name.vcxproj"
|
||||
$exe = "native_bridge\build\Release\$name.exe"
|
||||
if (-not (Test-Path $proj)) { Fail "Thieu project: $proj (can CMake native_bridge truoc)" }
|
||||
$newest = Get-ChildItem -Path "native_bridge\src","native_bridge\include" -Recurse -Include *.cpp,*.h,*.hpp -ErrorAction SilentlyContinue |
|
||||
Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
$needBuild = $true
|
||||
if ((Test-Path $exe) -and $newest) { $needBuild = $newest.LastWriteTime -gt (Get-Item $exe).LastWriteTime }
|
||||
if ($needBuild) {
|
||||
Write-Host "Build $name ..."
|
||||
& $msbuild $proj "/p:Configuration=Release" "/p:Platform=x64" "/m" "/nologo" "/v:m"
|
||||
if ($LASTEXITCODE -ne 0) { Fail "MSBuild $name that bai" }
|
||||
} else {
|
||||
Write-Host "Skip $name (exe moi nhat)"
|
||||
}
|
||||
if (-not (Test-Path $exe)) { Fail "Thieu output: $exe" }
|
||||
Copy-Item $exe "src-tauri\binaries\$name.exe" -Force
|
||||
Copy-Item $exe "src-tauri\binaries\$name-x86_64-pc-windows-msvc.exe" -Force
|
||||
}
|
||||
foreach ($dll in @("libfluidsynth-3.dll", "jpeg62.dll")) {
|
||||
if (Test-Path "native_bridge\build\Release\$dll") {
|
||||
Copy-Item "native_bridge\build\Release\$dll" "src-tauri\binaries\$dll" -Force
|
||||
}
|
||||
}
|
||||
Write-Host "Bridge OK -> src-tauri/binaries"
|
||||
}
|
||||
if (-not (Test-Path "src-tauri\resources\daw_engine\_internal")) {
|
||||
Write-Host "ERROR: thieu src-tauri\resources\daw_engine\_internal (onedir khong day du)" -ForegroundColor Red
|
||||
exit 1
|
||||
|
||||
# ---- [3] Engine (PyInstaller) + sync resources ------------------------------
|
||||
if ($doEngine) {
|
||||
Write-Host "== [3] Engine (PyInstaller onedir -> src-tauri/resources) =="
|
||||
$specContent = Get-Content "engine.spec" -Raw -ErrorAction SilentlyContinue
|
||||
if ($specContent -notmatch "collect_data_files\('app'") { Fail "engine.spec CU (thieu collect_data_files('app')). Pull code moi truoc khi build!" }
|
||||
if (-not $SkipPip) {
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements.txt pyinstaller pywin32
|
||||
}
|
||||
if (Test-Path "dist\daw_engine") { Remove-Item -Recurse -Force "dist\daw_engine" }
|
||||
pyinstaller engine.spec --clean --noconfirm
|
||||
if ($LASTEXITCODE -ne 0) { Fail "pyinstaller that bai" }
|
||||
python tools\verify_bundle.py
|
||||
if ($LASTEXITCODE -ne 0) { Fail "Bundle thieu asset - dung build, kiem tra engine.spec datas" }
|
||||
if (-not (Test-Path "dist\daw_engine\daw_engine.exe")) { Fail "dist\daw_engine\daw_engine.exe khong ton tai (onedir build loi?)" }
|
||||
if (Test-Path "src-tauri\resources\daw_engine") { Remove-Item -Recurse -Force "src-tauri\resources\daw_engine" }
|
||||
New-Item -ItemType Directory -Force "src-tauri\resources\daw_engine" | Out-Null
|
||||
Copy-Item "dist\daw_engine\*" "src-tauri\resources\daw_engine\" -Recurse -Force
|
||||
Write-Host "Engine OK -> src-tauri/resources/daw_engine"
|
||||
}
|
||||
|
||||
# ---- [4] Tauri installer -----------------------------------------------------
|
||||
if ($doTauri) {
|
||||
Write-Host "== [4] VC++ Redistributable (cho hooks.nsh) =="
|
||||
if (-not (Test-Path src-tauri\vc_redist.x64.exe)) {
|
||||
Invoke-WebRequest -Uri "https://aka.ms/vs/17/release/vc_redist.x64.exe" -OutFile src-tauri\vc_redist.x64.exe
|
||||
}
|
||||
|
||||
Write-Host "== [5] Tauri build (NSIS + MSI) =="
|
||||
if (-not (Test-Path "src-tauri\resources\daw_engine\daw_engine.exe")) { Fail "resources/daw_engine thieu - chay -Engine hoac full truoc" }
|
||||
if (-not (Test-Path "src-tauri\resources\daw_engine\_internal")) { Fail "resources/daw_engine/_internal thieu (onedir khong day du)" }
|
||||
foreach ($name in @("daw_vst_bridge", "fx_vst_bridge", "plugin_host")) {
|
||||
if (-not (Test-Path "src-tauri\binaries\$name-x86_64-pc-windows-msvc.exe")) { Fail "Thieu src-tauri\binaries\$name-x86_64-pc-windows-msvc.exe - chay -Bridge truoc" }
|
||||
}
|
||||
if (-not $SkipNpm) { npm install -D @tauri-apps/cli }
|
||||
npx tauri build
|
||||
if ($LASTEXITCODE -ne 0) { Fail "tauri build that bai" }
|
||||
}
|
||||
npm install -D @tauri-apps/cli
|
||||
npx tauri build
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "== DONE =="
|
||||
Write-Host " NSIS: src-tauri\target\release\bundle\nsis\SonicForgeDAW_1.0.0_x64-setup.exe"
|
||||
Write-Host " MSI : src-tauri\target\release\bundle\msi\SonicForgeDAW_1.0.0_x64_en-US.msi"
|
||||
Write-Host ""
|
||||
Write-Host "== XAC MINH SAU KHI CAI DAT (quan trong) =="
|
||||
Write-Host " Mo %APPDATA%\SonicForgeDAW\logs\spawn.log - phai thay:"
|
||||
Write-Host " [resource_dir/daw_engine (map layout)] ...exists=True"
|
||||
Write-Host " Neu exists=False: bundle resources KHONG vao installer (chay lai buoc [4/6])."
|
||||
Write-Host " Engine phai nam o: <thu muc cai dat>\daw_engine\daw_engine.exe"
|
||||
Write-Host "== XAC MINH SAU KHI CAI DAT =="
|
||||
Write-Host " Mo %APPDATA%\SonicForgeDAW\logs\spawn.log - phai thay [resource_dir/daw_engine (map layout)] ...exists=True"
|
||||
|
||||
Reference in New Issue
Block a user