fix(windows): improve Windows build setup and DLL handling

- 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 <noreply@anthropic.com>
This commit is contained in:
Jamie Pine
2025-12-29 07:48:45 -08:00
parent 544f4ef063
commit a45490acf2
3 changed files with 59 additions and 5 deletions

View File

@@ -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,
},
});

View File

@@ -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

View File

@@ -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!();