# AGENTS.md - kmake Development Guidelines This document provides guidance for AI agents working on the kmake codebase. ## Project Structure ``` kmake/ ├── kmake.yml # Example/build configuration ├── CMakeLists.txt # Build configuration ├── README.md # User documentation ├── AGENTS.md # This file └── src/ └── kmake/ ├── kmake.hpp # Core includes and namespace ├── kmake.cpp # Main entry point ├── project/ │ ├── Project.hpp # Project configuration model │ ├── Project.cpp # YAML parsing, variable resolution │ ├── Distro.hpp # Per-distro build commands │ └── Distro.cpp # Distro implementation └── build/ ├── Executor.hpp # Command execution engine └── Executor.cpp # Parallel/serial execution logic ``` ## Key Concepts ### Project Configuration (`Project`) - Loads and parses `kmake.yml` - Holds global `vars`, `build` settings, and `distros` map - Provides variable resolution with fallback: distro vars → global vars → defaults ### Distro Configuration (`Distro`) - Contains phase commands: `start`, `deps`, `compile`, `link`, `end` - Has own `vars` map that overrides global variables - Commands use `{placeholder}` substitution ### Execution Model (`Executor`) - Runs commands sequentially within a phase - `compile` phase runs in parallel (one thread per file, up to `build.threads`) - Other phases run serially - Each command is a shell command with variable expansion ## Variable Placeholders Standard placeholders available in all commands: - `{src_file}` - Current source file - `{obj_file}` - Current object file - `{obj_files}` - All object files (link phase only) - `{dep_file}` - Current dependency file - `{rv_dep_file}` - Reverse dependency file - `{out}` - Output executable path - `{bin}` - Binary directory - `{include}` - Include paths - `{cflags}` - Compiler flags - `{ldflags}` - Linker flags Custom variables from `vars` and `distros.*.vars` are also available. ## Coding Conventions ### C++ Style - Use `ckitty::` namespace utilities (string, vector, map, optional) - Follow existing naming: `PascalCase` for classes, `camelCase` for methods/variables - Use `struct` for plain data, `class` for behavior - Prefer `std::optional` over pointers for nullable values ### Error Handling - Return `bool` for success/failure in loading/parsing - Use `ckitty::optional` for lookup operations - Log errors via `desktoplib::terminal` at appropriate verbosity ### YAML Parsing - Use existing YAML library (likely yaml-cpp) - Validate required fields, provide defaults for optional - Distro names are case-sensitive keys in the `distros` map ## Building and Testing ```bash # On Windows, development is done on MSYS2 UCRT64. # Please use the dedicated script to forward commands there. ./msys2.ps1 make ``` ## Common Tasks ### Adding a New Build Phase 1. Add field to `Distro` class (vector) 2. Add field to `Project::build` struct if global config needed 3. Update `Project::load()` to parse from YAML 4. Add execution in `Executor` or main build loop 5. Document in README.md ### Adding a New Placeholder Variable 1. Add resolution logic in `Project::getVar()` or `Distro::getVar()` 2. Ensure fallback chain works: distro → global → builtin 3. Update command expansion to recognize new placeholder ### Supporting New Dependency Style 1. Add `style` enum/string to `Project::build::deps` 2. Implement generation in distro `deps` commands 3. Implement parsing in reverse dependency tracking ## Testing Checklist - [ ] Valid kmake.yml loads without errors - [ ] Variable substitution works in all phases - [ ] Parallel compilation respects thread limit - [ ] Dependency files generated correctly - [ ] Distro-specific vars override globals - [ ] Missing distro gives clear error - [ ] Verbosity levels control output correctly ## Debugging Tips - Use `-verbosity debug` to see all command expansions - Check generated dependency files in `{bin}/*.d` - Verify placeholder expansion with `echo` in start phase - Use `kmake -list` to verify parsed config