メインコンテンツまでスキップ

Cursor での C++ 品質ゲートの設定:3 つの自動化チェック

Cursor C++ Quality Gate

C++ 開発には厳格な品質管理が必要です。このガイドでは、Cursor で毎回のコミット前に実行される 3 つの自動チェックを設定する方法を示します:ターゲットビルド、サニタイザービルド、および cppcheck を使用した静的解析。Git pre-push フックと組み合わせることで、これらのチェックによりコードが常に本番環境に対応していることを保証します。

3 つのチェック

チェック 1:ターゲットビルド

デプロイ環境と同じ設定でコードをコンパイルします。

チェック 2:サニタイザービルド

AddressSanitizer (ASan) と UndefinedBehaviorSanitizer (UBSan) を実行して、メモリエラーや未定義の動作を検出します。

チェック 3:静的解析

コードを実行せずに、cppcheck を使用してバグ、スタイル違反、潜在的な問題を見つけます。

前提条件

必要なツールをインストールします:

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y build-essential cmake cppcheck

# macOS
brew install cmake cppcheck

# Windows(MSYS2 または WSL 経由)
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-cppcheck

プロジェクト構造

my-cpp-project/
├── src/
│ ├── main.cpp
│ └── utils.cpp
├── include/
│ └── utils.h
├── tests/
│ └── test_main.cpp
├── CMakeLists.txt
├── .cursor/
│ └── quality-gate.sh
└── .git/hooks/
└── pre-push

ステップ 1:CMake 設定

ビルドプロファイルを含む CMakeLists.txt を作成します:

cmake_minimum_required(VERSION 3.14)
project(MyProject CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# ソースファイル
add_executable(myapp
src/main.cpp
src/utils.cpp
)

target_include_directories(myapp PRIVATE include)

# ターゲットビルドプロファイル(本番環境に類似)
add_library(target_profile INTERFACE)
target_compile_options(target_profile INTERFACE
-O2
-DNDEBUG
-Wall
-Wextra
-Werror
)

# サニタイザービルドプロファイル
add_library(sanitizer_profile INTERFACE)
target_compile_options(sanitizer_profile INTERFACE
-O1
-g
-fsanitize=address,undefined
-fno-omit-frame-pointer
)
target_link_options(sanitizer_profile INTERFACE
-fsanitize=address,undefined
)

# プロファイルの適用
option(USE_SANITIZER "Build with sanitizers" OFF)
if(USE_SANITIZER)
target_link_libraries(myapp sanitizer_profile)
else()
target_link_libraries(myapp target_profile)
endif()

# テスト
enable_testing()
add_executable(myapp_tests tests/test_main.cpp)
target_link_libraries(myapp_tests target_profile)
add_test(NAME unit_tests COMMAND myapp_tests)

ステップ 2:品質ゲートスクリプト

.cursor/quality-gate.sh を作成します:

#!/bin/bash
set -e

PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BUILD_DIR="$PROJECT_ROOT/build"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # 色なし

echo "=========================================="
echo " Cursor C++ Quality Gate"
echo "=========================================="

# ビルドディレクトリのクリーンアップ
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"

# チェック 1:ターゲットビルド
echo -e "\n${YELLOW}[1/3] ターゲットビルド${NC}"
echo "本番環境の設定でビルド中..."
mkdir -p "$BUILD_DIR/target"
cd "$BUILD_DIR/target"
cmake ../.. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
echo -e "${GREEN}ターゲットビルド:合格${NC}"

# テストの実行
echo "テストを実行中..."
ctest --output-on-failure
echo -e "${GREEN}テスト:合格${NC}"

# チェック 2:サニタイザービルド
echo -e "\n${YELLOW}[2/3] サニタイザービルド${NC}"
echo "AddressSanitizer と UBSan でビルド中..."
mkdir -p "$BUILD_DIR/sanitizer"
cd "$BUILD_DIR/sanitizer"
cmake ../.. -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=ON
make -j$(nproc)

echo "サニタイザー付きで実行中..."
./myapp || {
echo -e "${RED}サニタイザーがエラーを検出しました!${NC}"
exit 1
}
echo -e "${GREEN}サニタイザービルド:合格${NC}"

# チェック 3:静的解析
echo -e "\n${YELLOW}[3/3] 静的解析 (cppcheck)${NC}"
cd "$PROJECT_ROOT"

cppcheck \
--enable=all \
--suppress=missingIncludeSystem \
--error-exitcode=1 \
--inline-suppr \
--check-config \
-I include \
src/ \
tests/ \
2>&1 | tee "$BUILD_DIR/cppcheck-report.txt"

echo -e "${GREEN}静的解析:合格${NC}"

# サマリー
echo -e "\n=========================================="
echo -e "${GREEN}すべての品質ゲートに合格しました!${NC}"
echo "=========================================="
echo "ビルド成果物:$BUILD_DIR/"
echo "レポート:$BUILD_DIR/cppcheck-report.txt"

実行可能にします:

chmod +x .cursor/quality-gate.sh

ステップ 3:Git Pre-Push フック

.git/hooks/pre-push を作成します:

#!/bin/bash

echo "プッシュ前に品質ゲートを実行中..."

if [ -f ".cursor/quality-gate.sh" ]; then
bash .cursor/quality-gate.sh
exit $?
else
echo "警告:品質ゲートスクリプトが見つかりません"
exit 0
fi

実行可能にします:

chmod +x .git/hooks/pre-push

ステップ 4:Cursor との統合

Cursor タスクへの追加

.vscode/tasks.json を作成します(Cursor は VS Code タスクシステムを使用します):

{
"version": "2.0.0",
"tasks": [
{
"label": "C++ Quality Gate",
"type": "shell",
"command": "bash",
"args": [".cursor/quality-gate.sh"],
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": ["$gcc"]
},
{
"label": "Quick Build",
"type": "shell",
"command": "cmake",
"args": ["--build", "build/target", "--parallel"],
"group": "build"
},
{
"label": "Run Sanitizer Build",
"type": "shell",
"command": "bash",
"args": ["-c", "mkdir -p build/sanitizer && cd build/sanitizer && cmake ../.. -DUSE_SANITIZER=ON && make -j$(nproc) && ./myapp"],
"group": "test"
}
]
}

キーボードショートカット

.vscode/keybindings.json に追加します:

[
{
"key": "ctrl+shift+q",
"command": "workbench.action.tasks.runTask",
"args": "C++ Quality Gate"
}
]

サニタイザー出力の理解

AddressSanitizer (ASan)

検出対象:

  • 解放後の使用
  • ヒープバッファオーバーフロー
  • スタックバッファオーバーフロー
  • グローバルバッファオーバーフロー
  • リターン後の使用
  • スコープ後の使用
  • 二重解放
  • メモリリーク

出力例:

==12345==ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 4 at 0x602000000014 thread T0
#0 0x5555555551a9 in main src/main.cpp:15

UndefinedBehaviorSanitizer (UBSan)

検出対象:

  • 符号付き整数オーバーフロー
  • ゼロ除算
  • NULL ポインターの逆参照
  • アラインメントされていないポインターアクセス
  • 無効なシフト操作

出力例:

src/utils.cpp:42:15: runtime error: signed integer overflow

cppcheck のカスタマイズ

抑制コメント

コード内で:

// cppcheck-suppress unusedFunction
void debugHelper() {
// これはデバッグビルドでのみ使用される
}

// cppcheck-suppress knownConditionTrueFalse
if (x == x) { // 意図的な NaN チェック
// NaN の処理
}

設定ファイル

cppcheck-suppressions.txt を作成します:

unusedFunction:*test*
missingIncludeSystem
unmatchedSuppression

スクリプトを更新します:

cppcheck \
--enable=all \
--suppressions-list=cppcheck-suppressions.txt \
--error-exitcode=1 \
src/ tests/

CI/CD 統合

GitHub Actions

name: C++ Quality Gate

on: [push, pull_request]

jobs:
quality-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake cppcheck

- name: Run Quality Gate
run: bash .cursor/quality-gate.sh

トラブルシューティング

問題解決策
サニタイザービルドが遅すぎるより速いビルドのために -O0 の代わりに -O1 を使用する
cppcheck の誤検出抑制コメントまたは設定ファイルを追加する
フックが実行されない.git/hooks/pre-push が実行可能であることを確認する
ビルド中にメモリ不足並列ジョブを減らす:-j$(nproc) の代わりに make -j2

クイックリファレンス

# フル品質ゲートを実行
bash .cursor/quality-gate.sh

# ターゲットビルドのみを高速実行
mkdir -p build && cd build && cmake .. && make -j$(nproc)

# サニタイザー付きで実行
mkdir -p build-san && cd build-san && cmake .. -DUSE_SANITIZER=ON && make -j$(nproc) && ./myapp

# cppcheck のみを実行
cppcheck --enable=all --error-exitcode=1 src/

関連リソース