CMake란 무엇인가?
CMake는 크로스 플랫폼 빌드 시스템을 생성하기 위한 도구이다. 소프트웨어 프로젝트의 컴파일, 링크 및 배포를 자동화하는 데 사용된다. CMake는 Makefile, Ninja 파일, Visual Studio 솔루션 파일 등을 생성하여, 다양한 환경에서 일관된 빌드 프로세스를 가능하게 한다. 이는 특히 대규모 프로젝트나 멀티플랫폼 환경에서 유용하다.
CMake의 구성 요소
CMake는 여러 구성 요소로 이루어져 있으며, 이들은 프로젝트의 빌드 프로세스를 정의하고 제어하는 역할을 한다.
-
CMakeLists.txt: CMakeLists.txt 파일은 CMake 프로젝트의 핵심 구성 파일이다. 이 파일에는 프로젝트 설정, 소스 파일 목록, 타겟 정의, 빌드 옵션 등이 포함된다. 이 파일은 각 디렉토리에 존재할 수 있으며, 계층 구조를 통해 서브 프로젝트를 관리할 수 있다.
-
Commands (명령어): CMake는 다양한 명령어를 제공하며, 이를 통해 빌드 설정을 구체적으로 지정할 수 있다. 주요 명령어로는
project()
,add_executable()
,add_library()
,target_link_libraries()
,find_package()
등이 있다. -
Variables (변수): CMake에서 변수는 설정을 저장하고 빌드 프로세스 전반에서 이를 참조하는 데 사용된다. 예를 들어,
CMAKE_CXX_COMPILER
는 사용할 C++ 컴파일러를 지정하는 변수이다. 변수는set()
명령어를 통해 정의되며, 필요 시option()
을 사용해 사용자에게 값을 입력받을 수도 있다. -
Targets (타겟): 타겟은 CMake에서 빌드할 엔티티를 의미한다. 예를 들어, 실행 파일, 라이브러리 등이 타겟이 될 수 있다. 타겟은
add_executable()
이나add_library()
명령어로 정의되며, 이후target_link_libraries()
,target_include_directories()
등을 통해 종속성 및 설정을 추가할 수 있다.
CMake의 작동 방식
CMake는 기본적으로 두 단계로 작동한다. 첫 번째 단계는 '생성' 단계이며, 두 번째 단계는 '빌드' 단계이다.
-
생성 단계 (Generation Stage): 이 단계에서는 CMake가 프로젝트의
CMakeLists.txt
파일을 읽고, 사용자가 지정한 빌드 시스템 파일(예: Makefile, Visual Studio 솔루션 파일)을 생성한다.cmake
명령어를 실행하면 이 단계가 시작된다. 이 단계에서 CMake는 설정된 변수 값, 타겟 및 종속성, 기타 설정을 종합하여 빌드 시스템을 설정한다. -
빌드 단계 (Build Stage): 빌드 시스템이 생성된 후, 사용자는 해당 빌드 시스템의 명령어(예:
make
,ninja
,msbuild
)를 사용해 실제 컴파일을 수행한다. 이 단계에서는 CMake가 직접 관여하지 않으며, 빌드 시스템에 의해 관리된다.
CMake의 주요 명령어
CMake에는 프로젝트를 구성하고 관리하는 데 필수적인 여러 명령어가 있다.
-
project():
project()
명령어는 CMake 프로젝트의 이름과 언어를 정의한다. 예를 들어,project(MyProject CXX)
는 MyProject라는 이름의 C++ 프로젝트를 정의한다. -
add_executable():
add_executable()
명령어는 실행 파일 타겟을 정의한다. 예를 들어,add_executable(MyApp main.cpp)
는 MyApp이라는 이름의 실행 파일을 생성하며, 이를 위해 main.cpp 파일을 컴파일한다. -
add_library():
add_library()
명령어는 정적 또는 동적 라이브러리 타겟을 정의한다. 예를 들어,add_library(MyLib STATIC lib.cpp)
는 MyLib라는 이름의 정적 라이브러리를 생성하며, 이를 위해 lib.cpp 파일을 컴파일한다. -
target_link_libraries():
target_link_libraries()
명령어는 타겟에 대해 링크할 라이브러리를 지정한다. 예를 들어,target_link_libraries(MyApp MyLib)
는 MyApp 실행 파일에 MyLib 라이브러리를 링크한다. -
find_package():
find_package()
명령어는 외부 패키지를 검색하고, 이를 프로젝트에 포함시킨다. 예를 들어,find_package(Boost REQUIRED)
는 Boost 라이브러리를 검색하고, 이를 프로젝트에 포함한다.
CMake의 변수와 설정
CMake에서는 다양한 변수와 설정을 통해 빌드 프로세스를 제어할 수 있다. 이러한 변수들은 전역적으로 사용되거나 특정 타겟에만 적용될 수 있다.
-
CMAKE_CXX_COMPILER: C++ 컴파일러를 지정하는 변수이다. 예를 들어,
set(CMAKE_CXX_COMPILER /usr/bin/g++)
는 G++ 컴파일러를 사용하도록 설정한다. -
CMAKE_BUILD_TYPE: 빌드 타입을 지정하는 변수로,
Debug
,Release
,MinSizeRel
,RelWithDebInfo
와 같은 값이 올 수 있다. 예를 들어,set(CMAKE_BUILD_TYPE Release)
는 릴리즈 빌드를 수행하도록 설정한다. -
CMAKE_CXX_FLAGS: C++ 컴파일러에 전달할 추가 플래그를 지정하는 변수이다. 예를 들어,
set(CMAKE_CXX_FLAGS "-Wall -O2")
는 모든 경고를 출력하고 최적화 수준 2를 사용하도록 설정한다.
CMake의 고급 기능
CMake는 대규모 프로젝트나 복잡한 빌드 요구사항을 지원하기 위해 다양한 고급 기능을 제공한다.
-
ExternalProject:
ExternalProject
모듈은 외부 프로젝트를 빌드하고 이를 포함할 수 있도록 한다. 이는 예를 들어, 서드파티 라이브러리를 소스 코드부터 빌드하여 포함해야 할 때 유용하다. -
CTest: CTest는 CMake와 통합된 테스트 도구이다. 이를 통해 자동화된 테스트를 설정하고 실행할 수 있다.
enable_testing()
과add_test()
명령어를 통해 테스트를 정의할 수 있다. -
CPack: CPack은 CMake 프로젝트의 패키징을 자동화하는 도구이다. 이를 통해 다양한 포맷(RPM, DEB, ZIP 등)으로 패키지를 생성할 수 있다.
CMake의 확장성과 모듈화
CMake는 모듈화된 구조를 가지고 있으며, 이는 사용자가 정의한 기능을 추가하거나 CMake의 기본 기능을 확장하는 데 유용하다.
-
Custom Modules: 사용자는 CMake 모듈을 정의하여, 프로젝트 내에서 반복적으로 사용되는 설정이나 명령어를 관리할 수 있다. 이는
CMakeLists.txt
파일을 간소화하고 유지보수를 용이하게 한다. -
Function 및 Macro:
function()
과macro()
명령어는 사용자 정의 함수와 매크로를 생성할 수 있도록 한다. 이는 복잡한 설정을 단순화하고, 코드 재사용성을 높인다.
관련 자료: - CMake 공식 문서: https://cmake.org/cmake/help/latest/ - Modern CMake 소개: https://cliutils.gitlab.io/modern-cmake/ - Professional CMake: A Practical Guide by Craig Scott