fix(sidecar): probe installed and dev paths for the binary

dpkg-deb -c on the bundled .deb shows mycelium at /usr/bin/mycelium
(no triple suffix), next to the app launcher. Our previous resolver
only looked for the suffixed dev name in resource_dir, so the
installed app could not find its sidecar.

Probe order is now: directory of current_exe, then resource_dir,
then CARGO_MANIFEST_DIR/binaries, then $PATH, with both the plain
"mycelium" name and the dev-style "mycelium-<triple>" alias
checked at each location.
This commit is contained in:
syoul
2026-04-26 01:09:44 +02:00
parent 939565b88a
commit a31a40a477
2 changed files with 47 additions and 10 deletions

View File

@@ -295,30 +295,67 @@ fn pick_port_skip(taken: &[u16]) -> AppResult<u16> {
))
}
/// Resolve the bundled `mycelium-<triple>` binary in both `tauri dev`
/// (cargo manifest) and bundled (resource_dir) modes.
/// Resolve the bundled `mycelium` sidecar across our two build modes:
/// • `tauri dev` keeps the file under `src-tauri/binaries/` with the
/// `-<target_triple>` suffix Tauri's externalBin convention requires.
/// • `tauri build` for a `.deb` strips the suffix and places the
/// binary at `/usr/bin/mycelium` next to the app launcher.
/// We probe the bundled path first, then walk back to the dev location.
fn locate_sidecar(app: &AppHandle) -> AppResult<PathBuf> {
let triple = std::env::var("TAURI_ENV_TARGET_TRIPLE")
.ok()
.or_else(|| option_env!("TARGET").map(|s| s.to_string()))
.unwrap_or_else(|| "x86_64-unknown-linux-gnu".to_string());
let name = format!("mycelium-{triple}");
let suffixed = format!("mycelium-{triple}");
let plain = "mycelium".to_string();
let mut tried: Vec<PathBuf> = Vec::new();
// Bundled .deb / AppImage: the launcher lives next to the sidecar
// under /usr/bin/. Resolve relative to the running executable.
if let Ok(exe) = std::env::current_exe() {
if let Some(dir) = exe.parent() {
for name in [&plain, &suffixed] {
let p = dir.join(name);
if p.exists() {
return Ok(p);
}
tried.push(p);
}
}
}
// Tauri's resource_dir() — used when externalBin is treated as a
// resource (older bundles, or when the user moves things around).
if let Ok(resource) = app.path().resource_dir() {
let p = resource.join(&name);
for name in [&plain, &suffixed] {
let p = resource.join(name);
if p.exists() {
return Ok(p);
}
tried.push(p);
}
}
// Dev mode: `pnpm tauri dev` runs the binary out of target/debug/ so
// current_exe() is far from src-tauri/binaries/. Use the manifest dir.
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
for name in [&suffixed, &plain] {
let p = manifest_dir.join("binaries").join(name);
if p.exists() {
return Ok(p);
}
tried.push(p);
}
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let dev_path = manifest_dir.join("binaries").join(&name);
if dev_path.exists() {
return Ok(dev_path);
// Final fallback: trust $PATH if a system-installed mycelium is around.
if let Ok(path) = std::env::var("PATH") {
for entry in path.split(':') {
let p = PathBuf::from(entry).join(&plain);
if p.exists() {
return Ok(p);
}
}
}
tried.push(dev_path);
Err(AppError::SidecarNotFound(tried))
}

View File

@@ -29,7 +29,7 @@
"bundle": {
"active": true,
"targets": ["deb", "appimage"],
"category": "Network",
"category": "Utility",
"shortDescription": "Mycelium overlay network client",
"longDescription": "Desktop GUI for the Mycelium end-to-end encrypted IPv6 overlay network.",
"icon": [