C/C++ 개발을 위한 확장 설치하기
C/C++ Extension Pack 확장을 설치한다. 이 확장은 데비안(Debian)의 메타 패키지와 유사하게 여러 확장을 모아 놓은 것으로, 설치 시 다음과 같은 C++ 개발 필수 확장들이 함께 설치된다.
- C/C++
- C/C++ Themes
- CMake Tools
코드 분석 도구로는 Microsoft C/C++ 확장보다 clangd 확장이 더 빠르고 지능적이라는 평가를 받는다.
clangd 확장을 설치할 때, 아래 그림과 같이 제작사인 LLVM을 신뢰할 것인지 묻는 창이 나타나면 Trust Publisher & Install 버튼을 클릭하여 설치를 진행한다.
clangd 확장 설치를 완료하면 우측 하단에 두 개의 알림 창이 나타난다.
- clangd language server가 없다는 알림 창에서는 Install 버튼을 클릭하여 설치한다.
-
Microsoft C/C++ 확장과 clangd 확장이 충돌한다는 알림 창에서는
Disable IntelliSense 버튼을 클릭한 후, 이어지는
Reload 버튼을 클릭하여 VS Code 설정을 다시 불러온다.
이렇게 하면 Microsoft C/C++ 확장의 인텔리센스(코드 분석/자동 완성) 기능만 비활성화되고, 디버깅 기능(GDB/LLDB 연동)은 그대로 유지되어 두 확장의 장점을 모두 활용할 수 있다.
프로젝트 폴더에 CMakeLists.txt 파일 생성하기
tasks.json이나 launch.json 파일을 수동으로 만들기보다 CMake를 사용하여 빌드 시스템을 정의하는 것이 효율적이다. 최근 대부분의 C++ 프로젝트는 CMake를 표준으로 사용한다. CMake는 빌드 파일을 직접 생성하는 것이 아니라 make나 Ninja용 빌드 파일을 생성해 주는 도구이다. 최신 개발 환경에서는 cmake -G Ninja 명령을 통해 속도가 빠른 Ninja를 사용하는 것이 추세다.
VS Code의 CMake Tools 확장을 활용하면 빌드, 테스트, 디버깅 설정을 자동화할 수 있다. 이 확장은 CMake 프로젝트를 인식하면 하단 상태 표시줄에 빌드, 디버그, 실행 버튼을 제공한다.
CMake 프로젝트임을 인식시키기 위해 프로젝트 루트 폴더에 CMakeLists.txt 파일을 생성한다. 이전 글(WSL에 C/C++ 개발을 위한 패키지 설치하기)에서 생성한 wsl_cpp 디렉터리를 그대로 사용한다.
파일을 생성하면 곧바로 Kit을 선택하라는 창이 나타난다. 동시에 하단 상태 표시줄에는 빌드 설정, 디버그, 실행 아이콘이 생성된다. 만약 Kit 선택 창을 닫았다면 상태 표시줄의 Build 설정 아이콘을 클릭하여 다시 열 수 있다.
Kit 선택 창에서 사용할 컴파일러를 선택한다. 보통 Clang이나 GCC를 선택한다. 위 그림에 mingw32 항목이 보이는 이유는 리눅스 환경에서 윈도우용 실행 파일(.exe)을 만드는 크로스 컴파일 테스트를 위해 mingw-w64 패키지를 설치했기 때문이다. 일반적인 리눅스 환경의 GCC를 사용하려면 /usr/bin/gcc, /usr/bin/g++ 경로가 표시된 항목을 선택한다. 만약 Clang이 목록에 없다면 맨 위의 Scan for kits를 실행하여 컴파일러를 새로 검색한다.
검색 후 위 그림과 같이 Clang 컴파일러 항목이 나타나면, WSL Linux 시스템 경로인 /usr/bin/clang, /usr/bin/clang++이 포함된 항목을 선택한다.
컴파일러 선택을 마치면 프로젝트 폴더에 build 디렉터리가 자동으로 생성된다. 이전에 테스트로 생성했던 a.out이나 hello 실행 파일은 삭제해도 무방하다. 앞으로 빌드 결과물은 모두 build 디렉터리 안에 생성되기 때문이다. 왼쪽 액티비티 바(Activity Bar)에 CMake 아이콘이 추가된 것도 확인할 수 있다.
CMakeLists.txt 파일에 설정 내용 추가하기
CMakeLists.txt 파일에 아무 내용도 입력하지 않으면, 아래 그림과 같이 OUTPUT 패널의 CMake/Build 메시지에 경고가 표시된다.
CMakeLists.txt 파일에 다음 내용을 추가한다.
cmake_minimum_required(VERSION 3.10)
project(WSLCPP LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_executable(hello hello.cpp)
- 라인 1: 최소 CMake 요구 버전 설정.
- 라인 2: 프로젝트 이름 및 사용 언어 설정.
- 라인 3, 4: C++17 표준 사용을 강제하는 설정.
- 라인 5: clangd를 위한 컴파일 데이터베이스(compile_commands.json) 생성 설정.
- 라인 6: hello.cpp 소스 파일을 사용하여 hello라는 이름의 실행 파일을 생성하는 설정.
파일을 저장하면 OUTPUT 패널에서 설정을 자동으로 반영한다. 만약 자동 반영이 되지 않는다면 Ctrl + Shift + P를 누른 후 CMake: Configure를 실행한다.
[main] Configuring project: wsl_cpp
[proc] Executing command: /usr/bin/cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ --no-warn-unused-cli -S /home/bitneer/study/CPP/wsl_cpp -B /home/bitneer/study/CPP/wsl_cpp/build -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: /home/bitneer/study/CPP/wsl_cpp/build
로그의 두 번째 라인에서 설정한 컴파일러와 빌드 시스템을 확인한다. 위 예시에서는 Clang과 Ninja를 사용하고 있다. CMake Tools 확장은 시스템에 Ninja가 설치되어 있으면 기존의 make보다 속도가 빠른 Ninja를 우선적으로 선택한다.
빌드 도구를 make로 변경하고 싶다면 다음 과정을 따른다.
- Ctrl + , 키로 설정을 연 후 Cmake: Generator 항목에 Unix Makefiles를 입력한다.
- 프로젝트 루트의 build 폴더를 삭제한다.
- Ctrl + Shift + P를 누른 후 CMake: Configure를 실행하여 설정을 재구성한다.
CMake Tools 확장의 빌드와 실행
상태 표시줄의 빌드(Build) 아이콘을 클릭하여 컴파일한 후, 실행(Run) 아이콘을 클릭한다. 아래 그림과 같이 터미널 탭에서 실행 결과를 확인할 수 있다.
CMake Tools의 주요 단축키는 다음과 같다.
- 빌드: F7
- 디버그 없이 실행: Ctrl + Shift + F5
여러 개의 main 함수 관리하기
학습 중에는 여러 소스 파일에 각각 main 함수를 두고 관리하고 싶을 때가 있다. add_executable을 매번 수동으로 추가하는 것은 번거로우므로, 다음과 같은 자동화 방법을 추천한다.
1. CMakeLists.txt에서 기존 add_executable(hello hello.cpp) 줄을 삭제하고 아래 내용을 추가한다. 하위 폴더를 재귀적으로 검색하여 main_으로 시작하는 모든 파일을 각각의 실행 파일로 등록한다.
# 폴더 아래의 main_*.cpp 파일을 모두 재귀적으로 찾기
file(GLOB_RECURSE MAIN_FILES "main_*.cpp")
foreach(main_file ${MAIN_FILES})
get_filename_component(target_name ${main_file} NAME_WE)
add_executable(${target_name} ${main_file})
endforeach()
2. 기존 hello.cpp 파일명을 main_hello.cpp로 변경한다.
3. Ctrl + Shift + P 키를 누른 후 CMake: Configure를 실행한다.
4. 테스트를 위해 다음 내용을 가진 main_goobye.cpp 파일을 생성한다.
#include <iostream>
int main() {
std::cout << "Goodbye, WSL!" << std::endl;
return 0;
}
5. 설정이 확실히 반영되도록 Ctrl + Shift + P 키를 누른 후 CMake: Delete Cache and Reconfigure를 실행한다.
6. 액티비티 바의 CMake 아이콘 클릭 후, Launch 항목의 편집 아이콘을 클릭하여 실행할 타겟을 선택한다.
7. 타겟을 선택한 후 상태 표시줄의 실행 아이콘을 누르면 해당 파일이 실행된다.
과정이 복잡해 보인다면 단축키를 설정하여 단순화할 수 있다.
예: CMake: Delete Cache and Reconfigure 단축키 Ctrl + Shift + F7 → CMake: Set Launch/Debug Target 단축키 Ctrl + Shift + F6 → CMake: Run Without Debugging 단축키 Ctrl + Shift + F5
코드 포맷 설정
소스 코드에서 마우스 오른쪽 버튼을 클릭하여 Format Document를 선택하거나 포맷 단축키를 누른다.
Microsoft C/C++ 확장의 인텔리센스를 비활성화했기 때문에 위와 같은 안내 창이 뜬다. Configure 버튼을 클릭한 후 포맷터로 clangd를 선택한다.
.clang-format 포맷 설정
C++ 코드 스타일은 .clang-format 파일로 관리하는 것이 표준이다. 프로젝트 루트에 파일을 생성하고 다음 내용을 입력한다. 구글 스타일(Google Style) 기반의 예시 설정이다.
BasedOnStyle: Google
IndentWidth: 2 # 들여쓰기 설정
ColumnLimit: 100 # 한 줄의 최대 길이 (보통 80~100자)
InsertTrailingNewline: true # 파일 끝에 빈 줄 추가 활성화 - Clang 16 버전에서 처음 도입. 이전 버전 적용 안됨
AllowShortFunctionsOnASingleLine: Empty # 중괄호 및 공백 설정
BreakBeforeBraces: Attach # 구글 스타일: 함수 옆에 중괄호 붙이기
.clangd 설정
소스 파일을 열면 하단에 clangd 확장 아이콘이 표시된다. CMake 프로젝트의 표준인 build 디렉터리를 사용하면 clangd가 compile_commands.json을 자동으로 찾아 코드 분석, 정의 이동, 리팩토링 등을 수행한다.
.clangd 파일은 clangd의 동작을 세밀하게 제어한다. 프로젝트 루트에 파일을 생성하고 다음 설정을 추가해 보자.
CompileFlags:
CompilationDatabase: build # CMake 빌드 데이터베이스 위치 지정. build가 기본값이나 나중의 변경을 위해 명시.
Index:
Background: Build # 백그라운드 인덱싱 활성화. 코드 정의 이동 및 심볼 검색 속도 향상.
InlayHints: # 코드 내 인라인 힌트 설정
Enabled: Yes
ParameterNames: Yes
DeducedTypes: Yes
Designators: Yes
Diagnostics: # 코드 진단 및 교정
ClangTidy:
Add: [modernize-*, readability-*, bugprone-*]
Remove: [modernize-use-trailing-return-type]
CheckOptions:
readability-identifier-naming.VariableCase: camelCase
설정을 변경했다면 Ctrl + Shift + P 키를 누른 후 clangd: Restart language server를 실행하여 적용한다.