CMakeLists.txt 파일은 복잡한 프로젝트의 빌드 과정을 정의하는 핵심 스크립트 파일이다. 이 파일은 여러 디렉토리에 걸친 소스 파일과 라이브러리, 외부 종속성을 체계적으로 관리하고, 다양한 플랫폼에서 일관된 빌드를 가능하게 한다. 복잡한 프로젝트에서의 CMakeLists.txt 파일은 단순한 빌드 구성 이상의 기능을 포함하며, 다수의 서브 디렉토리, 모듈, 옵션 등을 관리한다.
프로젝트 구성 개요
복잡한 프로젝트는 일반적으로 다수의 서브 디렉토리로 구성되며, 각각의 디렉토리는 독립적인 CMakeLists.txt 파일을 가질 수 있다. 최상위 CMakeLists.txt 파일은 전체 프로젝트의 빌드 구조를 정의하고, 각 서브 디렉토리의 빌드를 포함하며, 글로벌 옵션과 외부 종속성을 설정한다.
- 최상위 CMakeLists.txt: 프로젝트 전체의 설정을 관리.
- 서브 디렉토리의 CMakeLists.txt: 각 모듈 또는 라이브러리의 빌드를 정의.
- 모듈화된 외부 스크립트: 복잡한 작업을 외부 파일로 분리하여 관리.
최상위 CMakeLists.txt 분석
복잡한 프로젝트에서 최상위 CMakeLists.txt는 전체 프로젝트의 빌드 구조를 제어하는 중요한 역할을 한다. 일반적으로 이 파일은 다음과 같은 구성 요소를 포함한다:
프로젝트 정의 및 기본 설정
cmake_minimum_required(VERSION 3.15)
project(MyComplexProject VERSION 1.0 LANGUAGES CXX)
여기에서는 CMake의 최소 버전을 정의하고, 프로젝트의 이름과 버전, 사용 언어를 명시한다. 복잡한 프로젝트에서는 CMake의 최신 기능을 활용하기 위해 높은 버전의 CMake를 요구할 수 있다.
글로벌 옵션 설정
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
글로벌 옵션은 프로젝트 전체에서 일관되게 적용된다. 예를 들어, C++ 표준을 설정하거나, Position Independent Code(PIC)를 사용하여 라이브러리를 생성하는 옵션을 설정할 수 있다.
외부 패키지 및 종속성 관리
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM gtkmm-3.0)
복잡한 프로젝트에서는 다양한 외부 패키지와 라이브러리가 필요하다. find_package
명령어는 CMake가 기본적으로 제공하는 모듈을 사용해 패키지를 검색하고, 이를 프로젝트에 포함시킨다. 예를 들어, Boost 라이브러리를 찾고, 필요한 컴포넌트를 지정할 수 있다. pkg_check_modules
는 패키지 구성 파일을 사용해 라이브러리 정보를 가져온다.
서브 디렉토리 포함
add_subdirectory(src)
add_subdirectory(lib)
add_subdirectory(tests)
add_subdirectory
명령어를 사용해 하위 디렉토리의 CMakeLists.txt 파일을 포함한다. 각 하위 디렉토리는 독립적으로 빌드 규칙을 정의하며, 최상위 CMakeLists.txt는 이를 전체 프로젝트의 빌드 과정에 통합한다.
서브 디렉토리의 CMakeLists.txt 분석
복잡한 프로젝트의 각 서브 디렉토리는 자신만의 CMakeLists.txt 파일을 갖는다. 이 파일은 해당 모듈 또는 라이브러리의 빌드를 관리한다.
소스 파일과 헤더 파일 정의
set(SOURCE_FILES
main.cpp
utils.cpp
)
set(HEADER_FILES
utils.h
)
소스 파일과 헤더 파일을 각각 변수로 정의하여 나중에 빌드 구성에서 사용하기 쉽게 만든다.
라이브러리 및 실행 파일 생성
add_library(MyLibrary ${SOURCE_FILES}${HEADER_FILES})
target_include_directories(MyLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library
명령을 사용해 라이브러리를 생성하며, 해당 라이브러리에 필요한 헤더 파일 경로를 target_include_directories
로 지정한다. 이는 라이브러리 사용 시 필요한 경로를 자동으로 설정하게 한다.
종속성 설정
target_link_libraries(MyLibrary PUBLIC Boost::filesystem Boost::system)
라이브러리 또는 실행 파일이 외부 라이브러리에 종속적인 경우, target_link_libraries
명령을 사용해 종속성을 설정한다. 이는 빌드 과정에서 해당 라이브러리를 자동으로 링크하게 한다.
모듈화 및 스크립트 사용
복잡한 프로젝트에서는 특정 작업을 모듈화하거나 외부 스크립트로 분리하여 관리하는 것이 일반적이다. 이는 코드의 재사용성을 높이고, 빌드 설정을 보다 간결하게 만든다.
외부 스크립트 포함
include(cmake/CustomFunctions.cmake)
외부 CMake 스크립트를 include
명령을 사용해 포함한다. 예를 들어, CustomFunctions.cmake
파일에 복잡한 반복 작업이나 조건문 등을 정의해 놓고, 이를 필요할 때마다 호출할 수 있다.
사용자 정의 명령어
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/generated.cpp
COMMAND mycodegen ${CMAKE_SOURCE_DIR}/input.txt >${CMAKE_BINARY_DIR}/generated.cpp
DEPENDS ${CMAKE_SOURCE_DIR}/input.txt
)
사용자 정의 명령어를 통해, 빌드 과정에서 특정 작업을 자동화할 수 있다. 예를 들어, 코드 생성 도구를 사용해 소스 파일을 동적으로 생성하는 작업을 포함할 수 있다.
관련 자료:
- 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.