CMake - include module

mohadang·2022년 8월 8일
0

CMake

목록 보기
17/24
post-thumbnail

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
profile
mohadang

0개의 댓글