Skip to content

Commit 817ae1c

Browse files
docs: add AGENTS.md
1 parent b2fcb7e commit 817ae1c

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# instrument-hooks
2+
3+
Zig library that compiles to a single-file C library (`dist/core.c`) for controlling CodSpeed instrumentations via IPC. Consumed as FFI by integrations in multiple languages (Python, Rust, C/C++, etc.).
4+
5+
## Build & Test
6+
7+
```bash
8+
zig build # Build (outputs zig-out/lib/core.c)
9+
zig build test --summary all # Run tests
10+
just release # Build + generate dist/core.c
11+
just cmake-run-example # Build and run the C example via CMake
12+
just bazel-run-example # Build and run the C example via Bazel
13+
just test-valgrind # Compile example with gcc/clang and run under valgrind
14+
just fmt # Format Zig source
15+
```
16+
17+
Requires **Zig 0.14+**. Optional: [Just](https://github.com/casey/just) for convenience commands.
18+
19+
## Architecture
20+
21+
### Source layout
22+
23+
- `src/c.zig` — C FFI export layer. All public API functions are defined here with `pub export fn`.
24+
- `src/instrument_hooks.zig` — Main `InstrumentHooks` struct combining all subsystems.
25+
- `src/instruments/root.zig` — Instrumentation backend union (valgrind, perf, analysis, none). Fallback chain: valgrind > analysis > perf > none.
26+
- `src/instruments/{valgrind,perf,analysis}.zig` — Individual backends.
27+
- `src/runner_fifo.zig` — IPC protocol with the CodSpeed runner via Unix named pipes.
28+
- `src/fifo.zig` — Low-level Unix pipe reader/writer with bincode serialization.
29+
- `src/shared.zig` — Protocol types (`Command` union, `MarkerType`, version).
30+
- `src/bincode.zig` — Bincode binary serialization (port of qbradley/bincode-zig).
31+
- `src/environment/root.zig` — Key-value integration/toolchain metadata and linked library collection, serialized to JSON.
32+
- `src/environment/linked_libraries/root.zig` — Collects metadata about dynamically linked libraries (path, soname, build ID, verdef).
33+
- `src/environment/linked_libraries/elf_view.zig` — Read-only ELF navigation helper for parsing in-memory program headers (PT_DYNAMIC, PT_NOTE, DT_VERDEF). Portable across all Linux architectures.
34+
- `src/environment/linked_libraries/testdata/test_lib.c` — Minimal C source compiled into a test fixture `.so` by `build.zig`. Linked into the test binary so it appears in `dl_iterate_phdr` for ElfView tests.
35+
- `src/features.zig` — Runtime feature flags (bit set).
36+
- `src/logger.zig` — Simple leveled logging via C `printf`.
37+
- `src/utils.zig` — Low-level utilities (clock_gettime, sleep).
38+
- `src/root.zig` — Test runner entry point (imports all modules for testing).
39+
40+
### Headers & distribution
41+
42+
- `includes/core.h` — Manually maintained C API header. Must be updated when adding/removing exported functions.
43+
- `includes/compat.h` — Cross-platform compatibility macros.
44+
- `includes/valgrind.h`, `includes/callgrind.h` — Valgrind client request headers.
45+
- `dist/core.c` — Generated single-file C library. Linux gets the full Zig-transpiled implementation, Windows/macOS get stubs from `scripts/stub.c`.
46+
- `scripts/release.py` — Combines generated C, stubs, and valgrind wrapper into `dist/core.c`.
47+
- `scripts/stub.c` — Stub implementations for Windows/macOS. Must be updated when adding exported functions.
48+
49+
### IPC protocol
50+
51+
Communication with the CodSpeed runner happens over two named pipes:
52+
- `/tmp/runner.ctl.fifo` — Commands (hooks -> runner)
53+
- `/tmp/runner.ack.fifo` — Acknowledgments (runner -> hooks)
54+
55+
Messages use bincode serialization with `[u32 length][payload]` framing. Protocol version: 2.
56+
57+
## Conventions
58+
59+
### Adding a new exported function
60+
61+
1. Implement the logic in the appropriate module.
62+
2. Add the `pub export fn` wrapper in `src/c.zig`. Return `u8` status codes (0 = success, non-zero = error).
63+
3. Add the declaration in `includes/core.h`.
64+
4. Add a stub in `scripts/stub.c`.
65+
5. Run `just release` to regenerate `dist/core.c`.
66+
67+
### Code style
68+
69+
- Zig code is formatted with `zig fmt`.
70+
- C/C++ code follows Google style (`.clang-format`), pointer-left alignment.
71+
- Pre-commit hooks enforce formatting and build checks.
72+
- Error handling at FFI boundary: return `u8` (0 = ok, 1 = error). Never panic in release builds (`std.debug.no_panic`).
73+
- Memory: `std.heap.c_allocator` in production, `std.testing.allocator` in tests.
74+
- Hot paths (FIFO read/write) use pre-allocated buffers to avoid allocations.
75+
76+
### Testing
77+
78+
- Tests live alongside the code in each `.zig` file.
79+
- `src/root.zig` imports all modules to run all tests.
80+
- `build.zig` compiles a test fixture shared library (`libtest_fixture.so`) from `src/environment/linked_libraries/testdata/test_lib.c` and links it into the test binary. ElfView tests use `dl_iterate_phdr` to find it at runtime — no file parsing, same code path as production.
81+
- CI tests across multiple platforms (Linux x86/ARM, macOS, Windows), compiler versions (GCC 9-15, Clang 13-19), and cross-compilation targets.
82+
83+
### Commit messages
84+
85+
Follow conventional commits. Reference Linear issues when applicable (inferred from branch name).

0 commit comments

Comments
 (0)