summaryrefslogtreecommitdiff
path: root/IDE_INTEGRATION.md
diff options
context:
space:
mode:
Diffstat (limited to 'IDE_INTEGRATION.md')
-rw-r--r--IDE_INTEGRATION.md198
1 files changed, 198 insertions, 0 deletions
diff --git a/IDE_INTEGRATION.md b/IDE_INTEGRATION.md
new file mode 100644
index 0000000..67ba96e
--- /dev/null
+++ b/IDE_INTEGRATION.md
@@ -0,0 +1,198 @@
+# IDE integration
+
+YASL includes Zed debugger profiles for stepping from example applications into
+the library's display and window creation code. Open the repository root (the
+directory containing `meson.build`) as your Zed project. The shared configuration
+uses `build/` for the build directory on Linux and macOS.
+
+## Prerequisites
+
+Install Zed, a C23 compiler, Meson 1.6 or newer, Ninja, pkg-config, and Python 3.
+A C++ compiler enables the optional public-header compatibility test. Install
+the backend development dependencies described in
+[Getting started](docs/getting-started.md#build-and-run): at least one of Wayland
+or X11 on Linux, or the macOS 14+ SDK on macOS. Running windows on macOS also
+requires a Metal-capable device.
+
+[Zed's C support](https://zed.dev/docs/languages/c) includes clangd for code
+completion, diagnostics, and navigation, and CodeLLDB for debugging. Allow Zed
+to obtain these tools when prompted, or configure your existing installations
+in your personal Zed settings. Use a recent clangd with C23 support.
+
+Make sure `meson`, `ninja`, your compiler, `pkg-config`, and `python3` are on the
+PATH visible to Zed's terminal. You can open the project from an initialized
+terminal with `zed .` when Zed's CLI is installed. On macOS, if your toolchain
+defaults to an older deployment target, launch from a terminal with
+`MACOSX_DEPLOYMENT_TARGET=14.0` (or newer) exported before configuring.
+
+## Start debugging window creation
+
+1. Save your changes and open `examples/hello.c`.
+2. Set gutter breakpoints on the calls to `yasl_display_open()` and
+ `yasl_surface_create_toplevel()` in `main()`.
+3. Open the command palette (`Ctrl+Shift+P` on Linux, `Cmd+Shift+P` on macOS),
+ run `debugger: start`, and choose **YASL: debug hello**.
+4. The debugger prepares the build and pauses on entry. Continue to the display
+ creation breakpoint, then use **Step Into** to enter YASL's implementation in
+ `src/common/backend.c`. Continue to the surface creation breakpoint and step
+ into `yasl_surface_create_toplevel()` and `yasl_create_toplevel()`.
+5. Step into `d->ops->surface_create_toplevel(...)` to reach native window
+ creation. Inspect `spec`, `d`, local variables, and the call stack in Zed's
+ debug panel. Use **Step Over** for calls you want to execute without entering.
+
+Every debug profile runs **YASL: build for debugger** before launching. This
+task creates or reconfigures `build/` with debug symbols, optimization disabled,
+and LTO disabled, then builds the library and examples. It explicitly sets
+`buildtype=debug`, `debug=true`, `optimization=0`, and `b_lto=false`, including
+when `build/` was previously a release or customized build. Other Meson options,
+including backend selection, are preserved. Both the example and YASL have
+source-level debug information; the shared-library examples load the library
+from the Meson build tree.
+
+Profiles pause on entry through CodeLLDB's `stopOnEntry` setting, so initialization
+does not run before you can inspect the session. To launch directly to your
+breakpoints instead, set `"stopOnEntry": false` in the desired profile. See
+[CodeLLDB's launch settings](https://github.com/vadimcn/codelldb/blob/master/MANUAL.md#launching-a-new-process).
+
+Native creation follows the backend selected at runtime:
+
+| Backend | Window creation implementation |
+| --- | --- |
+| Wayland | `wayland_surface_create_toplevel()` in `src/platform/wayland/surface.c` |
+| X11 | `create_toplevel()` in `src/platform/x11/window.c` |
+| Cocoa | `cocoa_surface_create_toplevel()` in `src/platform/cocoa/window.m` |
+
+You can also put a source breakpoint directly in these functions before
+launching. A breakpoint in a backend that is disabled or not selected will not
+be hit. In the notepad and game examples, `yasl_run()` opens the display before
+calling the example's initialization callback; set a breakpoint in `yasl_run()`
+in `src/common/app.c` to follow that path.
+
+## Configure and build without launching
+
+1. Open the command palette (`Ctrl+Shift+P` on Linux, `Cmd+Shift+P` on macOS).
+2. Run `task: spawn`, then select **YASL: configure debug build**.
+3. Run **YASL: build** from the same task picker.
+4. Open `examples/hello.c` or a file in `src/` to use completion and navigation.
+
+The configure task runs:
+
+```sh
+meson setup build --backend=ninja --buildtype=debug
+```
+
+Meson's Ninja backend writes `build/compile_commands.json`. The root
+[.clangd](.clangd) points clangd at that directory, so it uses Meson's actual
+include paths, C standard, and enabled-backend definitions. Keep the generated
+database in the ignored build directory; no root-level copy or symlink is
+needed. The same configuration works with other clangd-based editors. See
+[clangd's compilation database setting](https://clangd.llvm.org/config#compilationdatabase).
+
+If `build/` is already configured, the configure task leaves its existing
+options in place. To change an existing build to debug, run this in Zed's
+terminal:
+
+```sh
+meson configure build -Dbuildtype=debug
+```
+
+Save edited files before building, running, or debugging. Use **YASL:
+reconfigure** to rerun Meson configuration and refresh its metadata. Meson also
+regenerates the build automatically when build definitions change.
+
+## Tasks and examples
+
+The project tasks live in [.zed/tasks.json](.zed/tasks.json). Select them with
+`task: spawn`; `task: rerun` repeats the last task. See
+[Zed's task documentation](https://zed.dev/docs/tasks) for personal keybindings.
+
+| Task | Behavior |
+| --- | --- |
+| YASL: configure debug build | Set up `build/` with Ninja and debug symbols. |
+| YASL: reconfigure | Reconfigure an existing `build/`, preserving its options. |
+| YASL: build | Compile the library, examples, and enabled tests. |
+| YASL: build for debugger | Configure symbols and disable optimization/LTO, then build. |
+| YASL: test | Build as needed and run enabled tests, printing failure logs. |
+| YASL: benchmark | Build as needed and run Meson's registered benchmarks. |
+| YASL: run hello | Build and launch `yasl-hello`. |
+| YASL: run simple window | Build and launch `yasl-example`. |
+| YASL: run tablet | Build and launch `yasl-tablet`. |
+| YASL: run notepad | Build and launch `yasl-notepad`. |
+| YASL: run game | Build and launch `yasl-game`. |
+
+Each run task builds its executable before launching and stops if compilation
+fails. Run tasks explicitly use `sh` for their compound command. All tasks use
+the repository root as their working directory, including when a nested source
+file is active.
+
+Examples need a desktop connection. On Linux, run Zed in your desktop session
+so the launched program inherits `WAYLAND_DISPLAY`/`DISPLAY` and
+`XDG_RUNTIME_DIR` as appropriate. Most tests can run without a display, but the
+currently registered `app-runner` test opens a window even in a default build.
+`app-input-destroy` also needs a Wayland compositor when `WAYLAND_DISPLAY` is
+set. Run the full suite in a desktop session with the corresponding backend
+enabled; additional tests retain their configured requirements.
+
+## Debugging
+
+The profiles in [.zed/debug.json](.zed/debug.json) use CodeLLDB. Run
+`debugger: start` from the command palette and select an example. Profiles cover
+hello, simple window, tablet, notepad, game, and the lifecycle test
+(`build/tests/yasl-test`), which needs no display. Each profile builds through
+**YASL: build for debugger** and pauses on entry.
+See [Zed's debugger documentation](https://zed.dev/docs/debugger).
+
+To debug another test, copy the lifecycle profile and change its `label` and
+`program` to the executable under `build/tests/`. To pass example arguments,
+add an `args` array to a debug profile; for example, the tablet profile accepts
+`"args": ["--backend", "x11"]` when that backend is enabled.
+
+## Backend options and additional builds
+
+Linux backend selection defaults to automatic dependency detection. To require
+X11 and disable Wayland in the IDE build, run:
+
+```sh
+meson configure build -Dx11=enabled -Dwayland=disabled
+meson compile -C build
+```
+
+Restore automatic selection with `-Dx11=auto -Dwayland=auto`. Integration tests
+are opt-in through `-Dintegration_tests=true`; their server dependencies and
+desktop requirements are documented in [Testing](docs/testing.md).
+
+For sanitizers or a different compiler, prefer a separate build directory:
+
+```sh
+meson setup build-sanitize -Db_sanitize=address,undefined
+meson test -C build-sanitize --print-errorlogs
+```
+
+The checked-in Zed tasks and profiles continue to target `build/`. To use a
+different directory throughout the IDE, update the tasks' build arguments and
+run commands, debugger program paths, and `.clangd`'s `CompilationDatabase`
+together. Ignore additional build directories locally (for example through
+`.git/info/exclude`) and keep machine-specific tool paths out of shared files.
+
+## Troubleshooting
+
+- **Missing headers or incorrect backend diagnostics:** confirm that
+ `build/compile_commands.json` exists, build successfully, then run
+ `editor: restart language server`. clangd analyzes the backend configuration
+ in that database; disabled native backends may lack their SDK headers.
+- **C23 syntax errors in the editor:** update clangd; the compiler used by Meson
+ and the clangd used by Zed are separate tools.
+- **A task cannot find Meson or a compiler:** check `command -v meson ninja cc`
+ in Zed's terminal and fix the PATH used by Zed and its task shell.
+- **No window opens:** check the desktop environment and enabled backends.
+ Use the lifecycle debug profile to check debugging without a display.
+- **`app-runner` or `app-input-destroy` fails at startup:** check that the test
+ can connect to the inherited desktop session. For a headless check of the
+ lifecycle test alone, run `meson test -C build basic --print-errorlogs`.
+- **Breakpoints do not bind:** use a **YASL: debug ...** profile so the debugger
+ build task runs, and confirm the executable and library come from `build/`.
+ Shared-library breakpoints may remain pending until the library loads. Check
+ that a native backend breakpoint belongs to the enabled, selected backend.
+- **Configuration fails on macOS:** check the SDK and deployment target against
+ [Getting started](docs/getting-started.md#build-and-run). Compiler or SDK
+ changes may require a fresh build directory.