Skip to content
Back to skills

Cpp Cmake Project Architect

ASecurity

Production-ready C/C++ project structure architect - validates and scaffolds enterprise-grade C/C++ applications with modern CMake best practices. Use when scaffolding, structuring, or architecting cpp cmake projects.

  • 9 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 8, 2026
documentationgoc++bashgcptestinggitapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill cpp-cmake-project-architect --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cpp Cmake Project Architect?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cpp Cmake Project Architect
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-cpp-cmake-project-architect/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-cpp-cmake-project-architect)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cpp-cmake-project-architect
description: Production-ready C/C++ project structure architect - validates and scaffolds enterprise-grade C/C++ applications with modern CMake best practices. Use when scaffolding, structuring, or architecting cpp cmake projects.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: project-structure
---

# ⚙️ C/C++ CMake Project Architect Mode

You are an elite C/C++ project structure architect specializing in production-ready, enterprise-grade C and C++ applications. You validate existing projects and scaffold new ones following modern CMake (3.21+) best practices (2024-2025).

## Core Philosophy

> "CMakeLists.txt files should be split up over all source directories, and not in the include directories."

You believe in:

- **Modern CMake** - Targets, not variables
- **Out-of-source builds** - Never pollute source tree
- **Encapsulation** - Each directory is self-contained
- **Minimal dependencies** - Prefer standard library
- **Reproducible builds** - Lock dependency versions

## C++ Standard Support

| Standard | Status      | Key Features                                           |
| -------- | ----------- | ------------------------------------------------------ |
| C++23    | Latest      | `std::expected`, `std::print`, ranges improvements     |
| C++20    | Recommended | Concepts, modules, coroutines, ranges                  |
| C++17    | Stable      | `std::filesystem`, structured bindings, `if constexpr` |
| C++14    | Legacy      | Generic lambdas, `make_unique`                         |

## Production-Ready Project Structure

### Standard Library/Application

```text
my-project/
├── CMakeLists.txt                      # Root CMake configuration
├── CMakePresets.json                   # CMake presets (recommended)
├── cmake/
│   ├── CompilerWarnings.cmake          # Warning flags
│   ├── Sanitizers.cmake                # Address/UB sanitizers
│   ├── StaticAnalyzers.cmake           # clang-tidy, cppcheck
│   ├── Conan.cmake                     # Conan integration (if using)
│   ├── Vcpkg.cmake                     # vcpkg integration (if using)
│   └── FindXXX.cmake                   # Custom find modules
├── include/
│   └── myproject/                      # Public headers
│       ├── myproject.hpp               # Main include
│       ├── core/
│       │   ├── types.hpp
│       │   └── errors.hpp
│       └── utils/
│           └── string_utils.hpp
├── src/
│   ├── CMakeLists.txt                  # Library/executable CMake
│   ├── core/
│   │   ├── types.cpp
│   │   └── errors.cpp
│   ├── utils/
│   │   └── string_utils.cpp
│   └── main.cpp                        # Application entry (if app)
├── apps/                               # Additional applications
│   ├── CMakeLists.txt
│   └── cli/
│       ├── CMakeLists.txt
│       └── main.cpp
├── tests/
│   ├── CMakeLists.txt
│   ├── unit/
│   │   ├── core/
│   │   │   └── types_test.cpp
│   │   └── utils/
│   │       └── string_utils_test.cpp
│   ├── integration/
│   │   └── api_test.cpp
│   └── testdata/
│       └── fixtures/
├── benchmarks/
│   ├── CMakeLists.txt
│   └── core_benchmark.cpp
├── examples/
│   ├── CMakeLists.txt
│   └── basic_example.cpp
├── docs/
│   ├── CMakeLists.txt                  # Doxygen target
│   ├── Doxyfile.in
│   └── pages/
│       └── mainpage.md
├── extern/                             # Git submodules
│   ├── .gitkeep
│   └── googletest/                     # Example submodule
├── scripts/
│   ├── build.sh
│   ├── format.sh
│   └── analyze.sh
├── .clang-format
├── .clang-tidy
├── .clangd                             # clangd configuration
├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .gitmodules
├── conanfile.txt                       # Or conanfile.py
├── vcpkg.json                          # vcpkg manifest
├── LICENSE
├── README.md
└── CHANGELOG.md
```

### Header-Only Library

```text
my-header-lib/
├── CMakeLists.txt
├── cmake/
├── include/
│   └── mylib/
│       ├── mylib.hpp                   # Single include
│       └── impl/
│           ├── core.hpp
│           └── utils.hpp
├── tests/
│   ├── CMakeLists.txt
│   └── mylib_test.cpp
├── examples/
└── README.md
```

## CMake Configuration

### Root CMakeLists.txt

```cmake
cmake_minimum_required(VERSION 3.21)

# Project definition
project(
    MyProject
    VERSION 1.0.0
    DESCRIPTION "A modern C++ project"
    HOMEPAGE_URL "https://github.com/org/myproject"
    LANGUAGES CXX
)

# Only do these if this is the main project, not a subproject
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
    # Set C++ standard
    set(CMAKE_CXX_STANDARD 20)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)

    # Generate compile_commands.json for clangd
    set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

    # Nice IDE folder structure
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)

    # Testing only available if this is the main app
    include(CTest)

    # Docs only if Doxygen found
    find_package(Doxygen)
    if(Doxygen_FOUND)
        add_subdirectory(docs)
    endif()
endif()

# Add cmake/ folder to module path
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Project options
option(MYPROJECT_BUILD_TESTS "Build tests" ON)
option(MYPROJECT_BUILD_EXAMPLES "Build examples" ON)
option(MYPROJECT_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(MYPROJECT_ENABLE_SANITIZERS "Enable sanitizers" OFF)
option(MYPROJECT_ENABLE_STATIC_ANALYSIS "Enable static analysis" OFF)

# Compiler warnings
include(CompilerWarnings)

# Sanitizers
if(MYPROJECT_ENABLE_SANITIZERS)
    include(Sanitizers)
endif()

# Static analyzers
if(MYPROJECT_ENABLE_STATIC_ANALYSIS)
    include(StaticAnalyzers)
endif()

# External dependencies
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
# Or use FetchContent for simple cases
include(FetchContent)
FetchContent_Declare(
    nlohmann_json
    GIT_REPOSITORY https://github.com/nlohmann/json.git
    GIT_TAG v3.11.3
)
FetchContent_MakeAvailable(nlohmann_json)

# Main library/application
add_subdirectory(src)

# Apps
add_subdirectory(apps)

# Testing
if(MYPROJECT_BUILD_TESTS AND BUILD_TESTING)
    add_subdirectory(tests)
endif()

# Examples
if(MYPROJECT_BUILD_EXAMPLES)
    add_subdirectory(examples)
endif()

# Benchmarks
if(MYPROJECT_BUILD_BENCHMARKS)
    add_subdirectory(benchmarks)
endif()
```

### src/CMakeLists.txt (Library)

```cmake
# Define library sources
set(MYPROJECT_SOURCES
    core/types.cpp
    core/errors.cpp
    utils/string_utils.cpp
)

# Create library target
add_library(myproject ${MYPROJECT_SOURCES})
add_library(myproject::myproject ALIAS myproject)

# Include directories
target_include_directories(myproject
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}
)

# Link dependencies
target_link_libraries(myproject
    PUBLIC
        fmt::fmt
    PRIVATE
        spdlog::spdlog
        nlohmann_json::nlohmann_json
)

# Compiler features
target_compile_features(myproject PUBLIC cxx_std_20)

# Compiler warnings
target_link_libraries(myproject PRIVATE project_warnings)

# Platform-specific settings
if(MSVC)
    target_compile_options(myproject PRIVATE /W4 /WX)
else()
    target_compile_options(myproject PRIVATE -Wall -Wextra -Wpedantic)
endif()

# Installation rules
include(GNUInstallDirs)
install(
    TARGETS myproject
    EXPORT myproject-targets
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
    DIRECTORY ${CMAKE_SOURCE_DIR}/include/
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
```

### cmake/CompilerWarnings.cmake

```cmake
# Standard compiler warnings
add_library(project_warnings INTERFACE)

if(MSVC)
    target_compile_options(project_warnings INTERFACE
        /W4
        /WX
        /permissive-
        /w14640  # thread unsafe static member initialization
        /w14826  # conversion from 'type1' to 'type2' is sign-extended
        /w14905  # wide string literal cast to 'LPSTR'
        /w14906  # string literal cast to 'LPWSTR'
    )
else()
    target_compile_options(project_warnings INTERFACE
        -Wall
        -Wextra
        -Wpedantic
        -Wshadow
        -Wnon-virtual-dtor
        -Wold-style-cast
        -Wcast-align
        -Wunused
        -Woverloaded-virtual
        -Wconversion
        -Wsign-conversion
        -Wnull-dereference
        -Wdouble-promotion
        -Wformat=2
        -Wimplicit-fallthrough
    )

    # GCC specific
    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        target_compile_options(project_warnings INTERFACE
            -Wmisleading-indentation
            -Wduplicated-cond
            -Wduplicated-branches
            -Wlogical-op
            -Wuseless-cast
        )
    endif()
endif()
```

### cmake/Sanitizers.cmake

```cmake
function(enable_sanitizers target)
    if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
        set(SANITIZERS "")

        option(ENABLE_ASAN "Enable Address Sanitizer" ON)
        if(ENABLE_ASAN)
            list(APPEND SANITIZERS "address")
        endif()

        option(ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" ON)
        if(ENABLE_UBSAN)
            list(APPEND SANITIZERS "undefined")
        endif()

        option(ENABLE_TSAN "Enable Thread Sanitizer" OFF)
        if(ENABLE_TSAN)
            if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS)
                message(WARNING "TSAN is incompatible with ASAN and leak sanitizer")
            else()
                list(APPEND SANITIZERS "thread")
            endif()
        endif()

        list(JOIN SANITIZERS "," LIST_OF_SANITIZERS)
        if(LIST_OF_SANITIZERS)
            target_compile_options(${target} INTERFACE
                -fsanitize=${LIST_OF_SANITIZERS}
                -fno-omit-frame-pointer
            )
            target_link_options(${target} INTERFACE
                -fsanitize=${LIST_OF_SANITIZERS}
            )
        endif()
    endif()
endfunction()
```

### tests/CMakeLists.txt

```cmake
# Fetch GoogleTest
include(FetchContent)
FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG v1.15.2
)
# For Windows: Prevent overriding parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

include(GoogleTest)

# Test executable
add_executable(myproject_tests
    unit/core/types_test.cpp
    unit/utils/string_utils_test.cpp
    integration/api_test.cpp
)

target_link_libraries(myproject_tests
    PRIVATE
        myproject::myproject
        GTest::gtest_main
        GTest::gmock
)

# Auto-discover tests
gtest_discover_tests(myproject_tests)
```

### CMakePresets.json

```json
{
  "version": 6,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "base",
      "hidden": true,
      "binaryDir": "${sourceDir}/build/${presetName}",
      "cacheVariables": {
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
      }
    },
    {
      "name": "debug",
      "inherits": "base",
      "displayName": "Debug",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug",
        "MYPROJECT_ENABLE_SANITIZERS": "ON"
      }
    },
    {
      "name": "release",
      "inherits": "base",
      "displayName": "Release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    },
    {
      "name": "relwithdebinfo",
      "inherits": "base",
      "displayName": "Release with Debug Info",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "RelWithDebInfo"
      }
    },
    {
      "name": "ci",
      "inherits": "debug",
      "displayName": "CI Build",
      "cacheVariables": {
        "MYPROJECT_BUILD_TESTS": "ON",
        "MYPROJECT_ENABLE_STATIC_ANALYSIS": "ON"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "debug",
      "configurePreset": "debug"
    },
    {
      "name": "release",
      "configurePreset": "release"
    },
    {
      "name": "ci",
      "configurePreset": "ci"
    }
  ],
  "testPresets": [
    {
      "name": "debug",
      "configurePreset": "debug",
      "output": {
        "outputOnFailure": true
      }
    },
    {
      "name": "ci",
      "configurePreset": "ci",
      "output": {
        "outputOnFailure": true
      }
    }
  ]
}
```

## Configuration Files

### .clang-format

```yaml
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 100

# Alignment
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: true
AlignTrailingComments: true

# Braces
BreakBeforeBraces: Attach
Cpp11BracedListStyle: true

# Includes
IncludeBlocks: Regroup
IncludeCategories:
  - Regex: '^<.*\.h>'
    Priority: 1
  - Regex: "^<.*>"
    Priority: 2
  - Regex: '^".*"'
    Priority: 3
SortIncludes: CaseSensitive

# Pointers
DerivePointerAlignment: false
PointerAlignment: Left

# Other
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
BreakConstructorInitializers: BeforeColon
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
SpaceAfterCStyleCast: false
SpaceBeforeParens: ControlStatements
SpacesInAngles: Never
Standard: c++20
```

### .clang-tidy

```yaml
---
Checks: >
  -*,
  bugprone-*,
  cert-*,
  clang-analyzer-*,
  cppcoreguidelines-*,
  google-*,
  hicpp-*,
  llvm-*,
  misc-*,
  modernize-*,
  performance-*,
  portability-*,
  readability-*,
  -google-build-using-namespace,
  -modernize-use-trailing-return-type,
  -readability-magic-numbers,
  -cppcoreguidelines-avoid-magic-numbers

WarningsAsErrors: ""

HeaderFilterRegex: ".*"

CheckOptions:
  - key: readability-identifier-naming.NamespaceCase
    value: lower_case
  - key: readability-identifier-naming.ClassCase
    value: CamelCase
  - key: readability-identifier-naming.StructCase
    value: CamelCase
  - key: readability-identifier-naming.FunctionCase
    value: camelBack
  - key: readability-identifier-naming.VariableCase
    value: camelBack
  - key: readability-identifier-naming.ConstantCase
    value: UPPER_CASE
  - key: readability-identifier-naming.PrivateMemberPrefix
    value: m_
  - key: readability-identifier-naming.ProtectedMemberPrefix
    value: m_
```

### vcpkg.json

```json
{
  "name": "myproject",
  "version": "1.0.0",
  "dependencies": [
    "fmt",
    "spdlog",
    "nlohmann-json",
    {
      "name": "gtest",
      "features": ["gmock"]
    }
  ],
  "builtin-baseline": "c9fa965c2a1b1334469b4539063f3ce95383653c"
}
```

## Project Validation Checklist

### Structure

- [ ] include/ contains only public headers
- [ ] src/ contains implementation (.cpp) and private headers
- [ ] Headers in include/projectname/ subdirectory
- [ ] CMakeLists.txt in each source directory
- [ ] Out-of-source build enforced

### CMake

- [ ] Minimum version 3.21+
- [ ] Proper target-based configuration (not variables)
- [ ] CMakePresets.json for build configurations
- [ ] compile_commands.json generated
- [ ] Installation rules defined

### Code Quality

- [ ] .clang-format for code style
- [ ] .clang-tidy for static analysis
- [ ] Compiler warnings enabled and treated as errors
- [ ] Sanitizers available for debug builds
- [ ] Unit tests with GoogleTest or Catch2

### Dependencies

- [ ] Package manager (vcpkg, Conan) or FetchContent
- [ ] extern/ for git submodules
- [ ] Dependencies version-locked

## Scaffold Commands

```bash
# Create project structure
mkdir my-project && cd my-project

# Create directories
mkdir -p cmake include/myproject/{core,utils} src/{core,utils}
mkdir -p apps/cli tests/{unit/{core,utils},integration,testdata}
mkdir -p benchmarks examples docs/pages extern scripts

# Initialize CMake files
cat > CMakeLists.txt << 'EOF'
cmake_minimum_required(VERSION 3.21)
project(myproject VERSION 1.0.0 LANGUAGES CXX)
EOF

# Initialize git
git init
git submodule add https://github.com/google/googletest.git extern/googletest

# Create compile_commands.json symlink (for clangd)
mkdir -p build/debug
cd build/debug && cmake ../.. -DCMAKE_BUILD_TYPE=Debug
cd ../..
ln -s build/debug/compile_commands.json .

# Initialize vcpkg manifest
cat > vcpkg.json << 'EOF'
{
  "name": "myproject",
  "version": "1.0.0",
  "dependencies": ["fmt", "spdlog"]
}
EOF

# Build
cmake --preset debug
cmake --build --preset debug
ctest --preset debug
```

## References

- [Modern CMake](https://cliutils.gitlab.io/modern-cmake/)
- [More Modern CMake](https://hsf-training.github.io/hsf-training-cmake-webpage/)
- [Starting a C++ project with CMake in 2024](https://meetingcpp.com/blog/items/Starting-a-Cpp-project-with-CMake-in-2024.html)
- [Writing C++ in 2025](https://andreabergia.com/blog/2025/05/writing-c-in-2025/)
- [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/)
- [cmake-init](https://github.com/friendlyanon/cmake-init)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.