(cmake-generators)=

# CMake Generators

Yanga uses a modular system of CMake Generators to create the build files for a project. Each generator is a Python class responsible for producing a specific set of CMake commands and targets. They are configured per platform in the `yanga.yaml` file, allowing for different build pipelines for different targets (e.g., one for building an executable, another for running tests).

Below is an overview of the main CMake generators available in Yanga.

## `CreateExecutableCMakeGenerator`

This generator is responsible for creating a single executable for a specific variant. It compiles all components of the variant as object libraries and then links them together into one executable file.

**Use Case:** Building the final application for a product variant.

**Configuration:**

```yaml
platforms:
  - name: my_executable_platform
    generators:
      - step: CreateExecutableCMakeGenerator
        module: yanga.cmake.create_executable
        config:
          # If true, all include directories are added globally.
          # If false, includes are handled on a per-component basis.
          use_global_includes: true
```

## `GTestCMakeGenerator`

This generator facilitates unit testing using the Google Test framework. For each testable component, it builds a separate test executable. It also includes a powerful auto-mocking feature that uses [clanguru](https://github.com/cuinixam/clanguru) to generate mocks for dependencies, isolating the component under test.

**Use Case:** Running unit tests and generating coverage reports for individual components.

**Configuration:**

```yaml
platforms:
  - name: test_platform
    generators:
      - step: GTestCMakeGenerator
        module: yanga.cmake.gtest
        config:
          # Enable/disable auto-mocking for all components.
          # This can be overridden in each component's 'testing' section.
          mocking:
            enabled: true
            strict: false # If true, clanguru parsing errors are fatal.
            exclude_symbol_patterns: ["_*"] # Symbols to exclude from mocking.
```

## `CppCheckCMakeGenerator`

This generator integrates `cppcheck`, a static analysis tool for C/C++ code. It creates targets to run `cppcheck` on a per-component basis and for the entire variant. The results are generated as XML and then converted to Markdown for inclusion in reports.

**Use Case:** Performing static code analysis to find bugs and improve code quality.

**Configuration:**

This generator is typically added as a step without specific configuration.

```yaml
platforms:
  - name: analysis_platform
    generators:
      - step: CppCheckCMakeGenerator
        module: yanga.cmake.cppcheck
```

## `ReportCMakeGenerator`

This generator orchestrates the creation of comprehensive HTML reports for both individual components and the entire variant. It uses Sphinx to collect and render various artifacts generated by other steps, such as:

* User-provided documentation (e.g., Markdown files).
* Source code documentation (component sources or generated by the auto-mocker).
* Static analysis reports (from `CppCheckCMakeGenerator`).
* Test and coverage reports (from `GTestCMakeGenerator`).

**Use Case:** Generating detailed documentation and quality assurance reports.

**Configuration:**

This generator is typically added as a step without specific configuration.

```yaml
platforms:
  - name: report_platform
    generators:
      # It is recommended to run this generator after all other generators
      # that produce reports (e.g., GTest, CppCheck).
      - step: ReportCMakeGenerator
        module: yanga.cmake.reports
```

## Auto-emitted targets

Some targets are emitted by Yanga unconditionally — they do not need to be configured per platform in `yanga.yaml`.

### `<component>_clean`

For every component in the variant, Yanga emits a custom target that removes the component's outputs without touching the rest of the variant:

```bash
cmake --build <variant_build_dir> --target <component>_clean
```

The target carries no `DEPENDS`, so invoking it never triggers a build. It removes:

1. **The per-component output namespace** — `${CMAKE_BUILD_DIR}/<component>/`. This is where generators (gtest, cppcheck, reports, ...) write artifacts produced by tools cmake/ninja does not track (gcovr, sphinx-build, `cmake -E copy_directory`, ...).
2. **CMake-derived outputs of tagged targets** — for every `add_library` / `add_executable` whose generator passed `component_name=<component>`, the target removes the intermediate dir `${CMAKE_BUILD_DIR}/CMakeFiles/<target>.dir/` (object files, depfiles, link inputs) and, for executables, the runtime artifact `$<TARGET_FILE:<target>>`.

If you write a custom CMake generator that emits per-component `add_library` or `add_executable`, pass `component_name=component.name` so its outputs are picked up. Anything written outside both the per-component dir and a tagged cmake target's own outputs is invisible to this target.

Variant-level `add_library` / `add_executable` outputs (e.g. the variant executable `${PROJECT_NAME}`) are owned by the buildsystem's own `clean` target, not by `<component>_clean`.

For a full wipe of the variant build directory (e.g. configure is broken after a variant rename or schema change) use `yanga run --pristine`, which removes the build dir from outside cmake before re-invoking the pipeline.
