22 KiB
MSVC C++ Harness 환경 구축 가이드
이 문서는 Windows에서 이 Harness framework를 설치하고, C++ 제품 저장소의 MSVC 빌드·테스트 및 Codex step 실행을 준비하는 절차를 설명한다. 명령은 별도 표시가 없으면 대상 저장소 루트의 PowerShell에서 실행한다.
현재 저장소에는 실행기, 훅, 설정 예제가 있으며 실제 C++ 제품 소스, CMake/Visual
Studio 프로젝트, 실행할 phases/, Python 테스트 디렉터리는 없다. 따라서 도구
설치 확인과 실제 제품 빌드 성공을 구분해야 한다. 아래 프로젝트명·preset 이름·경로는
설정 형식을 보여 주는 예시이며, 제품의 MSVC toolset·C++ 표준·테스트 프레임워크는
아직 확정되지 않았다.
1. 필요한 환경
| 구분 | 요구 사항 | 용도 및 확인 기준 |
|---|---|---|
| 운영체제 | 선택한 Visual Studio가 지원하는 Windows | 이 가이드는 Windows 네이티브 실행과 x64 빌드를 기준으로 한다. 현재 도구 탐색은 vswhere.exe, MSBuild.exe를 사용한다. |
| 셸 | PowerShell | 설치 점검과 Windows 훅 명령 실행. 아래 UTF-8 파일 작성 예제는 PowerShell 7 기준이다. |
| Git | Windows에서 실행 가능한 Git | 저장소 탐색, branch 전환, 자동 commit. --push 사용 시에만 원격 저장소 인증이 추가로 필요하다. |
| Python | 3.10 이상, python 명령으로 실행 가능 |
실행기와 훅은 표준 라이브러리만 사용한다. 일반 실행에 pip install이나 가상환경은 필수가 아니다. |
| Codex CLI | 아래 옵션·훅 호환성 점검을 통과하는 버전 | codex exec, JSON 출력, stdin 프롬프트와 프로젝트 훅을 지원해야 한다. 로그인과 서비스 네트워크 접근이 필요하다. |
| C++ 빌드 도구 | Visual Studio 또는 Build Tools의 MSVC x64/x86 도구, MSBuild, Windows SDK | Visual Studio Installer에서 C++ 워크로드를 설치한다. VS Code만 설치해서는 충족되지 않는다. |
| CMake 방식 | CMake와 CTest 3.20 이상, 제품이 요구하는 버전 이상 | ctest --test-dir와 build/test preset 기능에 필요한 하한이다. generator와 preset schema가 더 높은 버전을 요구할 수 있다. |
| MSBuild 방식 | 실제 .sln 또는 .vcxproj, 테스트 실행 명령 |
CMake/CTest는 이 방식의 Harness 검증에 필수가 아니다. |
| 선택 도구 | Node.js/npm, Ninja, pytest/uv | Node.js/npm은 Codex의 npm 설치 방식을 선택할 때, Ninja는 해당 generator를 쓸 때만 필요하다. pytest/uv는 Harness 자체 테스트가 있는 checkout에서 사용한다. |
CMake 기능의 버전 근거는 CMake 3.20 릴리스 노트와 CTest 명령 문서를 참고한다. Windows·Visual Studio·Codex의 정확한 지원 버전 조합은 저장소에서 고정하지 않았다. 팀에서 검증한 버전은 제품 도입 시 별도로 기록한다.
2. 기본 도구 설치
Git과 Python
- Git for Windows 공식 설치 페이지에서 설치하고
PowerShell과 외부 프로그램에서
git을 실행할 수 있도록 PATH를 설정한다. - Python Windows 공식 배포 페이지에서 3.10 이상의 Python을 설치한다. 실행기뿐 아니라 자식 훅에서도 같은 Python을 찾도록 실제 설치 디렉터리를 사용자 PATH에 등록한다.
- 새 PowerShell 창을 열고 확인한다.
git --version
python --version
python -c "import sys; print(sys.executable); assert sys.version_info >= (3, 10)"
Get-Command git, python | Select-Object Name, Source
python이 Microsoft Store를 열거나 실행되지 않으면 Windows의 앱 실행 별칭과
PATH 순서를 확인한다. py만 동작하는 상태는 충분하지 않다. 현재 Windows 훅이
python 명령을 사용하기 때문이다. 가상환경을 쓰면 활성화한 동일 터미널에서
Harness를 실행한다.
Visual Studio와 C++ 도구
- Microsoft의 MSVC 설치 안내를 따라 Visual Studio Installer를 실행한다. IDE가 필요하면 Visual Studio, 명령줄 빌드만 필요하면 Build Tools 설치를 선택한다.
- C++를 사용한 데스크톱 개발(Desktop development with C++) 워크로드를 선택한다.
- 설치 세부 정보에서 MSVC x64/x86 빌드 도구, MSBuild, 제품이 요구하는 Windows SDK가
포함되는지 확인한다. 기존 제품이면 해당
PlatformToolset과 SDK 버전을 설치한다. - CMake 방식이면 Windows용 C++ CMake 도구도 선택하거나 CMake를 별도 설치한다.
설치 후 아래 조회에서 실제 설치 경로와 MSBuild.exe 경로가 나와야 한다.
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio/Installer/vswhere.exe'
Test-Path -LiteralPath $vswhere
& $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
& $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find 'MSBuild\**\Bin\MSBuild.exe'
Harness도 이 C++ component ID로 설치를 찾는다. 여러 Visual Studio 설치가 있으면
조건에 맞는 최신 설치를 선택하며, .harness/config.json에는 Visual Studio 설치 경로를
고정하는 필드가 없다. 특정 toolset 선택은 제품의 preset 또는 프로젝트 metadata에서 한다.
CMake 사용 시 추가 점검
Harness는 PATH의 cmake.exe와 ctest.exe를 우선하고, 없으면 탐색한 Visual Studio의
번들 디렉터리를 사용한다. 아래는 번들 경로를 현재 터미널 PATH에 추가하는 예시다.
$vsInstall = & $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
$cmakeBin = Join-Path $vsInstall 'Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin'
if (Test-Path -LiteralPath (Join-Path $cmakeBin 'cmake.exe')) {
$env:PATH = "$cmakeBin;$env:PATH"
}
cmake --version
ctest --version
Get-Command cmake, ctest | Select-Object Name, Source
두 도구가 같은 CMake 배포본을 가리키도록 맞춘다. 새 터미널에서도 수동 명령을 사용하려면 해당 디렉터리를 사용자 PATH에 등록한다.
Visual Studio generator와 직접 MSBuild는 설치된 도구를 활용한다. Ninja preset이나
cl.exe 직접 실행을 쓰는 경우에는 Developer PowerShell for VS 또는
x64 Native Tools Command Prompt for VS로 개발 환경을 먼저 연다. 명령 프롬프트에서
이 문서의 예제를 실행하려면 그 창에서 PowerShell을 시작한다. Harness는
VsDevCmd.bat를 자동 실행하지 않으므로 compiler/include/library 환경은 호출자에게서
상속된다. Ninja preset이면 같은 터미널에서 ninja --version도 확인한다.
3. Codex CLI 설치와 호환성 확인
공식 Codex CLI 설치 안내의 Windows 설치
방법으로 CLI를 설치한 뒤 새 터미널을 연다. npm 방식을 선택한 경우에는 먼저
Node.js 공식 배포 페이지에서 Node.js/npm을 설치한다.
Harness는 Codex 앱 설치 여부와 별개로 codex 명령을 직접 실행한다.
codex --version
codex login
codex login status
codex exec --help
codex login의 안내에 따라 인증한다. Harness 설정에는 계정이나 API 키를 넣지 않는다.
현재 실행기가 사용하는 옵션은 다음과 같다.
codex exec --json --sandbox workspace-write --dangerously-bypass-hook-trust --cd <repository-root> -
exec --help에서 이 옵션들이 지원되는지 확인한다. 저장소는 최소 Codex 버전을
선언하지 않으므로 버전 숫자만으로 호환성을 판단하지 않는다. 문서 작성 시 로컬 CLI
0.153.4에서 옵션 목록은 확인했지만, 이것이 전체 실행 검증을 의미하지는 않는다.
실행기는 셸 alias나 PowerShell 함수 대신 Python 자식 프로세스로 Codex를 호출한다. 동일한 경로로 실행 가능한지 다음 명령으로 확인한다. 모델 호출은 발생하지 않는다.
python -X utf8 -c "import subprocess; subprocess.run(['codex', '--version'], check=True)"
python -X utf8 -c "import subprocess; subprocess.run(['codex', 'exec', '--help'], check=True)"
터미널의 codex는 되는데 위 명령이 실패하면 Get-Command codex -All과
where.exe codex로 PATH를 확인한다. .ps1 alias만 보이거나 npm shim이 자식
프로세스에서 실행되지 않으면 공식 Windows 설치 방식으로 CLI를 설치하고 실제
실행 파일 디렉터리를 PATH에 등록한 뒤 다시 점검한다.
4. 저장소 준비와 훅 확인
Git으로 저장소를 clone하거나, 기존 제품 저장소에 다음 Harness 구성요소를 가져온다.
기존 AGENTS.md와 훅 설정이 있으면 제품 규칙을 유지하면서 병합한다.
AGENTS.md
.agents/skills/harness/SKILL.md
.agents/skills/review/SKILL.md
.codex/hooks.json
.harness/config.example.json
scripts/execute.py
scripts/hooks/
scripts/msvc_harness/
docs/HARNESS.md
docs/HARNESS_WORKFLOW.md
docs/ENVIRONMENT_SETUP.md
실행기와 훅이 경로를 기준으로 저장소를 찾으므로 위 배치를 유지한다. 제품 구현은
src/, 공개 header는 include/, 테스트는 tests/에 배치한다.
git rev-parse --show-toplevel
git status --short
git config user.name
git config user.email
python -X utf8 scripts/execute.py --help
Git 작성자 정보가 없으면 대상 저장소에서 아래 예시를 자신의 정보로 바꾸어 설정한다.
실제 실행 전에는 준비한 설정·phase 파일을 검토하여 commit하고, 다른 작업의 변경이
없는 전용 checkout/worktree를 사용한다. 실행기는 git add -A와 자동 commit을 수행한다.
git config --local user.name 'YOUR_NAME'
git config --local user.email 'YOUR_EMAIL'
저장소 루트에서 codex를 실행하고 /hooks에서 .codex/hooks.json의 PreToolUse와
Stop이 로드되는지 확인한다. 프로젝트 신뢰 설정과 훅의 실행 상태도 확인한다.
공식 훅 문서는 프로젝트 훅의 신뢰 요구사항과 Windows용 commandWindows 필드를
설명한다. Codex 훅 문서
현재 실행기는 검토된 자동화용 --dangerously-bypass-hook-trust를 사용한다. 실행 전
저장소 훅 내용을 확인해야 하며, 이 옵션은 비활성 훅을 활성화하거나 빌드 설정을
대신하지 않는다. 사용자·관리자 설정에서 훅이 꺼져 있거나 프로젝트 훅이 제한되면
이를 먼저 해결한다.
Windows 훅은 python -X utf8과 Git 루트 탐색을 사용한다. 따라서 Codex가 실행하는
훅 환경에서도 Python과 Git이 보여야 한다. 아래 직접 호출은 훅 스크립트의 기본 실행만
확인하며, Codex가 훅을 자동 호출하는지까지 검증하지는 않는다.
'{"tool_name":"Edit","tool_input":{"file_path":"docs/ENVIRONMENT_SETUP.md"}}' | python -X utf8 scripts/hooks/pre_tool_use.py
$LASTEXITCODE
통과 기준은 종료 코드 0이고 입력 해석 실패 메시지가 없는 것이다. C++ 편집에는
대응 테스트 파일이 먼저 필요하다. 기본 이름은 {stem}_test.cpp, {stem}_tests.cpp,
test_{stem}.cpp, {stem}.test.cpp이며 실제 실패 테스트 확인은 별도로 수행해야 한다.
5. 제품 빌드 설정
.harness/config.example.json은 모든 필드를 보여 주는 참고 자료다. MyProject.sln,
windows-debug, 테스트 실행 파일은 이 저장소에 존재하지 않으므로 그대로 복사해
완성된 설정으로 사용하지 않는다. 아래 방식 중 실제 프로젝트에 맞는 하나로
.harness/config.json을 작성한다. JSON은 UTF-8 BOM 없이, 주석 없이 저장한다.
PowerShell 7에서 텍스트를 저장할 때는 Set-Content -Encoding utf8NoBOM을 사용할 수 있다.
A. CMake, preset 없이 사용
실제 루트 CMakeLists.txt가 있는 프로젝트의 최소 설정이다.
{
"version": 1,
"projectType": "cmake",
"cmake": { "sourceDir": "." }
}
이 방식은 Harness가 .harness/build, Debug, x64를 사용한다. 프로젝트에 맞는
Visual Studio generator가 선택되는 환경에서 다음 순서로 확인한다. generator·구성·
toolset을 명확히 고정해야 하는 제품은 B 방식의 preset을 사용한다.
cmake -S . -B .harness/build -A x64
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
각 명령이 성공해야 하고, 테스트 발견 JSON의 tests 배열에는 적어도 한 개의
테스트가 있어야 한다. 제품 CMake에서 C++ 언어와 테스트를 활성화하고 실제 테스트를
등록한다. Harness는 생성된 CMakeCXXCompiler.cmake의 compiler ID가 MSVC인지
확인하므로 MinGW/GCC 또는 Clang으로 설정된 build directory는 통과하지 않는다.
B. CMake preset 사용
다음은 이미 windows-debug configure/build/test preset이 정의된 제품의 예시다.
실제 CMakePresets.json 또는 CMakeUserPresets.json의 이름과 binary directory로 바꾼다.
{
"version": 1,
"projectType": "cmake",
"cmake": {
"sourceDir": ".",
"binaryDir": "out/build/windows-debug",
"configurePreset": "windows-debug",
"buildPreset": "windows-debug",
"testPreset": "windows-debug"
}
}
binaryDir, configurePreset, buildPreset, testPreset은 네 개를 함께 지정해야 한다.
binaryDir만 바꾸는 설정은 지원하지 않는다. 세 preset은 동일한 빌드 트리를 사용해야
하며 MSVC generator/toolset·아키텍처·빌드 구성을 제품 요구에 맞게 정의한다.
CMake preset 공식 문서
아래 명령은 설정의 sourceDir에서 실행한다. 이름은 실제 preset으로 바꾼다.
cmake --list-presets
cmake --build --list-presets
ctest --list-presets
cmake --preset windows-debug
cmake --build --preset windows-debug
ctest --preset windows-debug --show-only=json-v1
ctest --preset windows-debug --output-on-failure
C. Visual Studio solution/project와 MSBuild 사용
아래 파일명·출력 경로를 실제 .sln 또는 .vcxproj와 테스트 실행 파일로 바꾼다.
테스트 프레임워크는 지정하지 않으며, 실패할 때 nonzero로 종료하는 테스트 명령이 필요하다.
{
"version": 1,
"projectType": "msbuild",
"msbuild": {
"solution": "MyProject.sln",
"configuration": "Debug",
"platform": "x64",
"testCommand": ["build/tests/Debug/MyProjectTests.exe"]
}
}
testCommand는 실행 파일과 인자를 분리한 문자열 배열이다. 명령 전체를 한 문자열로
넣거나 &&, 파이프, 셸 변수 확장을 기대하지 않는다. 작업 디렉터리는 저장소 루트다.
실행 파일에 경로를 쓰면 저장소 내부여야 하며, 파일명만 쓰면 PATH에서 찾는다.
$msbuildExe = & $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find 'MSBuild\**\Bin\MSBuild.exe' | Select-Object -First 1
& $msbuildExe MyProject.sln /m /nologo /p:Configuration=Debug /p:Platform=x64
& ./build/tests/Debug/MyProjectTests.exe
빌드와 테스트 각각의 종료 코드가 0이어야 한다. 직접 MSBuild 방식에서 CTest 등록은
필수가 아니지만 msbuild.testCommand는 필수다. 현재 탐색기는 .slnx를 지원하지 않는다.
공통 설정 점검
sourceDir, binaryDir, solution, tdd.testRoots는 저장소 상대 경로로 지정하며
저장소 밖을 가리킬 수 없다. 알 수 없는 설정 필드는 오류다. projectType: "auto"는
루트 CMake metadata → 단일 루트 .sln → 단일 루트 .vcxproj 순서로 찾는다.
하위 디렉터리 제품이나 빌드 형식이 여러 개인 저장소는 projectType과 경로를 명시한다.
구문과 설정 형식을 빌드 없이 확인한다.
python -X utf8 -m json.tool .harness/config.json
python -X utf8 -c "import sys; from pathlib import Path; sys.path.insert(0, 'scripts'); from msvc_harness.config import load_config; print(load_config(Path.cwd()))"
현재 .gitignore는 .harness/build/를 제외하지만 .harness/config.json,
out/build/, .venv/는 제외하지 않는다. 제품 저장소에서 공유할 설정과 로컬 파일·
빌드 산출물을 정하고 자동 staging 전에 필요한 ignore 규칙을 적용한다.
6. 구축 완료 확인과 최초 실행
제품 metadata와 설정을 준비한 뒤 Stop 훅 검증을 수동 실행한다. 실제 빌드·테스트와 빌드 산출물 작성이 발생한다.
python -X utf8 scripts/hooks/stop_validation.py
이 스크립트는 실패해도 프로세스 종료 코드가 0일 수 있다. 표준 출력에
"continue": false와 stopReason이 나오면 검증 실패다. C++ 파일도 metadata도 없는
초기 저장소는 빌드를 수행하지 않고 조용히 종료하므로 MSVC 검증 성공으로 기록하지
않는다. CODEX_STOP_VALIDATION_ACTIVE=1이 설정된 재진입 환경이나 docs-only 실행
문맥에서도 검증이 생략될 수 있으므로 수동 점검은 일반 터미널에서 수행한다.
제품 검증 후 실행 흐름과
Harness 스킬의 phase 형식에 맞춰 실제 작업의
phases/index.json, phases/<phase>/index.json, stepN.md를 준비한다.
context_files에는 존재하는 파일만 넣는다. 현재 checkout에는 기존 문서가 참조하는
docs/phase/README.md도 없으므로 기록은 실행기가 명시한 다음 내용을 기준으로 준비한다.
docs/phase/<phase>/handoff.md: 현재 상황, 결정과 이유, 미해결 문제, 검증 결과, 다음 시작점과 상세 기록 링크를 약 60줄로 유지한다.docs/phase/<phase>/stepN.md: 변경 파일, 결정, 검증, 실패한 접근과 이유를 기록한다.- 실행 상태의 기준은
phases/<phase>/index.json이며 인계 기록은 상태를 대신하지 않는다.
<phase>를 실제 디렉터리 이름으로 바꾸어 실행한다.
python -X utf8 scripts/execute.py <phase> --dry-run
python -X utf8 scripts/execute.py <phase>
--dry-run은 첫 pending step의 문맥 경로와 프롬프트 크기만 확인하며 Codex, Git 변경,
인증, 빌드·테스트는 실행하지 않는다. 실제 실행은 branch 전환, 파일 수정과 자동
commit을 수행한다. 원격 전송이 필요할 때만 --push를 사용한다.
구축 완료 기준은 다음과 같다.
- Python에서
codex --version과exec --help를 직접 호출할 수 있고 인증이 되어 있다. - Codex에서 프로젝트 훅이 로드되고 실제 도구 호출·종료 시 동작한다.
- 실제 제품의 MSVC build와 테스트가 성공하고 Stop 훅에서 차단 응답이 없다.
- 실제 phase의 dry-run에서 필요한 문맥을 읽고 첫 step 실행 결과와 index 상태가 일치한다.
Harness 자체를 수정하는 checkout에 Python 테스트가 있다면 별도로 아래를 실행한다.
현재 checkout에는 tests/가 없어 pytest 통과를 구축 완료 근거로 사용할 수 없다.
python -m pip install pytest
python -m pytest -v -rs
python -m compileall -q scripts
7. 자주 발생하는 문제
| 증상 | 확인 및 조치 |
|---|---|
python 또는 codex를 찾지 못함 |
새 터미널에서 PATH와 앱 실행 별칭을 확인한다. Python 자식 프로세스 점검까지 통과해야 한다. |
unexpected argument / unrecognized option |
codex exec --help로 실행기의 옵션 지원 여부를 확인하고 호환 CLI를 설치한다. |
not logged in / 인증 실패 |
Harness를 실행하는 동일 Windows 계정과 Codex 환경에서 다시 로그인한다. |
| 훅이 보이지 않거나 실행되지 않음 | /hooks, 프로젝트 신뢰, 사용자·관리자 훅 설정, commandWindows 지원과 자식 환경의 PATH를 확인한다. |
vswhere.exe 또는 MSBuild를 찾지 못함 |
Visual Studio Installer에서 C++ x64/x86 도구와 MSBuild를 설치·복구한다. 조회 결과가 빈 문자열인지도 확인한다. |
CMake가 -A x64를 거부함 |
기본 generator가 Ninja 등인지 확인한다. Visual Studio generator 환경을 사용하거나 MSVC 개발 환경과 preset을 구성한다. |
| MSVC compiler metadata 오류 | 잘못된 compiler로 configure했는지, preset의 실제 binary directory와 binaryDir가 같은지 확인한다. |
CTest discovered no tests |
제품 CMake의 테스트 활성화·등록, test preset과 구성 필터를 확인한다. 실행 파일 존재만으로는 충분하지 않다. |
| 여러 solution / build metadata 없음 | projectType과 실제 프로젝트 경로를 명시한다. C++ 파일만 복사한 상태로는 build를 검증할 수 없다. |
TDD GUARD 차단 |
대응 테스트를 먼저 추가하고 red 단계 확인 후 제품 파일을 수정한다. |
dubious ownership |
가능하면 현재 계정 소유의 checkout을 사용한다. 신뢰하는 공유 경로라면 해당 경로 하나만 Git safe.directory에 등록하고 자식 계정에서도 적용되는지 확인한다. |
| phase 또는 context 파일을 찾지 못함 | 현재 저장소에는 기본 phase가 없다. 실제 phase/index/step과 참조 파일을 먼저 작성한다. |
| 빌드·Codex 시간 초과 | Stop 검증 전체와 Codex 호출 각각의 제한은 1,800초다. 로그의 실패 단계와 도구 경로를 확인한다. |
운영 중 재시도, error/blocked 복구와 상태 기록은
Harness 운영 가이드와 실행 흐름을 참고한다.