Files
2026-09-07 21:51:27 -06:00

120 lines
4.1 KiB
Markdown

# 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
├── 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<string>)
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