Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions .kilo/skills/benchmarks/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ You now have expertise in running and interpreting Pixie benchmarks. Follow thes

## Build Directory Convention

Uses the same suffix convention as the cmake skill:
Use a short commit hash suffix for committed revisions:

```bash
BUILD_SUFFIX=local
BUILD_SUFFIX=$(git rev-parse --short HEAD)
```

If the worktree has uncommitted changes, append a descriptive suffix so results
cannot be confused with a clean HEAD build:

```bash
BUILD_SUFFIX=$(git rev-parse --short HEAD)-dirty
```

If not a git repository, use

```bash
BUILD_SUFFIX=agent
```

## CRITICAL: Never Run Benchmarks from a Debug Build
Expand All @@ -27,10 +40,10 @@ BUILD_SUFFIX=local

If benchmarks affected by the changes are easily tractable build only related targets.

**Pure timing (benchmarks-all, Release):**
**Pure timing (benchmarks, Release):**
```bash
cmake -B build/benchmarks-all_${BUILD_SUFFIX} -DCMAKE_BUILD_TYPE=Release -DPIXIE_BENCHMARKS=ON
cmake --build build/benchmarks-all_${BUILD_SUFFIX} --config Release -j
cmake -B build/benchmarks_${BUILD_SUFFIX} -DCMAKE_BUILD_TYPE=Release -DPIXIE_BENCHMARKS=ON
cmake --build build/benchmarks_${BUILD_SUFFIX} --config Release -j
```

**Hardware counters / verbose report (benchmarks-diagnostic, RelWithDebInfo, Linux only):**
Expand Down Expand Up @@ -69,10 +82,10 @@ Binary paths vary by generator type:

```bash
# Multi-config (MSVC/Xcode)
build/benchmarks-all_${BUILD_SUFFIX}/Release/benchmarks
build/benchmarks_${BUILD_SUFFIX}/Release/benchmarks

# Single-config (Ninja/Make)
build/benchmarks-all_${BUILD_SUFFIX}/benchmarks
build/benchmarks_${BUILD_SUFFIX}/benchmarks
```

### Filter benchmarks with a regex (FILTER parameter)
Expand All @@ -81,10 +94,10 @@ build/benchmarks-all_${BUILD_SUFFIX}/benchmarks
FILTER="BM_Rank" # change to match benchmark names, e.g. "BM_Select", "BM_Louds", ""

# Multi-config
build/benchmarks-all_${BUILD_SUFFIX}/Release/benchmarks --benchmark_filter="${FILTER}"
build/benchmarks_${BUILD_SUFFIX}/Release/benchmarks --benchmark_filter="${FILTER}"

# Single-config
build/benchmarks-all_${BUILD_SUFFIX}/benchmarks --benchmark_filter="${FILTER}"
build/benchmarks_${BUILD_SUFFIX}/benchmarks --benchmark_filter="${FILTER}"
```

Examples:
Expand All @@ -110,7 +123,7 @@ build/benchmarks-diagnostic_${BUILD_SUFFIX}/RelWithDebInfo/benchmarks \
### Save results to file

```bash
build/benchmarks-all_${BUILD_SUFFIX}/Release/benchmarks \
build/benchmarks_${BUILD_SUFFIX}/Release/benchmarks \
--benchmark_filter="${FILTER}" \
--benchmark_report_aggregates_only=true \
--benchmark_display_aggregates_only=true \
Expand Down Expand Up @@ -167,7 +180,7 @@ perf script -F +pid > perf.data.txt
## Best Practices

1. **Never run from a Debug binary**: always use `--config Release` at build time; check path contains `Release/`
2. **Use benchmarks-all for clean timing**: Release optimizations, no debug info, no libpfm overhead
2. **Use benchmarks for clean timing**: Release optimizations, no debug info, no libpfm overhead
3. **Use benchmarks-diagnostic for hardware counters**: RelWithDebInfo + libpfm; Linux only
4. **Use perf for deep profiling**: when counters point to a hotspot but don't explain it
5. **Pin CPU frequency** before timing runs: `sudo cpupower frequency-set -g performance`
Expand Down
23 changes: 18 additions & 5 deletions .kilo/skills/cmake/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ You now have expertise in building and configuring CMake projects. Follow these

## Build Directory Convention

Always use a suffix to keep build directories isolated per machine/user:
Use a short commit hash suffix for committed revisions:

```bash
BUILD_SUFFIX=local # change per machine, e.g. "ci", "john", "avx2"
BUILD_SUFFIX=$(git rev-parse --short HEAD)
```

If the worktree has uncommitted changes, append a descriptive suffix so generated
artifacts cannot be confused with a clean HEAD build:

```bash
BUILD_SUFFIX=$(git rev-parse --short HEAD)-dirty
```

If not a git repository, use

```bash
BUILD_SUFFIX=agent
```

Build directories follow the pattern `build/<preset_name>_<suffix>`.
Expand Down Expand Up @@ -55,10 +68,10 @@ cmake -B build/coverage_${BUILD_SUFFIX} -DCMAKE_BUILD_TYPE=Debug -DPIXIE_BENCHMA
cmake --build build/coverage_${BUILD_SUFFIX} -j
```

All benchmarks (mirrors `benchmarks-all` preset):
Benchmarks (mirrors `benchmarks` preset):
```bash
cmake -B build/benchmarks-all_${BUILD_SUFFIX} -DCMAKE_BUILD_TYPE=Release -DPIXIE_BENCHMARKS=ON
cmake --build build/benchmarks-all_${BUILD_SUFFIX} -j
cmake -B build/benchmarks_${BUILD_SUFFIX} -DCMAKE_BUILD_TYPE=Release -DPIXIE_BENCHMARKS=ON
cmake --build build/benchmarks_${BUILD_SUFFIX} -j
```

## Additional Feature Options
Expand Down
137 changes: 137 additions & 0 deletions .kilo/skills/setup-cpp-repo/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
name: setup-cpp-repo
description: Scaffold a new C++20 repository with CMake, Google Test, Google Benchmark, CI workflows, Doxygen docs, and Chromium code style. Use when the user asks to create a new C++ project, set up a C++ library, or initialize a C++ repository with modern tooling.
---

# setup-cpp-repo

## Overview

This skill generates a complete C++20 project scaffold following the conventions of the Pixie succinct data structures library. The generated repository is header-only by default and includes:

- CMake build system with presets
- Google Test for unit testing
- Google Benchmark for performance benchmarks
- Doxygen documentation with doxygen-awesome-css theme
- GitHub Actions CI workflows (ASan, lint, coverage, docs)
- Chromium C++ code style via `.clang-format`
- `AGENTS.md` for AI coding assistant guidelines

## When to Use This Skill

Use this skill when:
- The user wants to create a new C++ library or project from scratch
- The user asks for a "C++ project template" or "C++ repo setup"
- The user needs CMake + Google Test + benchmark scaffolding
- The user wants to follow Pixie-style conventions (header-only, AVX-512 optional, Doxygen docs)

Do **not** use this skill when:
- Working with an existing codebase (use the `cmake` skill instead)
- The project is not C++ (use a different skill)
- The user only wants a single file or snippet

## Workflow

### Step 1: Gather Parameters

Ask the user for (or infer from context):
- **Project name** (required): Hyphenated lowercase identifier, e.g., `my-lib`
- **Namespace** (optional): C++ namespace. Defaults to project name with hyphens removed, e.g., `mylib`
- **Output directory** (optional): Where to create the project. Defaults to current directory.

### Step 2: Run the Generator

Execute the generation script:

```bash
python3 .kilo/skills/setup-cpp-repo/scripts/init_cpp_project.py \
--name <project-name> \
[--namespace <namespace>] \
[--output-dir <directory>]
```

Example:
```bash
python3 .kilo/skills/setup-cpp-repo/scripts/init_cpp_project.py \
--name succinct-lib --namespace succinct --output-dir .
```

### Step 3: Verify the Scaffold

After generation, the project structure should look like:

```
<project-name>/
├── CMakeLists.txt
├── CMakePresets.json
├── .clang-format
├── .gitignore
├── README.md
├── AGENTS.md
├── include/
│ └── <namespace>/
│ └── <project_snake>.hpp
├── src/
│ ├── tests/
│ │ └── unittests.cpp
│ ├── benchmarks/
│ │ └── benchmarks.cpp
│ └── docs/
│ ├── Doxyfile.in
│ └── images/
├── scripts/
│ └── coverage_report.sh
└── .github/
└── workflows/
├── build-test.yml
├── linter.yml
├── coverage.yml
└── doxygen.yml
```

### Step 4: Initial Build and Test

Change into the project directory and run an initial build to verify everything works:

```bash
cd <project-name>
cmake --preset release
cmake --build --preset release -j
./build/release/unittests
```

If the build and tests pass, the scaffold is ready.

### Step 5: Hand Off to cmake Skill

After project creation, use the **`cmake` skill** (`.kilo/skills/cmake/SKILL.md`) for all subsequent build operations. The `cmake` skill documents:
- Build directory conventions with git short-hash suffixes
- How to replicate preset settings with custom build directories
- AddressSanitizer, coverage, and benchmark workflows
- Best practices for out-of-source builds

## Customization Guide

### Adding More Test Executables

Edit `CMakeLists.txt` and add new `add_executable` blocks under the `if(<PROJECT_UPPER>_TESTS)` section, following the pattern of the existing `unittests` target.

Update `scripts/coverage_report.sh` to run any new test binaries.

Update `.github/workflows/build-test.yml` to execute new test binaries in CI.

### Adding More Benchmark Executables

Edit `CMakeLists.txt` and add new `add_executable` blocks under the `if(<PROJECT_UPPER>_BENCHMARKS)` section, following the pattern of the existing `benchmarks` target.

### Adding Third-Party Dependencies

For header-only libraries, prefer `FetchContent` in `CMakeLists.txt`. For compiled libraries, consider vendoring or using a package manager (Conan, vcpkg).

### Modifying Doxygen Configuration

Edit `src/docs/Doxyfile.in`. The generated version is intentionally minimal (only non-default settings). Add or override settings as needed. Run `doxygen -g` to see all available options.

## Reference

See `references/project_structure.md` for a detailed breakdown of every generated file and its purpose.
116 changes: 116 additions & 0 deletions .kilo/skills/setup-cpp-repo/references/project_structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Generated Project Structure Reference

This document describes every file and directory generated by `init_cpp_project.py` and its purpose.

## Root Files

### `CMakeLists.txt`
Main CMake configuration. Defines:
- C++20 standard requirements
- `MARCH` cache variable (defaults to `native`)
- `DISABLE_AVX512` option for SIMD fallback
- `ENABLE_ADDRESS_SANITIZER` option for ASan builds
- `<PROJECT_UPPER>_COVERAGE` option for gcov instrumentation
- Build options: `<PROJECT_UPPER>_TESTS`, `<PROJECT_UPPER>_BENCHMARKS`, `<PROJECT_UPPER>_DIAGNOSTICS`, `<PROJECT_UPPER>_DOCS`
- FetchContent dependencies: Google Test, Google Benchmark, spdlog (diagnostics only), Doxygen theme
- Test executable: `unittests`
- Benchmark executable: `benchmarks`
- Custom target: `docs` (when Doxygen is enabled)

### `CMakePresets.json`
CMake presets (version 4) with a hidden `base` preset. Defines presets for:
- `debug` — Debug build
- `release` — Release build
- `benchmarks` — Release with benchmarks enabled
- `benchmarks-diagnostic` — RelWithDebInfo with diagnostics and libpfm
- `docs` — Documentation build
- `coverage` — Debug with coverage instrumentation
- `asan` — Debug with AddressSanitizer

### `.clang-format`
Chromium-based C++ formatting configuration. Simplified from the full Chromium style by removing Windows-specific include priorities and IPC macro block definitions. Key settings:
- `BasedOnStyle: Chromium`
- `Standard: Cpp11`
- `InsertBraces: true`
- `InsertNewlineAtEOF: true`
- `IncludeBlocks: Regroup` with generic priority categories

### `.gitignore`
Standard C++ project ignores:
- `build/`, `.vscode/`, `Testing/`
- `plans/*`, `venv/`, `docs/*`
- `CMakeUserPresets.json`
- `_deps/`, gcov outputs (`*.gcda`, `*.gcno`, `*.gcov`)

### `README.md`
Minimal project README used as the Doxygen main page.

### `AGENTS.md`
Project documentation for AI coding assistants. Contains:
- Project overview and architecture conventions
- Technology stack (C++20, CMake, Google Test, Google Benchmark)
- Build commands with all CMake options
- Testing patterns and style guidelines
- Common tasks for AI agents (adding components, modifying SIMD code, adding tests)
- Performance philosophy

## Directories

### `include/<namespace>/`
Header-only library API. Contains a placeholder header (`<project_snake>.hpp`) with:
- Doxygen file documentation
- Example function in the project's namespace
- `#pragma once` guard

### `src/tests/`
Unit test scaffold. Contains `unittests.cpp` with:
- Google Test includes
- Basic assertion test against the placeholder header
- `gtest_main` supplies the test runner entry point

### `src/benchmarks/`
Benchmark scaffold. Contains `benchmarks.cpp` with:
- Google Benchmark includes
- Example benchmark using `benchmark::DoNotOptimize`
- `BENCHMARK_MAIN()` macro

### `src/docs/`
Doxygen configuration. Contains:
- `Doxyfile.in` — Trimmed Doxygen config (~300 lines vs. 1100+ in full). Only non-default settings are specified. Key templated values:
- `PROJECT_NAME`
- `INPUT` (points to `include/` and `README.md`)
- `STRIP_FROM_PATH` (strips source dir from file paths)
- `IMAGE_PATH`
- `HTML_EXTRA_STYLESHEET` (doxygen-awesome-css)
- `USE_MDFILE_AS_MAINPAGE`
- `images/` — Empty directory for documentation images

### `scripts/`
Utility scripts. Contains:
- `coverage_report.sh` — Runs the `coverage` CMake preset, executes tests, and generates gcov reports. Excludes `_deps/`, `third_party/`, and `src/benchmarks/` from coverage.

### `.github/workflows/`
CI/CD workflows:

#### `build-test.yml`
Builds the project with AddressSanitizer and runs unit tests on `ubuntu-latest`. Triggered on pushes and PRs to `main`.

#### `linter.yml`
Runs `clang-format --dry-run --Werror` on all C/C++ files. Triggered on pushes to `main` and all PRs.

#### `coverage.yml`
Runs the coverage script and uploads results to Codecov. Also uploads coverage artifacts. Triggered on pushes and PRs to `main`.

#### `doxygen.yml`
Installs Doxygen, builds documentation with the `docs` preset, and deploys HTML output to GitHub Pages. Triggered on pushes to `main` and manual dispatch.

## Template Substitution

All generated files use these placeholders, replaced by the script:

| Placeholder | Example input | Example output |
|-------------|---------------|----------------|
| `{{PROJECT_NAME}}` | `my-lib` | `my-lib` |
| `{{NAMESPACE}}` | `mylib` | `mylib` |
| `{{PROJECT_NAME_UPPER}}` | `MY_LIB` | `MY_LIB` |
| `{{HEADER_NAME}}` | `my_lib.hpp` | `my_lib.hpp` |
Loading
Loading