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

4.1 KiB

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

# 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