Files
zoitechat/osx/DEBUGGING.md
2026-02-19 11:36:36 -07:00

208 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Debugging ZoiteChat on macOS (Xcode + CLI)
If the unsigned `.app` launches but does nothing (or immediately exits), use the steps below to get actionable logs and a debugger session.
## 1) Build with debug symbols
ZoiteChat uses Meson. Build a debug configuration first so LLDB can show useful backtraces.
```bash
meson setup build-macos-debug --buildtype=debug
meson compile -C build-macos-debug
```
This project default is `debugoptimized`, but a full `debug` build is better while diagnosing crashes/startup issues.
## 2) Bundle the app and verify deployment target
Use the existing bundle script:
```bash
cd osx
./makebundle.sh
```
The generated `Info.plist` should keep:
- `LSMinimumSystemVersion = 11.0`
That is the projects explicit minimum runtime target for macOS 11+.
## 3) Sanity-check the Mach-O binary in the bundle
Confirm architecture(s), deployment target, and linked libraries:
```bash
file ZoiteChat.app/Contents/MacOS/ZoiteChat-bin
otool -l ZoiteChat.app/Contents/MacOS/ZoiteChat-bin | rg -n "LC_BUILD_VERSION|minos|sdk"
otool -L ZoiteChat.app/Contents/MacOS/ZoiteChat-bin
```
For widest compatibility, build universal (`arm64` + `x86_64`) or build separately per arch and test each on matching hosts.
## 4) Ad-hoc sign for local debugging
Unsigned GUI binaries can fail in unhelpful ways because of hardened runtime/quarantine/Gatekeeper interactions. For local debugging, ad-hoc sign the app:
```bash
xattr -dr com.apple.quarantine ZoiteChat.app
codesign --force --deep --sign - ZoiteChat.app
codesign --verify --deep --strict --verbose=2 ZoiteChat.app
```
## 5) Launch from Terminal first (before Xcode)
Direct launch exposes stdout/stderr and validates the launcher environment:
```bash
./ZoiteChat.app/Contents/MacOS/ZoiteChat
```
The launcher script sets GTK/Pango/GDK environment variables. If direct launch fails, capture that output first.
## 6) Debug with LLDB (reliable baseline)
Debug the real executable inside the bundle:
```bash
lldb -- ZoiteChat.app/Contents/MacOS/ZoiteChat-bin
(lldb) run
(lldb) bt
```
If it exits instantly, set breakpoints on startup entry points (for example `main`) and re-run.
## 7) Debug with Xcode (if you prefer GUI)
Xcode works best when opening the executable directly instead of importing build scripts.
1. **File → Open…** and select `ZoiteChat.app/Contents/MacOS/ZoiteChat-bin`.
2. In **Product → Scheme → Edit Scheme…**
- Executable: `ZoiteChat-bin`
- Working directory: repo root (or `osx/`)
- Add environment variables equivalent to the launcher if needed.
3. Run under debugger.
If Xcode “runs” but no UI appears, compare its environment to `osx/launcher.sh` and copy missing GTK-related variables into the scheme.
## 8) Capture macOS crash diagnostics
Even if no dialog appears, macOS usually logs termination reasons:
```bash
log stream --style compact --predicate 'process == "ZoiteChat-bin"'
```
Also check:
- `~/Library/Logs/DiagnosticReports/`
## 9) Frequent root causes for “silent” startup failures
- Missing GTK runtime libraries in app bundle (`otool -L` shows unresolved paths).
- Incorrect `@rpath`/install names after bundling.
- Running under Rosetta mismatch (x86_64 binary with arm64-only deps or vice versa).
- Quarantine/signature issues on unsigned artifacts.
- Missing `GDK_PIXBUF_MODULE_FILE`, `GTK_IM_MODULE_FILE`, or schema paths.
### "Bad CPU type in executable"
This means the bundled `ZoiteChat-bin` architecture does not match the Mac you are running on.
- Intel Mac requires `x86_64`
- Apple Silicon requires `arm64` (or Rosetta + `x86_64`)
Check the binary quickly:
```bash
file ZoiteChat.app/Contents/MacOS/ZoiteChat-bin
```
Build for Intel explicitly when needed:
```bash
export CFLAGS="-arch x86_64"
export LDFLAGS="-arch x86_64"
meson setup build-macos-intel --buildtype=debug
meson compile -C build-macos-intel
```
If your dependency stack supports it, build universal (`arm64` + `x86_64`) and verify with `lipo -info`.
### Linker says `found architecture 'arm64', required architecture 'x86_64'`
If you see warnings like this during `meson compile`:
```text
ld: warning: ignoring file '/opt/homebrew/.../libgio-2.0.dylib': found architecture 'arm64', required architecture 'x86_64'
Undefined symbols for architecture x86_64: ...
```
your compile target architecture and dependency architecture do not match.
On Apple Silicon, this usually means you are trying to build `x86_64` while linking against ARM Homebrew libraries from `/opt/homebrew`.
Quick checks:
```bash
echo "$CFLAGS" "$LDFLAGS"
pkg-config --libs glib-2.0
lipo -info "$(brew --prefix glib)/lib/libglib-2.0.dylib"
```
Use one of these consistent setups:
- Native Apple Silicon build (`arm64`) with `/opt/homebrew` dependencies.
- Intel build (`x86_64`) with an x86_64 dependency stack (typically Homebrew under `/usr/local` run under Rosetta).
Example x86_64 setup on Apple Silicon:
```bash
# Open a Rosetta shell first (or prefix commands with `arch -x86_64`)
arch -x86_64 /bin/bash -lc '
export PATH="/usr/local/bin:$PATH"
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig"
export CFLAGS="-arch x86_64"
export LDFLAGS="-arch x86_64"
meson setup build-macos-x86_64 --prefix="/usr/local"
meson compile -C build-macos-x86_64
'
```
If you do not specifically need Intel compatibility, remove any forced `-arch x86_64` flags and build native `arm64`.
Example with this repo's scripts:
```bash
PREFIX="$(brew --prefix)"
CFLAGS="-arch arm64" LDFLAGS="-arch arm64" meson setup build-macos-arm64 --prefix="$PREFIX"
CFLAGS="-arch x86_64" LDFLAGS="-arch x86_64" meson setup build-macos-x86_64 --prefix="$PREFIX"
CFLAGS="-arch arm64" LDFLAGS="-arch arm64" meson compile -C build-macos-arm64
CFLAGS="-arch x86_64" LDFLAGS="-arch x86_64" meson compile -C build-macos-x86_64
sudo meson install -C build-macos-arm64
cd osx
UNIVERSAL=1 \
UNIVERSAL_BINARIES="../build-macos-arm64/src/fe-gtk/zoitechat ../build-macos-x86_64/src/fe-gtk/zoitechat" \
./makebundle.sh
```
## 10) Recommended compatibility settings for macOS 11+
- Keep `LSMinimumSystemVersion` at `11.0`.
- Build on the oldest macOS SDK/toolchain that still supports your dependencies, or explicitly set:
```bash
export MACOSX_DEPLOYMENT_TARGET=11.0
```
- Verify with `otool -l` that `minos` is actually `11.0` in the final executable.
---
If you want, we can add an Xcode scheme file to this repo that mirrors `osx/launcher.sh` so “Run” in Xcode behaves exactly like launching the app bundle from Finder/Terminal.