개발 환경 설정
에디터·컴파일러·링커의 역할을 이해하고 VS Code에서 C++ 소스를 빌드하고 실행하는 개발 환경을 단계별로 구성합니다.
앞 절에서 C++이 어떤 언어인지, 그리고 어디에 활용되는지 개괄적으로 살펴봤습니다.
이제는 C++ 코드를 직접 작성하고 실행하기 위한 준비 단계로 넘어가겠습니다.
건축가가 건물을 짓기 위해 설계 도구와 자재를 준비하듯이, 프로그래머에게도 코드를 작성하기 위한 적절한 도구와 환경이 필요합니다.
이 장에서는 C++ 개발에 필요한 핵심 도구를 정리하고, 컴퓨터에 개발 환경을 설정하는 과정을 단계별로 안내합니다.
먼저 전체 흐름을 보면, C++ 개발 환경을 구성하는 일은 코드를 쓰는 도구와 실행 파일을 만드는 도구를 하나의 경로로 연결하는 작업입니다.
g++가 C++ 소스를 실행 파일로 만드는 단계
main.cpp의 전처리·목적 코드·링크 산출물을 거쳐 별도 PowerShell 실행으로 넘어가므로 현재 산출물과 빌드/실행 경계를 단계별로 확인할 수 있다.
C++ · BUILD AND EXECUTION
g++는 빌드를 조정하고 실행은 별도로 시작한다
한 번의 g++ 명령 안에서도 번역과 링크는 구별됩니다. 실행은 빌드 성공 뒤 운영체제에서 시작합니다.
- 전처리
#include와 매크로를 처리해 컴파일할 번역 단위를 준비합니다. - 컴파일과 어셈블
C++를 목적 코드로 바꿉니다.
-c를 쓰면 링크하지 않고 목적 파일에서 멈출 수 있습니다. - 링크
목적 코드와 필요한 C++ 라이브러리를 연결해
hello.exe를 만듭니다. - 실행
PowerShell의
.\hello.exe가 빌드 결과를 시작하고 Windows가 프로그램을 적재합니다.
빌드와 실행 명령
g++ -std=c++20 main.cpp -o hello.exe
.\hello.exe첫 줄은 빌드, 둘째 줄은 PowerShell에서의 실행입니다. 편집기나 C/C++ 확장과 별도로 컴파일러 툴체인이 필요합니다.
g++ main.cpp -o hello.exe처럼 한 번에 링크하면 목적 파일이 별도 파일로 남지 않을 수 있지만, 번역과 링크의 책임은 여전히 구분됩니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 소스 준비 실행 전에 소스를 빌드 입력으로 둔다. |
|
|
| 빌드 산출물 전처리·컴파일·링크로 실행 파일을 만든다. |
|
|
| 실행 시작 PowerShell에서 만들어진 파일을 실행한다. |
|
|
g++가 C++ 소스를 실행 파일로 만드는 단계
main.cpp의 전처리·목적 코드·링크 산출물을 거쳐 별도 PowerShell 실행으로 넘어가므로 현재 산출물과 빌드/실행 경계를 단계별로 확인할 수 있다.
C++ · BUILD AND EXECUTION
g++는 빌드를 조정하고 실행은 별도로 시작한다
한 번의 g++ 명령 안에서도 번역과 링크는 구별됩니다. 실행은 빌드 성공 뒤 운영체제에서 시작합니다.
- 전처리
#include와 매크로를 처리해 컴파일할 번역 단위를 준비합니다. - 컴파일과 어셈블
C++를 목적 코드로 바꿉니다.
-c를 쓰면 링크하지 않고 목적 파일에서 멈출 수 있습니다. - 링크
목적 코드와 필요한 C++ 라이브러리를 연결해
hello.exe를 만듭니다. - 실행
PowerShell의
.\hello.exe가 빌드 결과를 시작하고 Windows가 프로그램을 적재합니다.
빌드와 실행 명령
g++ -std=c++20 main.cpp -o hello.exe
.\hello.exe첫 줄은 빌드, 둘째 줄은 PowerShell에서의 실행입니다. 편집기나 C/C++ 확장과 별도로 컴파일러 툴체인이 필요합니다.
g++ main.cpp -o hello.exe처럼 한 번에 링크하면 목적 파일이 별도 파일로 남지 않을 수 있지만, 번역과 링크의 책임은 여전히 구분됩니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 소스 준비 실행 전에 소스를 빌드 입력으로 둔다. |
|
|
| 빌드 산출물 전처리·컴파일·링크로 실행 파일을 만든다. |
|
|
| 실행 시작 PowerShell에서 만들어진 파일을 실행한다. |
|
|
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 같은 빌드 시스템으로 전환합니다.
C++ · BUILD AND EXECUTION
편집·빌드·디버그 설정은 연결 값을 맞춘다
세 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++명령, 소스, 옵션, 출력 경로 - 계약
command는 같은 툴체인을 사용하고, 출력 실행 파일은launch.json의program과 같아야 합니다. launch.json- 책임 GDB로 시작할 프로그램과 작업 폴더
- 계약
program은 빌드 출력이고,preLaunchTask는 task의label과 정확히 같아야 합니다.
실제 값을 대조할 네 쌍
compilerPath ↔ task의 command
cppStandard ↔ 빌드의 -std
빌드의 -o ↔ debug의 program
task의 label ↔ preLaunchTask
includePath는 편집 지원의 검색 경로입니다. 실제 컴파일에 필요한 외부 헤더 경로는 빌드의 -I 인수에도 반영합니다.
IntelliSense가 정상이어도 빌드 명령은 실패할 수 있습니다. 편집 지원과 실제 빌드는 서로 다른 설정 경로입니다.
첫 번째 프로그램 작성 및 실행
#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빌드 명령이 성공한 뒤 실행했을 때 예상 출력은 Hello, C++ World!와 줄바꿈입니다. PowerShell에서는 빌드 직후 $LASTEXITCODE를 입력해 종료 상태를 확인할 수 있습니다. 0이면 이 명령이 성공한 것이고, 실패했다면 먼저 진단을 읽고 실행 명령을 미룹니다. 이전에 만든 hello.exe가 남아 있으면 이번 빌드가 실패해도 그 옛 파일을 실행할 수 있기 때문입니다.
소스의 인사말을 다른 문장으로 바꾸고 저장한 뒤 다시 빌드·실행해 보세요. 바뀐 문장이 나오면 ‘현재 저장된 소스 → 새 실행 파일 → 실행’의 연결을 확인한 것입니다. 원래 문장이 나오면 저장 여부와 빌드·실행 대상 경로를 차례로 대조합니다.
첫 프로그램이 바로 실행되지 않을 때는 IDE 설정을 무작정 바꾸기보다, 저장된 소스 파일, 컴파일러 호출, 링커 단계, 실행 파일 위치를 순서대로 나누어 확인하는 편이 빠릅니다.
실패 단계만 분리해도 고칠 파일과 설정 범위가 크게 줄어듭니다.
C++ · BUILD AND EXECUTION
첫 오류가 발생한 단계부터 원인을 좁힌다
설치·전처리/컴파일·링크·실행 시작·실행 중을 나누면 수정할 파일과 설정을 찾기 쉽습니다.
| 보이는 증상 | 멈춘 단계 | 먼저 확인할 것 |
|---|---|---|
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을 실행합니다. 기본 설치 경로는C:\msys64\ucrt64\bin이며, 실제 설치 위치와 Path를 대조합니다. - 컴파일 · header 진단
- 단계 전처리 · 컴파일
- 확인 첫 진단에 따라 문법 또는
#include이름·검색 경로를 봅니다. - 링크 진단
- 단계 링크
- 증상
undefined reference,cannot find -l... - 확인 누락된 정의·목적 파일·라이브러리와 명령 인수 순서를 봅니다.
- 실행 파일을 찾지 못함
- 단계 실행 시작
- 확인
tasks.json의-o출력과launch.json의program경로를 맞춥니다. - 출력이나 동작이 예상과 다름
- 단계 실행 중
- 확인 작업 폴더·입력값·중단점·변수 값을 확인합니다.
여러 진단이 이어지면 가장 먼저 출력된 오류부터 해결합니다. 뒤의 메시지는 앞선 실패가 만든 연쇄 증상일 수 있습니다.
첫 환경 설정의 목표는 많은 설정 파일을 외우는 것이 아니라, 저장한 main.cpp가 컴파일러와 링커를 거쳐 실행 파일로 만들어지는 경로를 직접 확인하는 것입니다.
혼자 점검해 보세요. 빌드 명령의 -o는 hello.exe인데 디버거의 program은 main.exe라면 어느 값을 맞춰야 할까요? c_cpp_properties.json의 includePath를 고쳤는데 GCC가 계속 헤더를 찾지 못한다면 실제 빌드의 어느 인수를 살펴야 할까요?
첫 경우에는 디버거가 시작할 program을 실제 빌드 출력과 일치시킵니다. 둘째 경우에는 필요한 헤더 경로가 빌드 명령의 -I에도 있는지 봅니다. 편집기의 오류 표시가 사라졌다는 사실만으로 실제 빌드 성공을 판단하지 않습니다.