CMakeLists.txt 파일은 프로젝트의 빌드 시스템을 정의하는 핵심 요소이다. 이 파일을 잘 작성하면 유지보수성이 높아지고, 여러 플랫폼에서 일관된 빌드가 가능해진다. 다음은 CMakeLists.txt 파일을 작성할 때 따라야 할 모범 사례들이다.
프로젝트 초기 설정
프로젝트 이름과 버전 명시
프로젝트의 이름과 버전을 명시하는 것은 기본적인 시작점이다. 이를 통해 프로젝트의 정보를 명확히 전달할 수 있다.
cmake_minimum_required(VERSION 3.14)
project(MyProject VERSION 1.0 LANGUAGES CXX)
cmake_minimum_required
는 CMake의 최소 버전을 지정하며, 호환성 문제를 방지하는 데 유용하다. project
명령어는 프로젝트 이름과 지원 언어(C, CXX, 등)를 설정한다.
표준 C++ 버전 설정
특정 C++ 표준을 사용해야 하는 경우, CMake를 통해 이를 명확히 설정할 수 있다.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)
이 설정은 C++ 17 표준을 강제하며, 컴파일러 확장을 사용하지 않도록 한다.
파일 및 디렉토리 구조 관리
소스 및 헤더 파일 정리
프로젝트가 커질수록 소스 파일과 헤더 파일을 명확하게 구분하고 관리하는 것이 중요하다. 일반적으로, 소스 파일과 헤더 파일을 각각 src
와 include
디렉토리에 배치한다.
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp)
include_directories
명령어를 사용해 헤더 파일의 경로를 지정하고, file(GLOB_RECURSE ...)
을 사용해 소스 파일을 자동으로 검색할 수 있다.
출력 디렉토리 지정
빌드 결과물을 별도의 디렉토리에 저장하도록 설정하면, 소스 디렉토리가 더 깔끔하게 유지된다.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
이 설정은 실행 파일과 라이브러리가 각각 bin
과 lib
디렉토리에 저장되도록 한다.
빌드 설정
빌드 유형 정의
디버그와 릴리즈 빌드의 차이를 명확히 하기 위해 빌드 유형을 명시적으로 정의하는 것이 좋다.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
CMAKE_BUILD_TYPE
을 통해 기본 빌드 유형을 설정하고, 각 빌드 유형에 맞는 컴파일러 플래그를 지정한다.
외부 라이브러리 사용
외부 라이브러리와의 종속성을 관리하는 방법도 중요하다. find_package
명령을 사용해 외부 라이브러리를 찾아 링크하는 방식이 권장된다.
find_package(Boost 1.65 REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(MyExecutable ${Boost_LIBRARIES})
이 설정은 Boost 라이브러리를 찾고, 이를 프로젝트에 포함시킨다.
모듈화와 재사용성
타겟 사용
CMake에서 target
을 사용하면 모듈화와 재사용성을 높일 수 있다. 타겟을 정의하고, 해당 타겟에 필요한 설정을 추가하는 것이 좋다.
add_executable(MyExecutable ${SOURCES})
target_include_directories(MyExecutable PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_compile_options(MyExecutable PRIVATE -Wall -Wextra)
이렇게 하면 특정 타겟에만 필요한 설정을 추가할 수 있어 관리가 용이해진다.
CMake 모듈 분리
CMakeLists.txt 파일이 복잡해질 경우, 이를 여러 파일로 나누어 관리하는 것이 바람직한다. include
명령을 사용해 다른 CMake 파일을 불러올 수 있다.
include(cmake/AdditionalConfig.cmake)
이 방식은 CMake 설정을 모듈화하고, 특정 기능이나 설정을 별도의 파일로 분리하여 관리할 수 있게 한다.
문서화
CMakeLists.txt 파일에 주석 추가
CMakeLists.txt 파일에 주석을 추가하여 설정의 의도와 목적을 설명하는 것이 중요하다. 이는 향후 유지보수 시 이해도를 높이고, 다른 개발자들과의 협업에 도움이 된다.
add_executable(MyExecutable ${SOURCES})
주석은 간결하고 명확하게 작성하는 것이 좋다.
예외 처리와 오류 검증
필수 요소 검증
필수 요소들이 설정되었는지 확인하고, 오류 메시지를 제공하여 빌드 실패 시 문제를 쉽게 파악할 수 있도록 한다.
if(NOT DEFINED REQUIRED_VARIABLE)
message(FATAL_ERROR "REQUIRED_VARIABLE is not set")
endif()
message(FATAL_ERROR ...)
를 통해 필수 설정이 누락된 경우 빌드를 중단하고 명확한 오류 메시지를 출력하도록 한다.
관련 자료:
- Kitware Inc., CMake Documentation, https://cmake.org/cmake/help/latest/
- Martin, R., Mastering CMake, Kitware, Inc., 2010.
- Saxer, A., Professional CMake: A Practical Guide, Leanpub, 2020.