fix: daw_engine khong chay tren Windows - bundle resources sai layout
Spawn.log cho thay: resource_dir()/daw_engine/daw_engine.exe exists=false
tren ca ban cai lan target/release - engine KHONG duoc bundle dung cho.
Goc re (doc source tauri-utils/src/resources.rs + tauri-cli/src/interface/rust.rs):
- bundle.resources dang ARRAY ['resources/daw_engine']: ResourcePaths::new
(Slice) -> target = resource_relpath(path) GIU TIEN TO 'resources/'
-> engine nam o /resources/daw_engine/...
- lib.rs cu tim o /daw_engine/... -> exists=false.
Fix:
- tauri.conf.json: resources dang MAP {'resources/daw_engine': 'daw_engine/'}
-> resources_map -> Walk mode, dest.join(strip_prefix) -> giu nguyen cay
_internal, dich chuan /daw_engine/ (xac nhan tauri-cli
BundleResources::Map -> settings.resources_map, dong 1467-1469).
- lib.rs: do them 3 vi tri fallback (legacy resources/ prefix, portable
exe_dir, dev exe_dir/../resources) + log diagnostic day du vao spawn.log
(liet ke noi dung resource_dir/exe_dir khi khong tim thay).
- build_windows.ps1: them huong dan xac minh spawn.log sau khi cai dat.
This commit is contained in:
@@ -91,6 +91,16 @@ Nguyên nhân nặng cũ: `librosa` kéo theo `numba`+`llvmlite` (~171MB) + `sci
|
||||
NSIS không còn lỗi mmapping; `hooks.nsh` cài VC++ Redistributable (MSI không
|
||||
chạy hooks → máy thiếu VC++ → daw_engine.exe không chạy — đây là nguyên nhân
|
||||
"build xong không chạy daw_engine" trên Windows).
|
||||
- **Fix layout resources (bản 1.1.1 — `exists=false` trong spawn.log)**:
|
||||
`bundle.resources` dạng ARRAY `["resources/daw_engine"]` copy engine tới
|
||||
`$RESOURCE_DIR/resources/daw_engine/...` (giữ tiền tố `resources/` — đọc
|
||||
source `tauri-utils/src/resources.rs`) trong khi lib.rs tìm ở
|
||||
`$RESOURCE_DIR/daw_engine/...` → `exists=false`. Đổi sang dạng MAP
|
||||
`{"resources/daw_engine": "daw_engine/"}` (Walk mode, giữ nguyên cây
|
||||
`_internal`, đích chuẩn `daw_engine/`). `src-tauri/src/lib.rs` đồng thời dò
|
||||
thêm 3 vị trí fallback (legacy/portable/dev) + ghi diagnostic đầy đủ vào
|
||||
`%APPDATA%/SonicForgeDAW/logs/spawn.log` (liệt kê nội dung resource_dir khi
|
||||
không tìm thấy).
|
||||
|
||||
Lệnh build 1 lệnh mỗi OS:
|
||||
```bash
|
||||
|
||||
@@ -87,3 +87,9 @@ 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"
|
||||
|
||||
+120
-31
@@ -1,34 +1,90 @@
|
||||
// SonicForge DAW — desktop shell: spawn/terminate daw_engine.exe sidecar.
|
||||
// SonicForge DAW — desktop shell: spawn/terminate daw_engine sidecar.
|
||||
//
|
||||
// QUAN TRONG (fix bản 1.1.1 — engine không chạy trên Windows):
|
||||
// tauri.conf.json bundle.resources giờ dùng dạng MAP:
|
||||
// { "resources/daw_engine": "daw_engine/" }
|
||||
// vì dạng ARRAY ("resources/daw_engine") copy file tới
|
||||
// $RESOURCE_DIR/resources/daw_engine/... (giữ tiền tố "resources/"),
|
||||
// trong khi code cũ tìm ở $RESOURCE_DIR/daw_engine/... -> exists=false.
|
||||
// Dạng map (Walk mode) giữ nguyên cây thư mục (_internal) dưới đích
|
||||
// "daw_engine/" — đúng layout lib.rs chờ.
|
||||
// Ngoài ra lib.rs còn dò THÊM các vị trí fallback (legacy/portable/dev)
|
||||
// và ghi đầy đủ diagnostic vào %APPDATA%/SonicForgeDAW/logs/spawn.log.
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_shell::process::CommandChild;
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
|
||||
struct EngineProcess(Mutex<Option<CommandChild>>);
|
||||
|
||||
/// Các vị trí có thể chứa daw_engine, theo thứ tự ưu tiên.
|
||||
fn engine_candidates(res_dir: &Path, exe_dir: &Path) -> Vec<(PathBuf, String)> {
|
||||
let exe_name = if cfg!(windows) { "daw_engine.exe" } else { "daw_engine" };
|
||||
vec![
|
||||
// 1. Layout chuẩn (resources map): $RESOURCE/daw_engine/daw_engine.exe
|
||||
(
|
||||
res_dir.join("daw_engine").join(exe_name),
|
||||
"resource_dir/daw_engine (map layout)".into(),
|
||||
),
|
||||
// 2. Legacy (resources array cũ giữ tiền tố resources/)
|
||||
(
|
||||
res_dir.join("resources").join("daw_engine").join(exe_name),
|
||||
"resource_dir/resources/daw_engine (legacy array)".into(),
|
||||
),
|
||||
// 3. Portable: engine đặt cạnh exe
|
||||
(
|
||||
exe_dir.join("daw_engine").join(exe_name),
|
||||
"exe_dir/daw_engine (portable)".into(),
|
||||
),
|
||||
// 4. Dev mode: target/{debug,release} -> src-tauri/resources
|
||||
(
|
||||
exe_dir.join("..").join("resources").join("daw_engine").join(exe_name),
|
||||
"exe_dir/../resources/daw_engine (dev)".into(),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn list_dir_snippet(dir: &Path) -> String {
|
||||
let mut s = String::new();
|
||||
match std::fs::read_dir(dir) {
|
||||
Ok(rd) => {
|
||||
let mut n = 0;
|
||||
for e in rd.flatten() {
|
||||
if n > 0 {
|
||||
s.push_str(", ");
|
||||
}
|
||||
s.push_str(&e.file_name().to_string_lossy());
|
||||
n += 1;
|
||||
if n >= 15 {
|
||||
s.push_str(", ...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => s.push_str("<khong doc duoc dir>"),
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.setup(|app| {
|
||||
// 1. Spawn daw_engine (PyInstaller ONEDIR bundle — khong giai nen
|
||||
// moi lan chay nhu onefile, khoi dong nhanh). Bundle qua Tauri
|
||||
// resources: resource_dir()/daw_engine/daw_engine(.exe)
|
||||
let res_dir = app
|
||||
.path()
|
||||
.resource_dir()
|
||||
.expect("resource dir not found");
|
||||
let engine_dir = res_dir.join("daw_engine");
|
||||
let engine_exe = if cfg!(windows) {
|
||||
engine_dir.join("daw_engine.exe")
|
||||
} else {
|
||||
engine_dir.join("daw_engine")
|
||||
};
|
||||
// Ghi log spawn de chan doan (UI khong duoc panic/thoat — chi log).
|
||||
// Ghi vao %APPDATA%/SonicForgeDAW/logs/spawn.log (thu muc luon ton
|
||||
// tai) — KHONG ghi vao engine_dir vi thu muc do co the khong duoc
|
||||
// bundle vao installer (resources loi) -> ghi am tham that bai.
|
||||
let exe_dir = std::env::current_exe()
|
||||
.ok()
|
||||
.and_then(|p| p.parent().map(|d| d.to_path_buf()))
|
||||
.unwrap_or_default();
|
||||
let candidates = engine_candidates(&res_dir, &exe_dir);
|
||||
|
||||
// Ghi log spawn de chan doan — vao %APPDATA%/SonicForgeDAW/logs/
|
||||
// spawn.log (thu muc luon ton tai), KHONG ghi vao engine_dir.
|
||||
let log_dir = std::env::var("APPDATA").unwrap_or_else(|_| ".".into());
|
||||
let spawn_log_path = std::path::Path::new(&log_dir)
|
||||
.join("SonicForgeDAW")
|
||||
@@ -37,12 +93,31 @@ pub fn run() {
|
||||
if let Some(parent) = spawn_log_path.parent() {
|
||||
let _ = std::fs::create_dir_all(parent);
|
||||
}
|
||||
let log_line = format!(
|
||||
"spawn daw_engine: {} exists={}\nresource_dir={}\n",
|
||||
engine_exe.display(),
|
||||
engine_exe.exists(),
|
||||
res_dir.display()
|
||||
|
||||
let mut log_line = format!(
|
||||
"resource_dir={}\nexe_dir={}\n",
|
||||
res_dir.display(),
|
||||
exe_dir.display()
|
||||
);
|
||||
let mut found: Option<(PathBuf, String)> = None;
|
||||
for (path, label) in &candidates {
|
||||
let exists = path.exists();
|
||||
log_line.push_str(&format!(
|
||||
" [{label}] {} exists={}\n",
|
||||
path.display(),
|
||||
exists
|
||||
));
|
||||
if found.is_none() && exists {
|
||||
found = Some((path.clone(), label.clone()));
|
||||
}
|
||||
}
|
||||
if found.is_none() {
|
||||
log_line.push_str(&format!(
|
||||
" NOT FOUND — resource_dir contents: {}\n exe_dir contents: {}\n",
|
||||
list_dir_snippet(&res_dir),
|
||||
list_dir_snippet(&exe_dir)
|
||||
));
|
||||
}
|
||||
if let Ok(mut f) = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
@@ -51,26 +126,40 @@ pub fn run() {
|
||||
use std::io::Write;
|
||||
let _ = f.write_all(log_line.as_bytes());
|
||||
}
|
||||
match app.shell().command(&engine_exe)
|
||||
.env("SF_PARENT_PID", std::process::id().to_string())
|
||||
.spawn() {
|
||||
Ok((_rx, child)) => {
|
||||
app.manage(EngineProcess(Mutex::new(Some(child))));
|
||||
println!("Python Background Engine started (localhost:8000, auto-fallback 8000-8010)");
|
||||
|
||||
match found {
|
||||
Some((engine_exe, label)) => {
|
||||
match app
|
||||
.shell()
|
||||
.command(&engine_exe)
|
||||
.env("SF_PARENT_PID", std::process::id().to_string())
|
||||
.spawn()
|
||||
{
|
||||
Ok((_rx, child)) => {
|
||||
app.manage(EngineProcess(Mutex::new(Some(child))));
|
||||
println!(
|
||||
"Python Background Engine started ({label}): {}",
|
||||
engine_exe.display()
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to spawn daw_engine {engine_exe:?}: {e}");
|
||||
app.manage(EngineProcess(Mutex::new(None)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
// Khong panic: UI van mo, engine loi se hien trong UI loader
|
||||
// ("Khong tim thay SonicForge Engine"). Log ro de chan doan.
|
||||
println!("Failed to spawn daw_engine: {e}");
|
||||
None => {
|
||||
println!(
|
||||
"daw_engine binary not found in any candidate path — xem spawn.log de biet chi tiet"
|
||||
);
|
||||
app.manage(EngineProcess(Mutex::new(None)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(|window, event| {
|
||||
// 2. Terminate sidecar khi DAW window dong — tranh orphan process
|
||||
// Terminate sidecar khi DAW window dong — tranh orphan process
|
||||
if let tauri::WindowEvent::Destroyed = event {
|
||||
// Lay child ra khoi lock, guard drop ngay tai day (trach E0597)
|
||||
let child = window
|
||||
.state::<EngineProcess>()
|
||||
.0
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
"icons/128x128@2x.png",
|
||||
"icons/favicon.ico"
|
||||
],
|
||||
"resources": [
|
||||
"resources/daw_engine"
|
||||
],
|
||||
"resources": {
|
||||
"resources/daw_engine": "daw_engine/"
|
||||
},
|
||||
"externalBin": [],
|
||||
"windows": {
|
||||
"nsis": {
|
||||
|
||||
Reference in New Issue
Block a user