반응형

 

Module

CMake에서 기존 코드를 쉽게 재사용하는 방법이 있다. 바로 모듈(Module)이라는 것.

 

CMakeLists.txt 파일에서 Include라는 키워드로 모듈을 사용한다고 선언할 수 있다. 사실, CMake를 설치할 때, 함께 설치되는 표준 모듈들이 있다. 대표적으로 FindThreads, FindPkgConfig, FindCURL, FetchContent 모듈들이 있다.  (기본 설치 모듈이라고도 불린다.)

(함께 설치되는 모듈 리스트: https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html#manual:cmake-modules(7))

 

우분투 환경에서 아래의 명령어로 현재 설치된 모듈 리스트를 확인할 수 있다.

> cmake --help-module-list

 

일반적으로 모듈들의 위치는 아래의 경로에 있다.

/usr/share/cmake-3.XX/Modules/

 

 모듈을 사용하는 방법은 include()를 CMakeLists.txt에서 쓰면 된다.

이 include(XXX)는 XXX라는 기능 모듈 호출하는 코드이다.

 

아래는 간단한 예제이다.

간단한 예제

더보기

■ 프로젝트 구조

project/
 ├── CMakeLists.txt
 └── main.cpp

 

■ main.cpp

#include <iostream>

int main() {
    std::cout << "Hello from C++!" << std::endl;
    return 0;
}

 

■ CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(IncludeExample)

# include()로 CMake 기능 모듈 불러오기
include(CheckCXXCompilerFlag)

# 모듈 안의 함수 사용 가능
# check_cxx_compiler_flag는 주어진 C++ 컴파일러 옵션이
# 현재 컴파일러에서 지원되는지 체크하는 기능
# 즉, SUPPORTS_WALL 이라는 컴파일옵션이 지원되면 SUPPORTS_WALL = TRUE 가 된다.
check_cxx_compiler_flag("-Wall" SUPPORTS_WALL)

if (SUPPORTS_WALL)
    message(STATUS "Compiler supports -Wall")
    add_compile_options(-Wall)
else()
    message(STATUS "Compiler does NOT support -Wall")
endif()

add_executable(myapp main.cpp)

 

■ 빌드 방법

mkdir build
cd build
cmake ..
make

 

■ configure 로그 (cmake 명령어 실행시 나오는 로그)

-- Compiler supports -Wall
-- Configuring done
-- Generating done

 

■ 컴파일 시

[100%] Building CXX object CMakeFiles/myapp.dir/main.cpp.o
[100%] Linking CXX executable myapp

 


include 명령어

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                      [NO_POLICY_SCOPE])

 

 

 include 명령어의 첫번째 인자는 모듈 이름이 들어간다. 내부적으로 "이 모듈 이름.cmake" 파일을 찾고 그 cmake에 쓰여진 코드를 가져온다. 예를 들어 include(Seoul)은 CMake가 내부적으로 Seoul.cmake라는 파일을 찾고 그 코드를 가져오게 되는데 이 때 Seoul.cmake파일 안에 정의된 함수/변수를 불러오게됩니다.  이 때 모듈 이름은 대소문자를 구분하니 유의해야 한다.

 

 여기서 중요한 건, include는 모듈(.cmake)을 찾는다고 했는데, 찾는 것에도 순서가 있다.

다시 말해, 현재 설치된 모듈 리스트에서만 모듈을 찾는 것인가? 아니다.

 

CMake가 include를 통해 모듈(.cmake파일)을 찾을 때의 실제 검색 순서는 아래와 같다.

1. 현재 디렉토리 / 프로젝트 내부 기본 위치

- ./CMakeLists.txt와 같은 폴더에 "모듈 이름.cmake" 파일

- ./cmake/ 폴더

 

2. CMAKE_MODULE_PATH에 등록된 디렉토리

 

3. CMake가 내장으로 가지고 있는 시스템 모듈 디렉토리

(위에서 말한 CMake 설치 시 자동으로 설치되는 표준 모듈듈이라고 보면 된다. 예) FindThreads, FindPkgConfig, FindCURL, FetchContent)

 

 

 여기서 MAKE_MODULE_PATH는 CMake가 "모듈 이름.cmake"파일을 찾을 때 추가로 검색할 디렉토리를 지정하는 변수이다. 비유하자면 PATH 환경변수라고 생각하면 된다. 즉, "CMake 모듈을 여기에서도 찾아보세요"하고 CMake에게 알려주는 목록이라고 보면 된다.

즉, CMake가 include()나 find_package()를 실행할 때 모듈 파일을 찾을 경로를 우리가 추가로 넣는 변수이다.

 

위 순서를 CMakeLists.txt에서 사용되는 환경변수에 빗대어 설명하면 아래와 같다.

순위 경로 유형 변수 예시 검색 파일
1순위 현재 작업 디렉토리 CMAKE_CURRENT_SOURCE_DIR <filename>.cmake
2순위 사용자 정의 경로 CMAKE_MODULE_PATH <filename>.cmake
3순위 CMake 설치 경로 CMAKE_ROOT/...Modules <filename>.cmake

 

 

 

■ include와 find_package비교

기능 include find_package
단순 CMake 코드 가져오기 O X
함수/변수 정의 불러오기 O O (간접적으로)
외부 라이브러리 탐색 X O
IMPORTED target wprhd X O
CMake built-in 모듈 사용 O O
REQUIRED, VERSION 체크 X O

 

 

 

참고자료

https://cmake.org/cmake/help/latest/command/include.html#command:include

https://cmake.org/cmake/help/book/mastering-cmake/chapter/Modules.html

https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html#manual:cmake-modules(7)

https://junstar92.tistory.com/215

반응형