include를 사용하여 모듈 포함
- cmake 모듈은 코드 재사용을 할 수 있는 일반적인 방법이다.
- 모듈은 .cmake 확장자를 가진다.
- include 명령어를 사용하면 모듈을 포함시켜서 사용 가능하다.
# CMakeLists.txt : 표준 모듈인 ProcessorCount 포함하여 사용
cmake_minimum_required(VERSION 2.8)
project(foo NONE)
include(ProcessorCount) <-- 프로세서 갯수 획득하는 ProcessorCount 표준 모듈 포함
ProcessorCount(N) <-- ProcessorCount 사용
message("Number of processors: ${N}") <-- 4
red@DESKTOP-G15ND3V:~/cgold$ cmake -B build
Number of processors: 4 <-- 프로세서 갯수 출력
-- Configuring done
-- Generating done
-- Build files have been written to: /home/red/cgold/build
모듈 포함 경로(include 경로) 설정
- CMAKE_MODULE_PATH 변수를 수정하여 사용자 지정 cmake 모듈이 있는 경로를 추가할 수 있다.
- CMAKE_MODULE_PATH 변수 수정시 list 명령어 사용
- CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(foo NONE)
# 사용자 지정 cmake 모듈 경로 추가
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
include(MyModule) # 모듈 포함
# modules/MyModule.cmake
message("Hello from MyModule!")
[cmake-sources]> rm -rf _builds
[cmake-sources]> cmake -Hinclude-users -B_builds
Hello from MyModule! <-- MyModule.cmake 모듈이 포함됨
-- Configuring done
-- Generating done
모듈 포함 경로 변경
- 모듈 포함 경로를 바꾸기 위해서는 기존 값에 APPEND 해야 한다.
- 경로를 OVERWRITE 하면 안된다. OVERWRITE 할 경우 기존 표준 포함 경로들이 모두 제거되어 정상적으로 동작하지 않을 수 있다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
include(ProcessorCount)
ProcessorCount(N)
message("Number of processors: ${N}")
# modules/ProcessorCount.cmake
function(ProcessorCount varname)
message("Force processor count")
set("${varname}" 16 PARENT_SCOPE)
endfunction()
red@DESKTOP-G15ND3V:~/cgold$ cmake -B build
Force processor count
Number of processors: 16 # 결과
-- Configuring done
-- Generating done
-- Build files have been written to: /home/red/cgold/build
네임스페이스
- 모듈을 포함시키는 과정에서 다른 모듈과 이름이 같으면 충돌할 수 잇다.
- ex) : 부모 프로젝트에서 모듈을 포함 하고 서브 프로젝트에서 이미 포함된 모듈을 다시 포함
- 모듈이 다른 모듈과 충돌하지 않도록 하려면 프로젝트 이름과 함께 해당 이름을 네임스페이스로 지정할 수 있다.
# MyModule.cmake 중복 포함 구조
.
├── CMakeLists.txt
├── bar
│ ├── CMakeLists.txt
│ └── modules
│ └── MyModule.cmake
├── main.cc
└── modules
└── MyModule.cmake
# 최상위 CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(foo NONE)
message(STATUS "output ${CMAKE_CURRENT_LIST_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
include(MyModule) <-- 첫번째 MyModule 추가
add_subdirectory(bar) <-- 서브 프로젝트 추가
# bar/CMakeLists.txt, 서브 프로젝트
cmake_minimum_required(VERSION 2.8)
project(bar NONE)
Message(STATUS "@@@@@@@@@@@@@@@bar submodule@@@@@@@@@@@@@@@")
Message(STATUS "output ${CMAKE_CURRENT_LIST_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
# bar/modules/MyModule.cmake 모듈이 추가될 것을 기대한다.
include(MyModule) # 두번째 MyModule 추가, 그러나 최상위 모듈에서 이미 추가되어 있음
# modules/MyModule.cmake
message("Hello from MyModule - root")
# bar/modules/MyModule.cmake
message("Hello from MyModule - bar")
red@DESKTOP-G15ND3V:~/cgold$ cmake -B build
-- output /home/red/cgold
Hello from MyModule - root # 최상위 모듈은 modules/MyModule.cmake 추가됨
-- @@@@@@@@@@@@@@@bar submodule@@@@@@@@@@@@@@@
-- output /home/red/cgold/bar
Hello from MyModule - root # 서브 모듈도 modules/MyModule.cmake가 추가됨
-- Configuring done
-- Generating done
-- Build files have been written to: /home/red/cgold/build
bar/modules/MyModule.cmake 는 추가되지 않음
- 사실 bar/CMakeLists.txt의 동작은 다음과 같치 처리 되었다.
cmake_minimum_required(VERSION 2.8)
project(bar NONE)
Message(STATUS "@@@@@@@@@@@@@@@bar submodule@@@@@@@@@@@@@@@")
Message(STATUS "output ${CMAKE_SOURCE_DIR}")
# list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/modules") # 있으나 없으나 상관 없음
include(MyModule) # 상위 프로젝트에서 이미 포함 하였기에 사용 가능
프로젝트와 모듈의 차이
- project를 추가(add_subdirectory)하면 빌드 시스템에 프로젝트가 추가되지만 모듈(.cmake)를 추가(include)하면 프로젝트가 추가되지 않는다.
# CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(foo NONE)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
include(root_module) # 모듈 추가 : 프로젝트 생성하지 않음
add_subdirectory(bar) # bar 서브 프로젝트를 추가 : 프로젝트 생성
# bar/CMakeLists.txt, bar 서브 프로젝트
cmake_minimum_required(VERSION 2.8)
project(bar NONE)
# 실행
# build 디렉터리에 빌드 시스템이 생성된다
cmake -B build
# tree
red@DESKTOP-G15ND3V:~/cgold$ tree .
.
├── CMakeLists.txt
├── bar
│ ├── CMakeLists.txt
│ └── modules
│ └── bar_module.cmake
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.18.2
│ │ │ └── CMakeSystem.cmake
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── Makefile.cmake
│ │ ├── Makefile2
│ │ ├── TargetDirectories.txt
│ │ ├── cmake.check_cache
│ │ └── progress.marks
│ ├── Makefile
│ ├── bar # bar 서브 프로젝트가 생성 되었다.
│ │ ├── CMakeFiles
│ │ │ ├── CMakeDirectoryInformation.cmake
│ │ │ └── progress.marks
│ │ ├── Makefile # bar 서브 프로젝트를 빌드하기 위한 프로젝트 파일
│ │ └── cmake_install.cmake
│ └── cmake_install.cmake
├── main.cc