diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5207126 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,141 @@ +# 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 +# Configure +cmake -B build -S . + +# Build +cmake --build build -j4 + +# Run +./build/kmake [options] + +# Run with specific distro(s) +./build/kmake linux-gcc windows-msvc + +# Set verbosity (debug, high, normal, low) +./build/kmake -verbosity normal + +# Show version +./build/kmake -version + +# List available distros +./build/kmake -list + +# Print project description and authors +./build/kmake -descr +``` + +## 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 \ No newline at end of file diff --git a/README.md b/README.md index 8da5afc..31c0656 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,169 @@ # kmake -Kitty Make, build automation application \ No newline at end of file +Kitty Make - A modern, flexible build automation application written in C++. + +## Overview + +kmake is a build automation tool designed to simplify the compilation and linking process for C/C++ projects. It uses a declarative YAML configuration file (`kmake.yml`) to define build parameters, targets, and per-platform/distro build commands. + +## Features + +- **Declarative Configuration**: Define builds in `kmake.yml` using YAML +- **Multi-platform Support**: Configure different build commands per distro/platform +- **Parallel Compilation**: Multi-threaded compilation with configurable thread count +- **Dependency Tracking**: Automatic dependency generation and tracking +- **Variable Substitution**: Use `{placeholders}` in commands for dynamic values +- **Distro-specific Overrides**: Override global settings per distribution + +## Configuration (`kmake.yml`) + +```yaml +name: '' # Project name +author: '' # Primary author +authors: [''] # List of authors +descr: + - '' # Project description (multi-line) +verbosity: normal # debug, high, normal, low + +build: + src: + path: './src' # Source directory + targets: ['c','cpp'] # File extensions to compile + out: + path: './out' # Output directory + target: 'exe' # Final output extension + bin: + path: './bin' # Object files directory + target: 'o' # Object file extension + deps: + path: './bin' # Dependency files directory + target: 'd' # Dependency file extension + rev_target: 'rd' # Reverse dependency extension + style: gcc # Dependency generation style (gcc/msvc) + threads: 4 # Parallel compilation threads (0 = disabled) + +vars: # Global variables for placeholder substitution + key: value + +distros: # Per-distro/platform configuration + distro_name: + vars: {} # Override global variables + start: [] # Commands run before build + deps: [] # Dependency generation commands + compile: [] # Per-file compilation commands (parallel) + link: [] # Linking commands + end: [] # Post-build commands +``` + +## Variable Placeholders + +Use `{placeholder}` syntax in commands for dynamic substitution: + +- `{src_file}` - Current source file path +- `{obj_file}` - Current object file path +- `{obj_files}` - All object files (space-separated, link phase only) +- `{dep_file}` - Current dependency file path +- `{rv_dep_file}` - Reverse dependency file path +- `{out}` - Output executable path +- `{bin}` - Binary/object directory +- `{include}` - Include directories +- `{cflags}` - Compiler flags +- `{ldflags}` - Linker flags +- Custom variables from `vars` and `distros.*.vars` + +## Build Phases + +1. **start** - Setup commands (create directories, etc.) +2. **deps** - Generate dependency files for each source file +3. **compile** - Compile each source file to object file (parallelizable) +4. **link** - Link object files into final executable +5. **end** - Cleanup, packaging, testing commands + +## Example: Linux GCC Distro + +```yaml +distros: + linux-gcc: + vars: + cflags: '-Wall -Wextra -O2' + ldflags: '' + start: + - 'mkdir -p {bin} {out}' + deps: + - 'gcc {cflags} -MM -MG -MP -MT {obj_file} -MF {dep_file} {src_file}' + compile: + - 'gcc {cflags} -c {src_file} -o {obj_file}' + link: + - 'gcc {ldflags} -o {out} {obj_files}' + end: + - 'echo "Build complete: {out}"' +``` + +## Example: Windows MSVC Distro + +```yaml +distros: + windows-msvc: + vars: + cflags: '/W4 /O2' + ldflags: '' + start: + - 'if not exist {bin} mkdir {bin}' + - 'if not exist {out} mkdir {out}' + deps: + - 'cl {cflags} /showIncludes {src_file} 2>nul | findstr /R "^Note: including file:" > {dep_file}' + compile: + - 'cl {cflags} /c {src_file} /Fo{obj_file}' + link: + - 'link {ldflags} /OUT:{out} {obj_files}' + end: + - 'echo Build complete: {out}' +``` + +## Usage + +```bash +# Build with default distro +kmake + +# Build with specific distro(s) +kmake linux-gcc windows-msvc + +# Set verbosity (debug, high, normal, low) +kmake -verbosity normal + +# Show version +kmake -version + +# List available distros +kmake -list + +# Print project description and authors +kmake -descr +``` + +## Architecture + +- **Project** - Parses and holds `kmake.yml` configuration +- **Distro** - Per-platform build command sets with variable overrides +- **Executor** - Runs command sequences (serial per phase, parallel for compile) +- **Variables** - Global and per-distro variable resolution with placeholders + +## Requirements + +- C++17 compatible compiler +- CMake 3.16+ +- ckitty library +- desktoplib library + +## Building + +```bash +mkdir build && cd build +cmake .. +make -j4 +``` + +## License + +MIT License \ No newline at end of file diff --git a/kmake.code-workspace b/kmake.code-workspace index 7ff0a6a..b38155f 100644 --- a/kmake.code-workspace +++ b/kmake.code-workspace @@ -2,6 +2,12 @@ "folders": [ { "path": "." + }, + { + "path": "../ckittylib" + }, + { + "path": "../desktoplib" } ], "settings": {