Cmakelists 使用

轉載 https://blog.csdn.net/afei__/article/details/81201039

常用變量

預定義變量

PROJECT_SOURCE_DIR:工程的根目錄
PROJECT_BINARY_DIR:運行 cmake 命令的目錄,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通過 project 命令定義的項目名稱
CMAKE_CURRENT_SOURCE_DIR:當前處理的 CMakeLists.txt 所在的路徑
CMAKE_CURRENT_BINARY_DIR:target 編譯目錄
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路徑
CMAKE_CURRENT_LIST_LINE:當前所在的行
CMAKE_MODULE_PATH:定義自己的 cmake 模塊所在的路徑,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然後可以用INCLUDE命令來調用自己的模塊
EXECUTABLE_OUTPUT_PATH:重新定義目標二進制可執行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定義目標鏈接庫文件的存放位置

環境變量

使用環境變量

 $ENV{Name}

寫入環境變量

 set(ENV{Name} value) # 這裏沒有“$”符號

系統信息

CMAKE_MAJOR_VERSION:cmake 主版本號,比如 3.4.1 中的 3
­CMAKE_MINOR_VERSION:cmake 次版本號,比如 3.4.1 中的 4
­CMAKE_PATCH_VERSION:cmake 補丁等級,比如 3.4.1 中的 1
­CMAKE_SYSTEM:系統名稱,比如 Linux-­2.6.22
­CMAKE_SYSTEM_NAME:不包含版本的系統名,比如 Linux
­CMAKE_SYSTEM_VERSION:系統版本,比如 2.6.22
­CMAKE_SYSTEM_PROCESSOR:處理器名稱,比如 i686
­UNIX:在所有的類 UNIX 平臺下該值爲 TRUE,包括 OS X 和 cygwin
­WIN32:在所有的 win32 平臺下該值爲 TRUE,包括 cygwin

主要開關選項

BUILD_SHARED_LIBS:這個開關用來控制默認的庫編譯方式,如果不進行設置,使用 add_library 又沒有指定庫類型的情況下,默認編譯生成的庫都是靜態庫。如果 set(BUILD_SHARED_LIBS ON) 後,默認生成的爲動態庫
CMAKE_C_FLAGS:設置 C 編譯選項,也可以通過指令 add_definitions() 添加
CMAKE_CXX_FLAGS:設置 C++ 編譯選項,也可以通過指令 add_definitions() 添加

主要編寫步驟

#指定 cmake 的最小版本
cmake_minimum_required(VERSION 3.4.1)
#項目名稱
project(demo)
add_executable(demo demo.cpp) # 生成可執行文件
#add_library(common STATIC util.cpp) # 生成靜態庫
#add_library(common SHARED util.cpp) # 生成動態庫或共享庫
#指定生成庫的需要用的cpp文件
add_library(demo STATIC demo.cpp test.cpp util.cpp)
aux_source_directory(. SRC_LIST) # 搜索當前目錄下的所有.cpp文件
add_library(demo ${SRC_LIST})
{
自定義搜索規則
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
}

find_library( # Sets the name of the path variable.
              log-lib
 
              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )
#設置包括的頭文件
include_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${CMAKE_CURRENT_BINARY_DIR}
        ${CMAKE_CURRENT_SOURCE_DIR}/include
 )
 
#設置搜索的庫目錄
link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)
target_link_libraries( # 目標庫
                       demo
 
                       # 目標庫需要鏈接的庫
                       # log-lib 是上面 find_library 指定的變量名
                       ${log-lib} )
#設置變量
set(SRC_LIST main.cpp test.cpp)
#追加變量
set(SRC_LIST ${SRC_LIST} test.cpp)
##追加或者刪除變量
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
add_executable(demo ${SRC_LIST})

find_package 基本原理

https://blog.csdn.net/sen873591769/article/details/90183015
如果我們在cmake某個程序的時候,經常會提示找不到某個所依賴的庫,那麼這是時候我們就需要檢查我們引入依賴庫的路徑對不對了, Cmake中一個自動尋找函數find_package()可以幫我們實現這個功能。

概括來說,以opencv爲例:find_package()函數,如果找到了相關的頭文件和庫文件,則會相應保存在OpenCV_INCLUDE_DIRS 和OpenCV_LIBRARIES (OpenCV_LIBS) 中。
我們可以輸出一下看看上面兩個cmake變量是什麼內容,在上述文件後面加如下

//以slam十四講中的joinMap程序Cmake文件爲例:
cmake_minimum_required( VERSION 2.8 )
project( joinMap )

set( CMAKE_BUILD_TYPE Release )
set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )

# opencv 
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )

# eigen 
include_directories( "/usr/include/eigen3/" )

# pcl 
find_package( PCL REQUIRED COMPONENT common io )
include_directories( ${PCL_INCLUDE_DIRS} )
add_definitions( ${PCL_DEFINITIONS} )

list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
add_executable( joinMap joinMap.cpp )
target_link_libraries( joinMap ${OpenCV_LIBS} ${PCL_LIBRARIES} )


message("!!!!!!!!OpenCV_INCLUDE_DIRS:" ${OpenCV_INCLUDE_DIRS})
message("!!!!!!!!OpenCV_LIBRARIES:" ${OpenCV_LIBRARIES} )

關鍵字解析

version和EXACT: 都是可選的,version指定的是版本,如果指定就必須檢查找到的包的版本是否和version兼容。如果指定EXACT則表示必須完全匹配的版本而不是兼容版本就可以。
QUIET 可選字段,表示如果查找失敗,不會在屏幕進行輸出(但是如果指定了REQUIRED字段,則QUIET無效,仍然會輸出查找失敗提示語)。
MODULE可選字段。前面提到說“如果Module模式查找失敗則回退到Config模式進行查找”,但是假如設定了MODULE選項,那麼就只在Module模式查找,如果Module模式下查找失敗並不回落到Config模式查找。
CONFIG可選字段。直接在Config模式中查找。下文會介紹什麼是Moudule模式什麼是Config模式。
REQUIRED可選字段。表示一定要找到包,找不到的話就立即停掉整個cmake。而如果不指定REQUIRED則cmake會繼續執行。
COMPONENTS:可選字段,表示查找的包中必須要找到的組件(components),如果有任何一個找不到就算失敗,類似於REQUIRED,導致cmake停止執行。上面的例子中find_package( PCL REQUIRED COMPONENT common io )我們就利用了該關鍵字尋找了common和io包。
OPTIONAL_COMPONENTS:可選的模塊,找不到也不會讓cmake停止執行。

find_package原理

首先,cmake本身不提供任何搜索庫的便捷方法,所有搜索庫並給變量賦值的操作必須由cmake代碼完成,比如FindXXX.cmake和XXXConfig.cmake。只不過,庫的作者通常會提供這兩個文件,以方便使用者調用。
find_package採用兩種模式搜索庫:

Module模式:搜索CMAKE_MODULE_PATH指定路徑下的FindXXX.cmake文件,執行該文件從而找到XXX庫。其中,具體查找庫並給XXX_INCLUDE_DIRS和XXX_LIBRARIES兩個變量賦值的操作由FindXXX.cmake模塊完成(先搜索當前項目裏面的Module文件夾裏面提供的FindXXX.cmake,然後再搜索系統路徑/usr/local/share/cmake-x.y/Modules/FindXXX.cmake)
Config模式:搜索XXX_DIR指定路徑下的XXXConfig.cmake文件,執行該文件從而找到XXX庫。其中具體查找庫並給XXX_INCLUDE_DIRS和XXX_LIBRARIES兩個變量賦值的操作由XXXConfig.cmake模塊完成。
對於可能沒有***.cmake和***Config.cmake的庫文件,可以直接找到其頭文件和庫文件所在文件夾,直接進行路徑賦值:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章