From a45490acf2c87fa102641dbd39b1af25cbecaffe Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Mon, 29 Dec 2025 07:48:45 -0800 Subject: [PATCH] fix(windows): improve Windows build setup and DLL handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add .exe extension to target-suffixed daemon binary on Windows - Auto-copy DLLs from apps/.deps/bin to target/debug and target/release - Add PATH env var for Windows in dev-with-daemon.ts so daemon finds DLLs - Run cargo xtask setup automatically at end of setup.ps1 These changes fix DLL_NOT_FOUND errors when running the Tauri app or daemon on Windows by ensuring native dependency DLLs are discoverable. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- apps/tauri/scripts/dev-with-daemon.ts | 11 +++++-- scripts/setup.ps1 | 11 +++++++ xtask/src/main.rs | 42 +++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/apps/tauri/scripts/dev-with-daemon.ts b/apps/tauri/scripts/dev-with-daemon.ts index 1defd1c88..720f71482 100755 --- a/apps/tauri/scripts/dev-with-daemon.ts +++ b/apps/tauri/scripts/dev-with-daemon.ts @@ -126,13 +126,20 @@ async function main() { throw new Error(`Daemon binary not found at: ${DAEMON_BIN}`); } + const depsLibPath = join(PROJECT_ROOT, "apps/.deps/lib"); + const depsBinPath = join(PROJECT_ROOT, "apps/.deps/bin"); + daemonProcess = spawn(DAEMON_BIN, ["--data-dir", DATA_DIR], { cwd: PROJECT_ROOT, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, - // On Windows DYLD_LIBRARY_PATH does nothing, but keeping it doesn't hurt - DYLD_LIBRARY_PATH: join(PROJECT_ROOT, "apps/.deps/lib"), + // macOS library path + DYLD_LIBRARY_PATH: depsLibPath, + // Windows: Add DLLs directory to PATH + PATH: IS_WIN + ? `${depsBinPath};${process.env.PATH || ""}` + : process.env.PATH, }, }); diff --git a/scripts/setup.ps1 b/scripts/setup.ps1 index 413b4d717..49d56254a 100644 --- a/scripts/setup.ps1 +++ b/scripts/setup.ps1 @@ -256,6 +256,17 @@ if ($LASTEXITCODE -ne 0) { Exit-WithError "Something went wrong, exit code: $LASTEXITCODE" } +# Run xtask setup to download native dependencies and configure cargo +if (-not $env:CI) { + Write-Host + Write-Host 'Running cargo xtask setup to download native dependencies...' -ForegroundColor Yellow + Set-Location $projectRoot + cargo xtask setup + if ($LASTEXITCODE -ne 0) { + Exit-WithError 'Failed to run cargo xtask setup' + } +} + if (-not $env:CI) { Write-Host Write-Host 'Your machine has been setup for Spacedrive development!' -ForegroundColor Green diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 733344f7f..c5bcce188 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -213,13 +213,49 @@ fn setup() -> Result<()> { // Create target-suffixed daemon binary for Tauri bundler // Tauri's externalBin appends the target triple to binary names let target_triple = system.target_triple(); - let daemon_source = project_root.join("target/release/sd-daemon"); - let daemon_target = project_root.join(format!("target/release/sd-daemon-{}", target_triple)); + let exe_ext = if cfg!(windows) { ".exe" } else { "" }; + let daemon_source = project_root.join(format!("target/release/sd-daemon{}", exe_ext)); + let daemon_target = project_root.join(format!( + "target/release/sd-daemon-{}{}", + target_triple, exe_ext + )); if daemon_source.exists() { fs::copy(&daemon_source, &daemon_target) .context("Failed to create target-suffixed daemon binary")?; - println!(" ✓ Created sd-daemon-{}", target_triple); + println!(" ✓ Created sd-daemon-{}{}", target_triple, exe_ext); + } + + // On Windows, copy DLLs to target directories so executables can find them at runtime + #[cfg(windows)] + { + println!(); + println!("Copying DLLs to target directories..."); + let dll_source_dir = native_deps_dir.join("bin"); + if dll_source_dir.exists() { + // Copy to both debug and release directories + for target_profile in ["debug", "release"] { + let target_dir = project_root.join("target").join(target_profile); + fs::create_dir_all(&target_dir).ok(); + + if let Ok(entries) = fs::read_dir(&dll_source_dir) { + for entry in entries.flatten() { + let path = entry.path(); + if path.extension().map_or(false, |ext| ext == "dll") { + let dest = target_dir.join(path.file_name().unwrap()); + if let Err(e) = fs::copy(&path, &dest) { + eprintln!( + " Warning: Failed to copy {}: {}", + path.file_name().unwrap().to_string_lossy(), + e + ); + } + } + } + } + println!(" ✓ DLLs copied to target/{}/", target_profile); + } + } } println!();