CMakeLists.txt详解
一:CMakeLists.txt文件是cmake用來生成Makefile文件需要的一個描述編譯鏈接的規則文件
學習cmake需要提前了解gcc等編譯命令,先來解釋一條最簡單的命令
? ? ? ? gcc ./source/*.c -o ./bin/test -I ./include -L ./lib/ -l動態庫名
上述命令的解釋為:用gcc工具編譯當前目錄下source文件夾中的所有的.c文件 生成目標為test的可執行文件且將其放在當前目錄下的bin文件夾中,其所用到的頭文件所在路徑為當前目錄下的include文件夾,動態庫文件路徑為當前目錄下的lib文件夾,編譯時需要用到的動態庫為庫名所對應的.so動態庫
二:CMakeList.txt規則文件常用變量
(1)常用變量
? ? ? ? PROJECT_NAME:用函數project(demo)指定的項目名稱,這里變量的值為demo
? ? ? ? PROJECT_SOURCE_DIR:工程的根目錄
? ? ? ? PROJECT_BINARY_DIR:執行cmake命令的目錄,如果mkdir build ,cd build, cmake ../,的話,該變量的值為build目錄
????????CMAKE_CURRENT_SOURCE_DIR:當前處理的CMakeLists.txt文件所在目錄
? ? ? ? CMAKE_CURRENT_BINARY_DIR:cmake當前正在處理的二進制目錄
????????CMAKE_CURRENT_LIST_DIR:CMakeLists.txt的完整路徑
????????CMAKE_CURRENT_LIST_LINE:當前所在行
? ? ? ? CMAKE_C_FLAGS:設置C編譯選項
? ? ? ? CMAKE_CXX_FLAGS:設置C++編譯選項
? ? ? ? CMAKE_INSTALL_PREFIX:指定install指令安裝文件的根目錄
? ? ? ? EXECUTABLE_OUTPUT_PATH:生成目標可執行文件的輸出位置
? ? ? ? LIBRARY_OUTPUT_PATH:庫文件輸出位置
? ? 三:指令詳解
? ? ? ?? ? ? 需要注意的是CMakeLists.txt文件中的指令不區分大小寫?
(1)PROJECT(projectname [CXX] [C] [Java]):
該函數定義工程名字,并指定了工程的語言,支持語言的列表可以省略,默認情況下表示支持所有語言,并隱式定義了兩個cmake的變量? ?
? ? ? ? PROJECT_BINARY_DIR:執行cmake的目錄
? ? ? ? PROJECT_SOURCE_DIR:工程的根目錄
(2).SET(<variable> <value>... [PARENT_SCOPE])
顯式設置普通變量
????????variable:只能有一個;
????????value:可以有0個,1個或多個,當value值為空時,方法同unset,用于取消設置的值;
????????PARENT_SCOPE(父作用域):作用域,除PARENT_SCOPE外還有function scope(方法作用域)和directory scope(目錄作用域)。
? ? ?2.set(<variable> <value>... CACHE <type> <docstring> [FORCE]) #設置緩存條目
????????variable:只能有一個
????????value:可以有0個,1個或多個,當value值為空時,方法同unset,用于取消設置的值
????????CACHE:關鍵字,說明是緩存變量設置
????????type(類型):必須為以下中的一種:
????????????????BOOL:有ON/OFF,兩種取值
????????????????FILEPATH:文件的全路徑
????????????????PATH:目錄路徑
????????????????STRING:字符串
????????????????INTERNAL:字符串
????????docstring:總結性文字(字符串)
????????[FORCE]:變量名相同,第二次調用set方法時,第一次的value將會被覆蓋
? ? ?3.set(ENV{<variable>} [<value>]) #設置環境變量
????????variable:只有一個
??value:一般來說,只有一個,為空時,將清除之前設置的變量值,多個時,取值最近的一個,之后的值將被忽略
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin):設置可執行文件的輸出路徑為build/bin
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib):設置庫文件的輸出路徑為build/lib
(3)include_directories(xxx)
????????????????給工程添加頭文件,例如使用opencv時需要包含/usr/local/include/opencv/cv.h這個頭文件,則我們需要include_directories(/usr/local/include),在調用的函數里寫 #include “opencv/cv.h”即可
????????target_include_directories()
????????????????為指定的目標添加搜索頭文件
include_directories()和target_include_directories()區別
include_directories 會為當前CMakeLists.txt的所有目標,以及之后添加的所有子目錄的目標添加頭文件搜索路徑。因此,慎用,會影響全局target
target_include_directories 只會為指定目標包含頭文件搜索路徑。如果想為不同目標設置不同的搜索路徑,target_include_directories 更合適
例:target_include_directories(test xxx ${PROJECT_SOURCE_DIR}/include)
如果xxx為PRIVATE 則表示頭文件只能由 test使用
如果xxx為INTERFACE 則表示頭文件只能由 調用test的文件使用
如果xxx為PUBLIC 則test和任何調用test的文件都能使用頭文件
(4)add_executable(可執行文件名 1.cpp 2.ppp …)
添加可執行文件,其中可執行文件需要用到1.cpp和2.cpp 工程會給1.cpp和2.cpp編譯生成一個可執行文件
(5)add_library(生成的庫名稱 STATIC/SHARED 源文件.cpp)
將源文件生成 靜態/動態?庫文件 STSTIC 表示靜態庫最終會編入到可執行文件中,SHARED(常見參數)表示動態庫(又稱共享庫)方式
(6)target_link_libraries (庫/可執行文件 library1 library2 ...)
為庫或者可執行文件添加需要鏈接的庫
注:需要放在add_executable之后
(7)add_subdirectory(source_dir)
向當前工程添加存放其他源文件的子目錄,用于多目錄下都有CMakeLists.txt文件的情況
(8)aux_source_directory( 文件目錄 變量名)
把文件目錄下的所有源文件儲存在變量中
例:aux_source_directory(${PROJECT_SOURCE_DIR}/ DIR_SRCS) 表示把工程目錄的源文件添加到DIR_SRCS變量中
(9)message(模式 "output msg" )
打印輸出信息,常見模式有FATAL_ERROR、WARNING、STATUS、DEBUG等
(10)find_package(<NAME> 版本號 EXACT/QUIET/REQUIRED)
version:指定查找庫的版本號。 EXACT:要求該版本號必須精確匹配。 QUIET:禁掉沒有找到時的警告信息。如果沒找到則忽略這一問題,繼續執行 REQUIRED選項表示如果包沒有找到的話,CMake的過程會終止,并輸出警告信息
當find_package找到一個庫的時候,以下變量會自動初始化:
<NAME>_FOUND : 顯示是否找到庫的標記
<NAME>_INCLUDE_DIRS 或 <NAME>INCLUDES : 頭文件路徑
<NAME>_LIBRARIES 或 <NAME>_LIBS : 庫文件?
注:如果CMake自動找不到路徑,我們需要手動設置路徑,如 先 set(OpenCV_INCLUDE_DIRS “home/hwh/Opencv3.1/build”) 設置路徑 然后find_package(OpenCV 3.1 REQUIRED)
(11)file(GLOB 變量 "路徑")
會在路徑下查找目標文件并保存在變量中
(12)execute_process(COMMAND shell命令 WORKING_DIRECTORY shell命令的工作目錄)
執行shell命令
(13)foreach(var ${list})
? ? ? ? ? ? ? ? xxx
? ? ? ? ? endforeach()
變量var從list中取值,并循環執行xxx命令
(14)install指令
install(TARGETS a.a b.so exe?ARCHIVE a.a? DESTINATION lib/? LIBRARY b.so DESTINATION lib/ RUNTIME exe DESTINATION bin/)
TARGETS:通過ADD_EXECUTABLE ADD_LIBRARY定義的目標文件,ARCHIVE特指靜態庫,LIBRARY特指動態庫,RUNTIME特指可執行目標二進制,DESTINATION定義了安裝的路徑
FILE:普通文件的安裝
PROGRAMS :可執行腳本
DIRECTORY:目錄安裝
(15)add_definitions()
向編譯器添加-D定義,如ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),參數之間用空格隔開
如果代碼中定義了#ifdef ENABLE_DEBUG #endif,這個代碼塊就會生效
如果要添加其他編譯器開關,可以通過CMAKE_C_FLAGS變量和CMAKE_CXX_FLAGS變量設置
(16)ADD_DEPENDENCIES()
定義target依賴其他的target,確保在編譯本target之前,其他的target以及被構建
(17)FILE()
文件操作指令
(18)include(file OPTIONAL)
用于載入CMakeLists.txt文件和.cmake文件,模塊文件搜索路徑與CMAKE_MODULE_PATH
變量指定的路徑有關,OPTIONAL參數作用是即使文件不存在也不報錯
(19)find_xxx(<VAR> name1 path1 path2)
查找相應的文件,VAR變量表示找到文件的全路徑
(20)
function的定義格式如下:后面可作為命令供調用
function(<name> [<arg1> ...])
????????<commands>
endfunction()
其中name是function的名字,參數為arg1, arg2等。
注意:變量的取值使用${},但在if控制語句中和直接使用變量名
?????????????????? Make VERBOSE=1可以看到makefile執行的詳細步驟
?????????????????? CMAKE_INCLUDE_PATH 與CMAKE_LIBRARY_PATH是環境變量,兩者都被用于find_path
總結
以上是生活随笔為你收集整理的CMakeLists.txt详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 达芬奇密码题解
- 下一篇: ROS::差速运动模型机器人运动控制