Knowhow/C, C++, CMake

CMakeLists.txt 팩토링

침닦는수건 2024. 1. 30. 20:27
반응형
${ROOT}
    |-app
    |   |-CMakeLists.txt (3)
    |-core
    |   |-CMakeLists.txt (2)
    |-CMakeLists.txt (1)

 

모든 코드가 CMakeLists.txt 파일 하나로 정리되지는 않는다. 가능은 하다만 팩토링 측면에서 너무 길고 지저분해지므로 권장되는 방식이 아니다. 보통 C++ 프로젝트를 작성할 때 위와 같이 나누곤 하는데 최소 3개로 나누어서 사용한다. 


CMakeLists.txt (1)

(1)의 경우, 프로젝트 전체를 한 번에 build할 때 사용되는 CMakeList로써 큰 설정들만 들어간다.

  • find_package : 프로젝트 전체에 걸쳐 쓰일 것
  • cmake_module : find_package 실패에 대비한 FindXXX.cmake 파일 추가
  • pkg_search_module / pkg_check_modules : find_package 실패에 대한 pkg_config 추가
  • add_subdiretory : app, core와 같은 하위 폴더 build가 연쇄적으로 일어나도록 추가
  • include_directories / link_directories

예시

cmake_minimum_required(VERSION 3.1)
project(example VERSION 0.0 LANGUAGES C CXX)

# Build in release mode by default
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Release")
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(WARN_FLAGS "-Wall")

# Find required packages
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

find_package(OpenCV REQUIRED)
find_package(TBB REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(Boost 1.58.0 REQUIRED COMPONENTS filesystem program_options serialization)

add_subdirectory(app)
add_subdirectory(core)

CMakeLists.txt (2)

(2)의 경우, 프로젝트 핵심이 되는 코드 CMakeLists.txt 이므로 사실 상 본체다. 이 파일에 필요한 모든 것을 다 작성한다. 포함되는 내용들은 다음과 같다.

  • add_library : core에 작성된 코드를 library로 만든다. 추후 executable 만들 때 불러오기 쉬운 형태로 분리는 것.
  • find_package : core 내부에서만 한정적으로 사용할 library가 있는 경우, 여기서도 find_package를 사용할 수 있다.
  • target_include_directories / target_link_directories : core라는 범위 안에서만 include/link하는 것이므로 target_*을 사용.

예시

add_library(core_example SHARED
  src/*.cpp
)

target_include_directories(core_example PUBLIC  
  ${*_INCLUDE_DIR}
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>  
)

target_link_libraries(core_example PUBLIC
  ${*_LIBRARIES}      
)

CMakeLists.txt (3)

(3)의 경우, 라이브러리화되어 완성된 프로젝트를 실행시키는 코드 CMakeLists.txt이므로 가장 간단한 형태다. executable화 하는 것이 사실 전부다.

  • add_executable : 실행용 코드화한다.
  • target_link_libraries : 최소 앞서 라이브러리화 한 프로젝트를 연결해주는 것은 필수
  • target_include_libarires : executable 만들 때 추가로 쓸 라이브러리가 있다면 추가

 

예시

add_executable(action1 action1.cpp)
target_link_libraries(action1 PUBLIC core_example)

add_executable(action2 action2.cpp)
target_link_libraries(action2 PUBLIC core_example)

 

action1.cpp에서 별도로 사용하는 라이브러리가 없다면 target_include_directories 같은 경우 생략되어 있을 것이다. 추가로 사용했다면 당연히 추가해주면 된다. 

반응형

'Knowhow > C, C++, CMake' 카테고리의 다른 글

Eigen Vector4d와 Quanterniond, 그리고 Ceres EigenQuaterniondParameterization()  (0) 2024.02.28
CMakeLists.txt 작성 팁 1  (0) 2024.01.31
STL vector 팁들  (0) 2023.09.27
TBB 팁  (0) 2023.09.25
Boost serialization 팁들  (0) 2023.09.25