개발 환경 설정
에디터·컴파일러·링커의 역할을 이해하고 VS Code에서 C++ 소스를 빌드하고 실행하는 개발 환경을 단계별로 구성합니다.
앞 절에서 C++이 어떤 언어인지, 그리고 어디에 활용되는지 개괄적으로 살펴봤습니다.
이제는 C++ 코드를 직접 작성하고 실행하기 위한 준비 단계로 넘어가겠습니다.
건축가가 건물을 짓기 위해 설계 도구와 자재를 준비하듯이, 프로그래머도 코드를 작성하기 위한 적절한 도구와 환경이 필요합니다.
이 장에서는 C++ 개발에 필요한 핵심 도구를 정리하고, 컴퓨터에 개발 환경을 설정하는 과정을 단계별로 안내합니다.
먼저 전체 흐름을 보면, C++ 개발 환경은 코드를 쓰는 도구와 실행 파일을 만드는 도구를 하나의 경로로 연결하는 작업입니다.
BUILD PIPELINE
한 번의 g++ 명령 안에서도 번역과 링크는 구별되며, 실행은 빌드가 끝난 뒤의 별도 단계입니다.
- 전처리
#include와 매크로를 처리해 컴파일할 번역 단위를 준비합니다. - 컴파일과 어셈블
C++를 목적 코드로 바꿉니다.
-c를 쓰면 링크하지 않고 목적 파일에서 멈출 수 있습니다. - 링크
목적 코드와 필요한 C++ 라이브러리를 연결해
hello.exe를 만듭니다. - 실행
PowerShell의
.\hello.exe가 빌드 결과를 시작하고 Windows가 프로그램을 적재합니다.
g++ main.cpp -o hello.exe처럼 한 번에 링크하면 목적 파일이 별도 파일로 남지 않을 수 있지만, 번역과 링크의 책임은 여전히 구분됩니다.C++ 개발을 위한 핵심 도구들
C++ 코드를 작성하고 실행하려면 다음 역할을 맡는 도구가 필요합니다.
- 텍스트 에디터(Text Editor): 소스 코드를 작성하고 탐색합니다. 문법 강조와 자동 완성 같은 편집 기능을 제공할 수 있습니다.
- 컴파일러 도구 모음(Compiler Toolchain): 전처리, 컴파일, 어셈블 단계를 거쳐 소스를 목적 코드로 바꿉니다.
g++같은 컴파일러 드라이버는 이 단계들과 링커 호출을 한 명령으로 조정할 수 있습니다. - 링커(Linker): 목적 코드와 필요한 라이브러리를 연결해 실행 파일을 만듭니다.
- 디버거(Debugger): 실행 중인 프로그램을 멈추고 호출 흐름과 변수 값을 관찰합니다.
통합 개발 환경(IDE)은 이런 도구를 한 화면에서 호출하고 결과를 연결해 줍니다. 다만 IDE나 에디터 자체가 언제나 컴파일러를 포함하는 것은 아니므로, 사용하는 편집기와 별도로 툴체인을 설치해야 할 수 있습니다.
C++ 컴파일러 소개
C++ 소스는 전처리, 컴파일, 어셈블을 거쳐 목적 코드가 되고, 링크 단계에서 라이브러리와 결합해 실행 파일이 됩니다. 컴파일러 드라이버는 이 도구들을 순서대로 호출합니다.
주요 C++ 컴파일러는 다음과 같습니다.
- GCC: GNU Compiler Collection의 C++ 드라이버는
g++입니다. 이 문서의 Windows 실습에서는 MSYS2가 제공하는 MinGW-w64 빌드를 사용합니다. 예:g++ myprogram.cpp -o myprogram.exe - Clang: LLVM 프로젝트의 C++ 컴파일러 드라이버는
clang++입니다. 예:clang++ myprogram.cpp -o myprogram - MSVC: Microsoft의 C++ 컴파일러 드라이버는
cl이며 Visual Studio 또는 Build Tools와 함께 설치할 수 있습니다. 예:cl myprogram.cpp
프로젝트의 대상 운영체제, 사용하는 라이브러리와 빌드 시스템, 팀의 배포 환경에 맞는 툴체인을 선택하고 공식 문서의 지원 범위를 확인합니다.
통합 개발 환경 (IDE) 소개
IDE는 코드 편집, 컴파일, 디버깅 등의 기능을 통합적으로 제공하는 소프트웨어입니다.
도구의 예로는 MSVC 툴체인을 연결하는 Visual Studio, 외부 툴체인과 확장을 조합하는 Visual Studio Code, CMake 등의 빌드 시스템과 통합하는 CLion과 Eclipse CDT가 있습니다.
제품 이름만으로 우열을 정하기보다 대상 플랫폼, 필요한 디버거와 빌드 시스템, 라이선스 조건을 각 공식 문서에서 확인해 선택합니다. 아래 실습은 도구 사이의 연결을 직접 확인하기 쉬운 VS Code와 MSYS2의 UCRT64 툴체인을 사용합니다.
개발 환경 설정 단계(VS Code)

- VS Code 공식 다운로드 페이지에서 현재 운영체제용 설치 프로그램을 내려받아 설치합니다.

- VS Code에서 확장(Extensions) 보기를 엽니다.
- C/C++를 검색해 Microsoft의
ms-vscode.cpptools확장을 설치합니다. 이 확장은 편집·IntelliSense·디버깅 기능을 제공하지만 컴파일러 자체를 설치하지는 않습니다.
- 이 실습의 명령과 설정은 x86_64 PC의 64비트 Windows 10 1809 이상 또는 Windows 11에서 UCRT64 환경을 사용하는 경우를 기준으로 합니다. Windows 11 ARM64의 MSYS2 지원은 별도 CLANGARM64 환경과 패키지를 사용하는 예비 지원 단계이므로 MSYS2 ARM64 안내를 따릅니다.
- MSYS2 공식 설치 페이지에서 최신 GUI 설치 프로그램을 내려받고 안내에 따라 설치합니다. 고정된 과거 버전 URL은 사용하지 않습니다.
- 설치가 끝나면 MSYS2 UCRT64 터미널을 열고 아래 명령으로 x86_64 UCRT64 툴체인을 설치합니다.
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
- 그룹 구성과 패키지 개수는 갱신될 수 있습니다.
Enter a selection (default=all)프롬프트에서는Enter를 눌러 현재 그룹의 기본 전체 선택을 수락합니다.

- 거래 요약 뒤
Proceed with installation? [Y/n]프롬프트에서는Y또는Enter를 눌러 설치를 진행합니다. 스크린샷의 버전과 개수보다 현재 터미널 출력과 공식 패키지 그룹을 기준으로 확인합니다.
- 사용자 환경 변수의
Path에 UCRT64의bin폴더를 추가합니다.
C:\msys64\ucrt64\bin- 다른 설치 폴더를 선택했다면 이
Path뿐 아니라 아래 예제의compilerPath, build task의command,miDebuggerPath에 있는C:\msys64또는C:/msys64도 실제 설치 루트로 모두 바꿉니다. - 열려 있던 터미널을 닫고 새 터미널에서 설치 결과를 확인합니다.
gcc --version
g++ --version
gdb --version- 새 폴더 생성 후 VS Code로 열기
.vscode폴더에c_cpp_properties.json,tasks.json,launch.json을 만듭니다. 아래 예제는 현재 활성 소스 파일 하나를 같은 폴더의 같은 이름.exe로 빌드하고 디버그합니다.
{
"configurations": [
{
"name": "GCC",
"includePath": ["${workspaceFolder}/**"],
"compilerPath": "C:/msys64/ucrt64/bin/g++.exe",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe 활성 파일 빌드",
"command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
"args": [
"-fdiagnostics-color=always",
"-std=c++20",
"-Wall",
"-Wextra",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "디버거에서 생성된 작업입니다."
}
],
"version": "2.0.0"
}{
"configurations": [
{
"name": "C/C++: g++.exe 활성 파일 빌드 및 디버그",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "C:/msys64/ucrt64/bin/gdb.exe",
"setupCommands": [
{
"description": "gdb에 자동 서식 지정 사용",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "디스어셈블리 버전을 Intel(으)로 설정",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++.exe 활성 파일 빌드"
}
],
"version": "0.2.0"
}세 파일의 version은 같은 값을 공유하는 앱 버전이 아니라 서로 다른 설정 스키마 버전입니다. C/C++ 설정 명세, 작업 스키마, 디버그 구성 명세에 따라 이 예제에서는 c_cpp_properties.json이 숫자 4, tasks.json이 문자열 2.0.0, launch.json이 문자열 0.2.0을 사용합니다.
c_cpp_properties.json은 IntelliSense가 참고할 컴파일러와 표준을 정하고, 실제 빌드 명령은 tasks.json이 실행합니다. launch.json은 그 빌드 결과를 GDB로 시작합니다. 따라서 compilerPath와 build task의 command, cppStandard와 -std 인수, task의 -o 출력과 program, task label과 preLaunchTask를 각각 짝으로 맞춥니다. includePath는 IntelliSense 검색 범위일 뿐 GCC의 include 경로를 바꾸지 않으므로, 소스 상대 경로나 시스템 경로 밖의 헤더를 쓴다면 build task에도 대응하는 -I 인수를 추가하거나 빌드 시스템에서 함께 관리합니다.
VS Code의 공식 MinGW 안내에 따라 작업 폴더의 *.cpp 와일드카드를 컴파일러 인수로 직접 넘기지 않았습니다. 2024년 11월 3일부터 MSYS2 mingw-w64 프로그램은 와일드카드 인수 확장을 기본으로 비활성화했으므로, tasks.json의 args에 ${workspaceFolder}/*.cpp를 직접 넣어도 Bash의 glob 확장처럼 동작하지 않습니다. 파일이 여러 개인 프로젝트는 소스를 명시적으로 나열하거나 CMake·Make 같은 빌드 시스템으로 전환합니다.
CONFIG CONTRACT
세 JSON 파일은 같은 일을 반복하지 않습니다. 각 파일의 책임과 서로 맞아야 하는 값만 구분합니다.
| 파일 | 결정하는 것 | 일치시킬 값 |
|---|---|---|
c_cpp_properties.json |
IntelliSense가 참고할 컴파일러, include 경로, C++ 표준 | compilerPath와 cppStandard를 실제 빌드 조건에 맞춤 |
tasks.json |
g++에 전달할 소스·옵션·출력 경로 |
command는 같은 툴체인, 출력 경로는 디버그 대상과 같아야 함 |
launch.json |
GDB가 시작할 프로그램과 작업 폴더 | program은 빌드 출력, preLaunchTask는 task의 label과 정확히 일치 |
c_cpp_properties.json- 책임 IntelliSense의 컴파일러·include 경로·C++ 표준
- 계약
compilerPath와cppStandard를 실제 빌드 조건에 맞춥니다. tasks.json- 책임 실제
g++명령, 소스, 옵션, 출력 경로 - 계약 출력 실행 파일이
launch.json의program과 같아야 합니다. launch.json- 책임 GDB로 시작할 프로그램과 작업 폴더
- 계약
preLaunchTask가 task의label과 정확히 같아야 합니다.
첫 번째 프로그램 작성 및 실행
#include <iostream>
int main() {
std::cout << "Hello, C++ World!" << std::endl;
return 0;
}g++ -std=c++20 -Wall -Wextra -g main.cpp -o hello.exe
.\hello.exe첫 프로그램이 바로 실행되지 않을 때는 IDE 설정을 무작정 바꾸기보다, 저장된 소스 파일, 컴파일러 호출, 링커 단계, 실행 파일 위치를 순서대로 나누어 확인하는 편이 빠릅니다.
실패 단계만 분리해도 고칠 파일과 설정 범위가 크게 줄어듭니다.
FIRST-ERROR TRIAGE
설정을 모두 바꾸기 전에 첫 오류 메시지가 어느 경계에서 나왔는지 확인합니다.
| 보이는 증상 | 멈춘 단계 | 먼저 확인할 것 |
|---|---|---|
g++ 또는 gdb를 찾을 수 없음 |
설치 · Path | 새 터미널에서 버전 명령을 실행하고 C:\msys64\ucrt64\bin을 확인 |
error: expected ... 또는 header를 찾지 못함 |
전처리 · 컴파일 | 첫 진단에 따라 저장된 파일의 문법 또는 #include 이름·검색 경로를 확인 |
undefined reference 또는 cannot find -l... |
링크 | 함수 정의가 든 목적 파일, 라이브러리 이름·경로·명령 인수 순서를 확인 |
| 빌드됐지만 실행 파일을 찾지 못함 | 실행 시작 | tasks.json의 -o와 launch.json의 program을 대조 |
| 실행되지만 출력이나 동작이 예상과 다름 | 실행 중 | 현재 작업 폴더, 입력값, 중단점과 변수 값을 확인 |
- 명령을 찾을 수 없음
- 단계 설치 · Path
- 확인 새 터미널에서
g++ --version과gdb --version을 실행합니다. - 컴파일 · header 진단
- 단계 전처리 · 컴파일
- 확인 첫 진단에 따라 문법 또는
#include이름·검색 경로를 봅니다. - 링크 진단
- 단계 링크
- 확인 누락된 정의·목적 파일·라이브러리와 명령 인수 순서를 봅니다.
- 실행 파일을 찾지 못함
- 단계 실행 시작
- 확인 build의 출력 경로와 debug의
program경로를 맞춥니다. - 출력이나 동작이 예상과 다름
- 단계 실행 중
- 확인 작업 폴더·입력값·중단점·변수 값을 확인합니다.
첫 환경 설정의 목표는 많은 설정 파일을 외우는 것이 아니라, 저장한 main.cpp가 컴파일러와 링커를 거쳐 실행 파일로 만들어지는 경로를 직접 확인하는 것입니다.