Claude Media
Claude CodeでC++を開発する — CMake presetsとctestを検証コマンドにする

Claude CodeでC++を開発する — CMake presetsとctestを検証コマンドにする

Claude CodeにC++を書かせるとき、CMakePresets.jsonでビルド設定を固定し、cmake --presetとctest --presetをCLAUDE.mdの検証コマンドにする運用を設定例つきでまとめます。

C++の検証コマンドをpresetsに寄せる理由

C++プロジェクトでClaude Codeに変更を任せると、最初につまずくのはビルドの呼び方です。ジェネレーター、ビルドタイプ、ビルドディレクトリを毎回指示文に書くと、セッションごとに微妙に違う cmake が走り、build/、build2/、out/ が散らかります。

CMakeには、この設定をファイルに固定する仕組みがあります。CMakePresets.json です。ここに設定を書いておけば、Claude Codeに渡す検証コマンドは cmake --preset debug のような短い定型に収まります。

手順

presetsで検証を固定する流れ

  1. 1

    CMakePresets.jsonを置く

    ジェネレーターとビルドディレクトリをconfigure presetに書きます。

  2. 2

    build presetとtest presetを足す

    ビルドとテストの呼び方も名前で固定します。

  3. 3

    CLAUDE.mdに3行書く

    configure、build、testの各コマンドを検証手順として書きます。

  4. 4

    permissionsで許可する

    定型のコマンドだけを確認なしで通します。

この記事は、CMakeとC++のコンパイラーが手元で動く前提です。Claude Code自体の導入はClaude Code完全ガイドにあります。

CMakePresets.jsonとは何か

CMake presetsは、プロジェクトの共通のconfigure方法を共有するためのファイルです。CMake 3.19で導入され、CMakePresets.json と CMakeUserPresets.json の2つを使います。どちらもプロジェクトのルートに置き、書式は同じです。

役割は分かれています。

ファイル想定する中身Gitでの扱い
CMakePresets.json想定する中身プロジェクト全体で共有するビルド設定Gitでの扱いコミットしてよい
CMakeUserPresets.json想定する中身開発者個人のローカル設定Gitでの扱いコミットせず .gitignore に入れる

CMakeUserPresets.json は、include を書かなくても CMakePresets.json を暗黙に取り込みます。個人環境の差分だけをユーザー側に置き、共有側のpresetを inherits で継ぐ構成が取れます。

presetの種類は5つあります。configure、build、test、package、workflowです。build presetとtest presetはCMake 3.20、package presetとworkflow presetは3.25で加わりました。ルートの version が新しい機能の下限を決めるので、使うCMakeのバージョンに合わせて数字を選びます。

最小のCMakePresets.jsonを書く

動かすために必要なのは、configure presetとそれに紐づくbuild preset、test presetです。次は、共有の土台をhiddenにして、デバッグとリリースを継がせる例です。

{
  "version": 6,
  "configurePresets": [
    {
      "name": "base",
      "hidden": true,
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/${presetName}"
    },
    {
      "name": "debug",
      "inherits": "base",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
    },
    {
      "name": "release",
      "inherits": "base",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
    }
  ],
  "buildPresets": [
    { "name": "debug", "configurePreset": "debug" },
    { "name": "release", "configurePreset": "release" }
  ],
  "testPresets": [
    {
      "name": "debug",
      "configurePreset": "debug",
      "output": { "outputOnFailure": true },
      "execution": { "noTestsAction": "error" }
    }
  ]
}

ポイントは4つです。

  • hidden: true のpresetは --preset に指定できず、GUIにも出ません。generator や binaryDir が無くてもよく、継承元専用になります
  • binaryDir に相対パスを書くとソースディレクトリからの相対になります。ここでは ${sourceDir}/build/${presetName} とし、presetごとにビルドディレクトリが分かれるようにしました
  • build presetとtest presetは configurePreset を持ち、ビルドディレクトリは対応するconfigure presetの binaryDir から決まります。ディレクトリを2か所に書く必要はありません
  • noTestsAction を error にすると、テストが1つも見つからないときの扱いがコマンドラインの --no-tests=error と同じになります

Ninjaを使う場合は、ninja コマンドが入っている必要があります。入っていない環境では generator を Unix Makefiles などに置き換えます。

ビルドとテストを呼ぶコマンド

presetを作ったら、呼び出しはどれも名前を指定するだけです。

cmake --list-presets          # 使えるconfigure presetの一覧
cmake --preset debug          # configure
cmake --build --preset debug  # build
ctest --preset debug          # test

cmake --preset は、CMakeLists.txtがあるソースのルートで実行します。-S を使うと別のディレクトリを指定できます。presetが決めたジェネレーターや変数は、コマンドラインで個別に上書きもできます。

ctest --preset と cmake --build --preset は、ビルドディレクトリをconfigure presetから推定します。そのため -B build/debug や --test-dir を書く必要がありません。ctestのリファレンスでは、--test-dir を併記すると、configure presetのものとは別のビルドディレクトリを指定できるとしています。

一覧の確認は種類ごとに別のオプションです。cmake --list-presets はconfigure、cmake --build --list-presets はbuild、ctest --list-presets はtestを列挙します。Claude Codeに「どのpresetがあるか」を調べさせるときは、この3つを使い分けます。

3コマンドを1つにまとめるworkflow preset

configure、build、testを毎回3回呼ぶのが煩わしければ、workflow presetで1コマンドにできます。

"workflowPresets": [
  {
    "name": "check",
    "steps": [
      { "type": "configure", "name": "debug" },
      { "type": "build", "name": "debug" },
      { "type": "test", "name": "debug" }
    ]
  }
]

実行は cmake --workflow --preset check です。CMake 3.31以降は --preset を省略して cmake --workflow check とも書けます。

制約も押さえておきます。最初のステップは必ずconfigureで、以降のステップは、その開始時のconfigure presetを参照するbuild、test、packageに限られます。workflow presetを使うにはルートの version を6以上にする必要があります。

検証の入口を1コマンドにしたいときに向きます。ただし、ビルドエラーとテスト失敗のどちらで止まったのかを切り分けたいときは、3コマンドに分けたほうが原因を追いやすくなります。

CLAUDE.mdに書くこと

CLAUDE.md は毎回のセッションに文脈として読み込まれる指示です。Claude Codeのメモリのドキュメントでは、具体的で検証できる書き方のほうが守られやすいとされています。「ビルドして確認する」ではなく、実行するコマンドそのものを書きます。目安は1ファイル200行以内です。

C++向けの例を示します。

# CLAUDE.md
## ビルドと検証(変更のたびに実行)
- configure: cmake --preset debug
- build: cmake --build --preset debug
- test: ctest --preset debug
- 失敗したテストだけ再実行: ctest --preset debug --rerun-failed
## ビルドディレクトリ
- ビルド成果物は build/<preset名>/ だけに出す。他の場所に cmake -B を作らない
- CMakePresets.json は編集前に相談する。個人設定は CMakeUserPresets.json に置く

この書き方の狙いは2つあります。

1つ目は、ビルドディレクトリを増やさないことです。cmake -B で場所を自由に決められる状態だと、指示のたびにビルドディレクトリが増えていきます。「build/<preset名>/ だけ」と範囲を書いておくと、散らかりを抑えやすくなります。ただし CLAUDE.md は強制ではなく文脈なので、守られなかった場合に備えて .gitignore に build/ を入れておきます。

2つ目は、失敗の再実行を絞ることです。ctestの --rerun-failed は、直前の実行で失敗したテストだけを再実行します。このオプションを指定すると、-R や -E などテスト選択のオプションは無視されます。失敗が出た後に全体を回し直すより、修正が効いたかを素早く確かめられます。

検証コマンドを決めて回す考え方は、Claude Codeのverifyコマンドの記事でも扱っています。

permissionsで定型コマンドだけを通す

検証コマンドが決まれば、確認なしで実行させる範囲も絞れます。権限ルールは Bash(コマンド *) の形で、* を引数の位置に置きます。

{
  "permissions": {
    "allow": [
      "Bash(cmake --preset *)",
      "Bash(cmake --build --preset *)",
      "Bash(ctest --preset *)",
      "Bash(cmake --list-presets)"
    ]
  }
}

これを .claude/settings.json に置きます。ここで許可しているのはpreset経由の呼び出しだけで、cmake -B のようにディレクトリを自由に指定する形は含まれません。ビルドディレクトリを固定する運用と、権限の設計が同じ方向を向きます。

* は引数の部分に一致するため、cmake --preset debug -DCMAKE_BUILD_TYPE=Release のように上書きを足した呼び出しも、上のルールに合致します。上書きまで禁じたい場合は、CLAUDE.md の規約とレビュー時の確認で補います。

OSごとにpresetを出し分ける

WindowsとLinuxで同じリポジトリを使うなら、condition でpresetの有効条件を書けます。conditionはCMake 3.21(version 3)で加わった項目で、configure、build、testの各presetに付けられます。

{
  "name": "windows-only",
  "inherits": "base",
  "condition": {
    "type": "equals",
    "lhs": "${hostSystemName}",
    "rhs": "Windows"
  }
}

${hostSystemName} はCMake 3.21で加わったマクロです。条件に合わない環境ではそのpresetが使えないので、Claude Codeが別のOSの設定を誤って呼ぶ事態を、CLAUDE.md の注意書きに頼らず避けられます。

個人の環境差は CMakeUserPresets.json に分けます。共有側の debug を inherits で継いで、コンパイラーのパスだけを上書きする形です。このファイルは .gitignore に入れ、Claude Codeには編集の前に相談させます。

つまずきやすい点

presetsで困るのは、書式のバージョンとCMake本体のバージョンの食い違いです。

症状の例確認すること
workflow presetが読めない確認することルートの version が6以上か。CMakeは3.25以上か
$comment を書くと読み込みに失敗する確認すること$comment は version 10(CMake 3.31)で加わった項目。ルートの version が足りているか
--preset に指定したpresetが選べない確認することhidden: true になっていないか
build presetやtest presetが見つからない確認することconfigurePreset の綴りと、継承元の指定
テスト0件で成功扱いになる確認することtest presetの noTestsAction を error にする

CMakeのバージョンが古い環境では、使える version の上限も下がります。CLAUDE.md に「必要なCMakeの最低バージョン」を書いておくと、Claudeが新しい書式の機能を持ち込んで失敗するのを避けられます。

もう1つは、CMakeUserPresets.json を誤ってコミットする事故です。個人の絶対パスやツールチェーンの場所を書くファイルなので、.gitignore に入れておきます。Claude Codeにファイルを追加させるときも、このファイル名を触らせないよう CLAUDE.md に書いておくと安全です。

実装を任せるときの進め方

最初のセッションでは、presetが先、コードが後です。空のディレクトリで「CMakePresets.jsonを作って、cmake --preset debug から ctest --preset debug まで通る最小の構成にして」と頼み、3つのコマンドが実際に成功するところまでClaude Codeに実行させます。

その後に機能の実装を任せると、変更のたびに同じ3コマンドが走ります。テストが無い箇所に手を入れるときは、先にテストを書かせてから実装させると、noTestsAction: error の設定がそのまま保険として働きます。C++を使うQtアプリの開発でも、言語は違いますがUnityのゲーム開発でも、検証コマンドを軸にする考え方は同じです。

まとめ

C++のビルド設定は、人にとっても散らかりやすい部分です。CMakePresets.json に集約すると、Claude Codeへの指示は cmake --preset、cmake --build --preset、ctest --preset の3行で済み、ビルドディレクトリの置き場所も1か所に決まります。CLAUDE.md は検証手順の置き場所、permissionsは通す範囲の線引きと役割を分けて考えると、運用が崩れにくくなります。

この記事を共有:XはてブLinkedIn