모던 CMake를 활용하여 효율적인 C++ 프로젝트 빌드 시스템을 구축하는 방법을 계속해서 알아보겠습니다. 이번 글에서는 C++ 표준 버전 설정에 대한 다양한 방법을 소개하고, 각 방법의 차이점과 장단점을 설명하겠습니다.
C++ 표준 버전 설정의 중요성
C++ 언어는 C++11, C++14, C++17, C++20 등 지속적으로 새로운 표준이 발표되고 있습니다. 프로젝트에서 사용하는 C++ 표준 버전을 명시적으로 설정하면 다음과 같은 이점이 있습니다:
- 코드 호환성 보장: 팀원 간 동일한 언어 기능을 사용하여 일관성 있는 코드베이스를 유지할 수 있습니다.
- 컴파일러 최적화: 컴파일러가 표준에 맞는 최적화를 적용하여 성능 향상을 기대할 수 있습니다.
- 미래 대비: 최신 표준을 사용하여 최신 언어 기능과 라이브러리를 활용할 수 있습니다.
1. 전통적인 방법
초기에는 CMake에서 C++ 표준을 설정하기 위해 컴파일러 플래그를 직접 지정하는 방법을 사용했습니다.
1.1. add_definitions() 사용
add_definitions(-std=c++11)
장점
- 간단함: 간단하게 컴파일러 플래그를 추가할 수 있습니다.
- 즉각적인 적용: 모든 타겟에 플래그가 적용됩니다.
단점
- 유연성 부족: 특정 타겟에만 적용하기 어렵습니다.
- 언어별 설정 어려움: C와 C++의 컴파일 옵션을 구분하기 어렵습니다.
- 플랫폼 종속성: 컴파일러에 따라 플래그가 다를 수 있습니다.
1.2. set(CMAKE_CXX_FLAGS ...) 사용
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
장점
- 전역 적용: 프로젝트의 모든 C++ 파일에 플래그가 적용됩니다.
단점
- 유연성 부족: 특정 타겟에만 적용하기 어렵습니다.
- 누적 관리 어려움: 여러 곳에서 CMAKE_CXX_FLAGS를 수정하면 추적이 어렵습니다.
- 컴파일러 호환성 문제: 다른 컴파일러나 언어에 영향을 줄 수 있습니다.
2. 모던 CMake 방법
모던 CMake에서는 타겟 기반의 설정을 통해 C++ 표준을 보다 명확하고 유연하게 설정할 수 있습니다.
2.1. CMAKE_CXX_STANDARD와 CMAKE_CXX_STANDARD_REQUIRED 사용
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
장점
- 간편함: 전역 변수로 C++ 표준을 설정할 수 있습니다.
- 컴파일러 독립적: CMake가 컴파일러에 맞는 플래그를 자동으로 설정합니다.
- 가독성 향상: 코드에서 명시적으로 표준 버전을 확인할 수 있습니다.
단점
- 타겟별 설정 어려움: 모든 타겟에 동일한 표준이 적용됩니다.
- 다중 프로젝트 관리 어려움: 서브 디렉토리에서 다른 표준을 사용하기 어렵습니다.
2.2. 타겟 프로퍼티 CXX_STANDARD 사용
add_executable(MyApp main.cpp)
set_target_properties(MyApp PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
사용 가능한 값들은 여기에서 확인할 수 있다.
장점
- 타겟별 설정 가능: 각 타겟마다 다른 C++ 표준을 설정할 수 있습니다.
- 유연성 증가: 라이브러리와 실행 파일에 다른 표준 적용이 가능합니다.
단점
- 코드 중복: 여러 타겟에 동일한 설정을 반복해야 할 수 있습니다.
- 복잡성 증가: 타겟 수가 많아질 경우 관리가 어려울 수 있습니다.
2.3. target_compile_features() 사용
add_executable(MyApp main.cpp)
target_compile_features(MyApp PRIVATE cxx_std_17)
사용 가능한 값들은 여기에서 확인할 수 있다.
장점
- 모던 CMake 방식: 필요한 C++ 표준 기능을 선언적으로 지정합니다.
- 컴파일러 자동 설정: CMake가 컴파일러에 맞는 플래그를 자동으로 설정합니다.
- 인터페이스 전파: PUBLIC 또는 INTERFACE로 설정하면 의존 타겟에 표준이 전파됩니다.
단점
- 학습 곡선: 기존 방식에 익숙한 개발자에게는 다소 생소할 수 있습니다.
- 명시적 버전 확인 필요: 코드에서 설정한 C++ 표준 버전을 한눈에 파악하기 어려울 수 있습니다.
방법별 비교 및 장단점
방법 | 장점 | 단점 |
add_definitions(-std=c++11) | 간단하고 즉각적인 적용 | 유연성 부족, 언어별 구분 어려움, 플랫폼 종속성 |
set(CMAKE_CXX_FLAGS ...) | 전역 적용 | 유연성 부족, 관리 어려움, 컴파일러 호환성 문제 |
CMAKE_CXX_STANDARD 설정 | 간편하고 컴파일러 독립적 | 타겟별 설정 어려움, 다중 프로젝트 관리 어려움 |
set_target_properties() 사용 | 타겟별 설정 가능 | 코드 중복 가능성, 복잡성 증가 |
target_compile_features() 사용 | 모던 방식, 선언적 설정, 인터페이스 전파 가능 | 학습 필요, 명시적 버전 확인 어려움 |
추천 방법 및 실전 예제
모던 CMake에서는 target_compile_features()를 사용하는 것을 권장합니다. 이를 통해 타겟별로 필요한 C++ 표준 기능을 선언하고, 컴파일러에 맞는 설정을 자동으로 적용할 수 있습니다.
예제: target_compile_features() 사용
CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(MyProject)
add_executable(MyApp main.cpp)
target_compile_features(MyApp PRIVATE cxx_std_17)
설명
- CMake 최소 요구 버전을 3.8로 설정합니다. (target_compile_features는 CMake 3.8 이상에서 안정적으로 지원)
- MyApp 타겟에 cxx_std_17 기능을 PRIVATE 범위로 설정합니다.
- CMake는 컴파일러에 맞는 플래그를 자동으로 추가합니다. 예를 들어, GCC의 경우 -std=gnu++17을 추가합니다.
예제: 라이브러리와 실행 파일에 적용
add_library(MyLib mylib.cpp)
target_compile_features(MyLib PUBLIC cxx_std_17)
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE MyLib)
- MyLib 라이브러리에 cxx_std_17을 PUBLIC 범위로 설정하여, 이를 링크하는 MyApp에도 표준이 전파됩니다.
- MyApp은 별도로 표준을 설정할 필요가 없습니다.
주의사항
- 컴파일러 최소 버전 확인: 프로젝트에서 사용하는 C++ 표준을 지원하는 컴파일러 버전을 확인해야 합니다.
- CMake 최소 버전 설정: 사용하려는 CMake 기능이 지원되는 최소 버전을 cmake_minimum_required()로 지정해야 합니다.
- 플랫폼 호환성 고려: Windows, macOS, Linux 등 다양한 플랫폼에서의 컴파일러 동작을 테스트해야 합니다.
결론
이번 글에서는 C++ 표준 버전을 설정하는 다양한 방법을 소개하고, 각 방법의 차이점과 장단점을 살펴보았습니다. 모던 CMake에서는 target_compile_features()를 사용하는 것이 권장되며, 이를 통해 타겟별로 유연하고 선언적으로 C++ 표준을 관리할 수 있습니다.
반응형
'개발 이야기 > CMake' 카테고리의 다른 글
[모던 CMake] 테스트 설정과 CI/CD 파이프라인 연동 (31) | 2024.12.02 |
---|---|
[모던 CMake] 외부 라이브러리와 패키지 관리 (0) | 2024.12.01 |
[모던 CMake] 타겟 기반 구성과 의존성 관리 (32) | 2024.11.30 |
[모던 CMake] 기초와 소개 (0) | 2024.11.28 |
[CMake] Google Test (구글테스트) 종속성 추가하기 (0) | 2024.03.31 |