Log like a debug build on macOS, where a Mac user can find it

Nobody working on DarkRoom has a Mac, so every macOS build is in the hands
of someone who can send a log and cannot attach a debugger. Three changes
make that log worth sending:

- The desktop's default filter on macOS is `debug` for every `dr_*` crate,
  the desktop crate and `onnxruntime` (the runtime's own session log).
- The state directory — the log and crash records — is `~/Library/Logs`
  on macOS rather than the `~/.local/state` Finder hides; Console.app
  lists it. Config and data keep the Unix rules.
- A `diagnostic` cargo profile: release plus line tables, so a crash
  record's backtrace reads file:line. On macOS the tables are in the
  `.dSYM` beside the executable, which the bundle must keep.
This commit is contained in:
2026-09-29 21:33:02 -04:00
parent b23527d5dc
commit 07e85cf0b2
5 changed files with 50 additions and 8 deletions
+2 -1
View File
@@ -98,7 +98,8 @@ pub fn set_state_dir(dir: PathBuf) {
/// Where this application keeps state that is neither configuration nor cache.
///
/// `$XDG_STATE_HOME/darkroom`, falling back to `~/.local/state/darkroom`.
/// `$XDG_STATE_HOME/darkroom`, falling back to `~/.local/state/darkroom` —
/// `~/Library/Logs/darkroom` on macOS (`dirs`).
/// State rather than cache because a crash record must survive the sweep that
/// a cache directory exists to permit, and rather than config because it is
/// not something the user edits.
+2
View File
@@ -46,6 +46,8 @@
//!
//! * Linux: `$XDG_STATE_HOME/darkroom/darkroom.log`, else
//! `~/.local/state/darkroom/darkroom.log`.
//! * macOS: `$XDG_STATE_HOME/darkroom/darkroom.log`, else
//! `~/Library/Logs/darkroom/darkroom.log`, where Console.app lists it.
//! * Android: `/sdcard/Android/data/paris.tourolle.darkroom/files/darkroom.log`,
//! which `adb pull` reads from an ordinary release build. See
//! [`crate::state`] for why not the internal directory, and
+15 -3
View File
@@ -17,6 +17,11 @@
//! | Unix default | `~/.config` | `~/.local/share` | `~/.local/state` |
//! | Windows | `%APPDATA%` | `%LOCALAPPDATA%` | `%LOCALAPPDATA%`, then `state` |
//! | Windows default | `%USERPROFILE%\AppData\Roaming` | `…\AppData\Local` | `…\AppData\Local` |
//! | macOS default | `~/.config` | `~/.local/share` | `~/Library/Logs` |
//!
//! macOS follows the Unix rules except for the one directory a user is asked
//! to find by hand: the log. Finder hides `~/.local`, and `~/Library/Logs`
//! is where Console.app and a Mac user already look (docs/dev/macos.md).
//!
//! then `darkroom` under each. Config roams on Windows and the rest does not,
//! which is the same split XDG makes between config and everything else, and
@@ -100,11 +105,18 @@ fn resolve(kind: Base, env: impl Fn(&str) -> Option<OsString>) -> PathBuf {
}
}
/// Where state goes under `$HOME` when `XDG_STATE_HOME` does not say.
const STATE_UNDER_HOME: &str = if cfg!(target_os = "macos") {
"Library/Logs"
} else {
".local/state"
};
fn xdg_base(kind: Base, env: &impl Fn(&str) -> Option<OsString>) -> Option<PathBuf> {
let (var, under_home) = match kind {
Base::Config => ("XDG_CONFIG_HOME", ".config"),
Base::Data => ("XDG_DATA_HOME", ".local/share"),
Base::State => ("XDG_STATE_HOME", ".local/state"),
Base::State => ("XDG_STATE_HOME", STATE_UNDER_HOME),
};
absolute(env(var)).or_else(|| absolute(env("HOME")).map(|h| h.join(under_home)))
}
@@ -150,7 +162,7 @@ mod tests {
);
assert_eq!(
xdg_base(Base::State, &e),
Some(PathBuf::from("/home/someone/.local/state"))
Some(PathBuf::from("/home/someone").join(STATE_UNDER_HOME))
);
}
@@ -162,7 +174,7 @@ mod tests {
let e = env(&[("XDG_STATE_HOME", "state"), ("HOME", "/home/someone")]);
assert_eq!(
xdg_base(Base::State, &e),
Some(PathBuf::from("/home/someone/.local/state"))
Some(PathBuf::from("/home/someone").join(STATE_UNDER_HOME))
);
assert_eq!(xdg_base(Base::State, &env(&[("HOME", "")])), None);
}