幹活|快速了解如何編寫CMakeLists.txt文件?
- 2019 年 10 月 6 日
- 筆記
本文以linux平台下CMakeLists.txt文件書寫方法總結。
一 開頭通用模組
1.1 cmake版本要求
cmake_minimum_required( VERSION 2.8 )
#工程文件名loop_closure,可任取
project( loop_closure )
1.2 編譯模式
IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE Release) ENDIF()
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
當然如果此處在前面加上語句:
set(CMAKE_BUILD_TYPE debug)
即表示設置為debug模式編譯。
1.3 檢查C++版本
檢查C++的版本
# Check C++11 or C++0x support include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") add_definitions(-DCOMPILEDWITHC11) message(STATUS "Using flag -std=c++11.") elseif(COMPILER_SUPPORTS_CXX0X) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") add_definitions(-DCOMPILEDWITHC0X) message(STATUS "Using flag -std=c++0x.") else() message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif()
二 項目文件配置模組
接下來,便開始配置各個庫模組。
2.1 如果僅包含OpenCV庫時
set(OpenCV_DIR "/usr/local/include/opencv3.2.0/share/OpenCV") find_package(OpenCV REQUIRED)
include_directories( ${OpenCV_INCLUDE_DIRS} )
#生成可執行文件
add_executable(${PROJECT_NAME} src/loop_closure.cpp )
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
備註:這裡的OpenCV包含目錄為含有OpenCVConfig.cmake的路徑。
如下圖:


2.2 如果包含第三方庫,該庫為源碼形式(.h和.cpp),非動態鏈接庫

此處以在工程中添加詞袋庫DBoW2為例,這裡的DBoW2是以源碼形式包含,也即未編譯成.so文件。

2.2.1 包含第三庫的頭文件
#設置.h文件對應的路徑
set( DBoW2_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/ThirdParty/DBow-master/include/)
#包含.h文件路徑
include_directories( ${OpenCV_INCLUDE_DIRS} ${DBoW2_INCLUDE_DIRS} ${DBoW2_INCLUDE_DIRS}/DBoW2/)
註:上述為啥要用兩條路徑${DBoW2_INCLUDE_DIRS}和${DBoW2_INCLUDE_DIRS}/DBoW2/?


為了防止在include層找不到,繼續往下一層路徑include/DBoW2/路徑下查找,這是為了防止某些文件的包含路徑不一致導致頭文件查找錯誤。
2.2.2 包含第三方庫的cpp文件


set(DBoW2_SRCS "${PROJECT_SOURCE_DIR}/ThirdParty/DBow-master/src") #生成可執行文件 add_executable(${PROJECT_NAME} src/loop_closure.cpp src/run_main.cpp ${DBoW2_SRCS}/BowVector.cpp ${DBoW2_SRCS}/FBrief.cpp ${DBoW2_SRCS}/FeatureVector.cpp ${DBoW2_SRCS}/FORB.cpp ${DBoW2_SRCS}/FSurf64.cpp ${DBoW2_SRCS}/QueryResults.cpp ${DBoW2_SRCS}/ScoringObject.cpp)
其中,src/loop_closure.cpp src/run_main.cpp 為本工程中我自己實現的,而對於其他的cpp文件,則直接添加路徑即可。
另一種方式,添加cpp文件路徑更為簡潔方便。
file(GLOB DBoW2_SRCS ${PROJECT_SOURCE_DIR}/ThirdParty/DBow-master/src/*.cpp) add_executable(${PROJECT_NAME} src/loop_closure.cpp src/run_main.cpp ${DBoW2_SRCS})
2.3 如果包含第三方庫,為庫形式(此處以靜態庫為例(.a後綴))
在上述工程下,同時還包含有DBoW3庫,此庫已經按默認路徑編譯安裝到電腦記憶體中。我們可以按如下方式添加DBoW3庫。
1)包含頭文件
set( DBoW3_INCLUDE_DIRS "/usr/local/include")
2)添加庫
set( DBoW3_LIBS "/usr/local/lib/libDBoW3.a")
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} ${DBoW3_LIBS} )
通過上述方式,即可調用。
三 一個簡單的CMakeLists.txt文件demo
該demo中相較於上述總結添加的庫,還額外包含了DLib庫。
cmake_minimum_required( VERSION 2.8 ) project( loop_closure ) #set(CMAKE_BUILD_TYPE Debug) IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE Release) ENDIF() MESSAGE("Build type: " ${CMAKE_BUILD_TYPE}) # Check C++11 or C++0x support include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") add_definitions(-DCOMPILEDWITHC11) message(STATUS "Using flag -std=c++11.") elseif(COMPILER_SUPPORTS_CXX0X) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") add_definitions(-DCOMPILEDWITHC0X) message(STATUS "Using flag -std=c++0x.") else() message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() #opencv #set(OpenCV_DIR "/usr/local/include/opencv3.2.0/share/OpenCV") set(OpenCV_DIR "/opt/ros/kinetic/share/OpenCV-3.3.1-dev") find_package(OpenCV REQUIRED) set( DBoW3_INCLUDE_DIRS "/usr/local/include") set( DBoW2_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/ThirdParty/DBow-master/include/) message(${DBoW2_INCLUDE_DIRS}) #important #file(GLOB DBoW2_SRCS ${PROJECT_SOURCE_DIR}/ThirdParty/DBow-master/src/*.cpp) #message(${DBoW2_SRCS}) set(DBoW2_SRCS "${PROJECT_SOURCE_DIR}/ThirdParty/DBow-master/src") message(${DBoW2_SRCS}) find_package(DLib QUIET PATHS ${DEPENDENCY_INSTALL_DIR}) if(${DLib_FOUND}) message("DLib library found, using it from the system") include_directories(${DLib_INCLUDE_DIRS}) add_custom_target(Dependencies) else(${DLib_FOUND}) message("DLib library not found in the system, it will be downloaded on build") option(DOWNLOAD_DLib_dependency "Download DLib dependency" ON) if(${DOWNLOAD_DLib_dependency}) ExternalProject_Add(DLib PREFIX ${DEPENDENCY_DIR} GIT_REPOSITORY http://github.com/dorian3d/DLib GIT_TAG master INSTALL_DIR ${DEPENDENCY_INSTALL_DIR} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>) add_custom_target(Dependencies ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} DEPENDS DLib) else() message(SEND_ERROR "Please, activate DOWNLOAD_DLib_dependency option or download manually") endif(${DOWNLOAD_DLib_dependency}) endif(${DLib_FOUND}) include_directories( ${OpenCV_INCLUDE_DIRS} ${DBoW3_INCLUDE_DIRS} ${DBoW2_INCLUDE_DIRS} ${DBoW2_INCLUDE_DIRS}/DBoW2/) message("DBoW3_INCLUDE_DIRS ${DBoW3_INCLUDE_DIRS}") message("DBoW2_INCLUDE_DIRS ${DBoW2_INCLUDE_DIRS}") message("opencv ${OpenCV_VERSION}") # dbow3 # dbow3 is a simple lib so I assume you installed it in default directory set( DBoW3_LIBS "/usr/local/lib/libDBoW3.a") add_executable(${PROJECT_NAME} src/loop_closure.cpp src/run_main.cpp ${DBoW2_SRCS}/BowVector.cpp ${DBoW2_SRCS}/FBrief.cpp ${DBoW2_SRCS}/FeatureVector.cpp ${DBoW2_SRCS}/FORB.cpp ${DBoW2_SRCS}/FSurf64.cpp ${DBoW2_SRCS}/QueryResults.cpp ${DBoW2_SRCS}/ScoringObject.cpp ) message(${DBoW2_SRCS}/BowVector.cpp) target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} ${DLib_LIBS} ${DBoW3_LIBS} )
四 跋
以上僅僅為CMakeLists.txt的一個簡單用法梳理,如有不到之處,還請批評指正。對於大型工程的管理,還有很多學問可以挖掘,此處限於篇幅便不再展示。