【Tools】cmake 常用变量和常用环境变量查表手册---整理
原文鏈接:https://blog.csdn.net/gubenpeiyuan/article/details/8667279
一.cmake 變量引用的方式:
前面我們已經(jīng)提到了,使用${}進(jìn)行變量的引用。在IF等語(yǔ)句中,是直接使用變量名而不通過(guò)${}取值.
二.cmake 自定義變量的方式:
主要有隱式定義和顯式定義兩種,前面舉了一個(gè)隱式定義的例子,就是 PROJECT 指令,他會(huì)隱式的定義<projectname>_BINARY_DIR 和<projectname>_SOURCE_DIR 兩個(gè)變量。
顯式定義的例子我們前面也提到了,使用 SET 指令,就可以構(gòu)建一個(gè)自定義變量了。
比如:
SET(HELLO_SRC main.SOURCE_PATHc),就 PROJECT_BINARY_DIR 可以通過(guò)${HELLO_SRC}來(lái)引用這個(gè)自定義變量了.
三.cmake 常用變量:
-
1.工程頂層目錄、工程編譯發(fā)生的目錄
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR
這三個(gè)變量指代的內(nèi)容是一致的,如果是 in source 編譯,指得就是工程頂層目錄,如果是 out-of-source 編譯,指的是工程編譯發(fā)生的目錄。PROJECT_BINARY_DIR 跟其他指令稍有區(qū)別,現(xiàn)在,你可以理解為他們是一致的。 -
2.工程頂層目錄
CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR
這三個(gè)變量指代的內(nèi)容是一致的,不論采用何種編譯方式,都是工程頂層目錄。
也就是在 in source 編譯時(shí),他跟 CMAKE_BINARY_DIR 等變量一致。
PROJECT_SOURCE_DIR 跟其他指令稍有區(qū)別,現(xiàn)在,你可以理解為他們是一致的。 -
3.CMAKE_CURRENT_SOURCE_DIR
指的是當(dāng)前處理的 CMakeLists.txt 所在的路徑,比如上面我們提到的 src 子目錄。 -
4.CMAKE_CURRRENT_BINARY_DIR
如果是 in-source 編譯,它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是 out-of-source 編譯,他指的是 target 編譯目錄。
使用我們上面提到的 ADD_SUBDIRECTORY(src bin)可以更改這個(gè)變量的值。
使用 SET(EXECUTABLE_OUTPUT_PATH <新路徑>)并不會(huì)對(duì)這個(gè)變量造成影響,它僅僅修改了最終目標(biāo)文件存放的路徑。 -
5.CMAKE_CURRENT_LIST_FILE
輸出調(diào)用這個(gè)變量的 CMakeLists.txt 的完整路徑 -
6.CMAKE_CURRENT_LIST_LINE
輸出這個(gè)變量所在的行 -
7.CMAKE_MODULE_PATH
這個(gè)變量用來(lái)定義自己的 cmake 模塊所在的路徑。如果你的工程比較復(fù)雜,有可能會(huì)自己編寫(xiě)一些 cmake 模塊,這些 cmake 模塊是隨你的工程發(fā)布的,為了讓 cmake 在處理CMakeLists.txt 時(shí)找到這些模塊,你需要通過(guò) SET 指令,將自己的cmake模塊路徑設(shè)置一下。
比如
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
這時(shí)候你就可以通過(guò) INCLUDE 指令來(lái)調(diào)用自己的模塊了。 -
8.EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH
分別用來(lái)重新定義最終結(jié)果的存放目錄,前面我們已經(jīng)提到了這兩個(gè)變量。 -
9.PROJECT_NAME
返回通過(guò) PROJECT 指令定義的項(xiàng)目名稱(chēng)。
四.cmake 調(diào)用環(huán)境變量的方式
使用$ENV{NAME}指令就可以調(diào)用系統(tǒng)的環(huán)境變量了。
比如
MESSAGE(STATUS “HOME dir: $ENV{HOME}”)
設(shè)置環(huán)境變量的方式是:
SET(ENV{變量名} 值)
-
1.CMAKE_INCLUDE_CURRENT_DIR
自動(dòng)添加 CMAKE_CURRENT_BINARY_DIR和 CMAKE_CURRENT_SOURCE_DIR 到當(dāng)前處理
的 CMakeLists.txt。相當(dāng)于在每個(gè)CMakeLists.txt加入:
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -
2.CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
將工程提供的頭文件目錄始終至于系統(tǒng)頭文件目錄的前面,當(dāng)你定義的頭文件確實(shí)跟系統(tǒng)發(fā)生沖突時(shí)可以提供一些幫助。 -
3.CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH我們?cè)谏弦还?jié)已經(jīng)提及。
五.系統(tǒng)信息
- CMAKE_MAJOR_VERSION,CMAKE 主版本號(hào),比如 2.4.6 中的 2
- 2.CMAKE_MINOR_VERSION,CMAKE 次版本號(hào),比如 2.4.6 中的 4
- 3.CMAKE_PATCH_VERSION,CMAKE 補(bǔ)丁等級(jí),比如 2.4.6 中的 6
- 4.CMAKE_SYSTEM,系統(tǒng)名稱(chēng),比如 Linux-2.6.22
- 5.CMAKE_SYSTEM_NAME,不包含版本的系統(tǒng)名,比如 Linux
- 6.CMAKE_SYSTEM_VERSION,系統(tǒng)版本,比如 2.6.22
- 7.CMAKE_SYSTEM_PROCESSOR,處理器名稱(chēng),比如 i686.
- 8.UNIX,在所有的類(lèi) UNIX 平臺(tái)為 TRUE,包括 OS X 和 cygwin
- 9.WIN32,在所有的 win32 平臺(tái)為 TRUE,包括 cygwin
六.主要的開(kāi)關(guān)選項(xiàng):
- 1.CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS,用來(lái)控制 IF ELSE 語(yǔ)句的書(shū)寫(xiě)方式,在
下一節(jié)語(yǔ)法部分會(huì)講到。 - 2.BUILD_SHARED_LIBS
這個(gè)開(kāi)關(guān)用來(lái)控制默認(rèn)的庫(kù)編譯方式,如果不進(jìn)行設(shè)置,使用 ADD_LIBRARY并沒(méi)有指定庫(kù)
類(lèi)型的情況下,默認(rèn)編譯生成的庫(kù)都是靜態(tài)庫(kù)。
如果 SET(BUILD_SHARED_LIBS ON)后,默認(rèn)生成的為動(dòng)態(tài)庫(kù)。 - 3.CMAKE_C_FLAGS
設(shè)置C編譯選項(xiàng),也可以通過(guò)指令 ADD_DEFINITIONS()添加。 - 4.CMAKE_CXX_FLAGS
設(shè)置C++編譯選項(xiàng),也可以通過(guò)指令A(yù)DD_DEFINITIONS()添加。
小結(jié):
本章介紹了一些較常用的 cmake 變量,這些變量?jī)H僅是所有 cmake 變量的很少一部分,目
前 cmake 的英文文檔也是比較缺乏的,如果需要了解更多的 cmake 變量,更好的方式是閱
讀一些成功項(xiàng)目的 cmake 工程文件,比如 KDE4 的代碼。
八.cmake 常用指令
前面我們講到了 cmake 常用的變量,相信“cmake 即編程”的感覺(jué)會(huì)越來(lái)越明顯,無(wú)論如何,我們?nèi)匀豢梢钥吹?cmake 比 autotools 要簡(jiǎn)單很多。接下來(lái)我們就要集中的看一看cmake 所提供的常用指令。在前面的章節(jié)我們已經(jīng)討論了很多指令的用法,如
PROJECT,ADD_EXECUTABLE,INSTALL,ADD_SUBDIRECTORY,SUBDIRS,
INCLUDE_DIRECTORIES,LINK_DIRECTORIES,TARGET_LINK_LIBRARIES,SET 等。
本節(jié)會(huì)引入更多的 cmake 指令,為了編寫(xiě)的方便,我們將按照 cmake man page的順序來(lái)介紹各種指令,不再推薦使用的指令將不再介紹,INSTALL 系列指令在安裝部分已經(jīng)做了非常詳細(xì)的說(shuō)明,本節(jié)也不在提及。(你可以將本章理解成選擇性翻譯,但是會(huì)加入更多的個(gè)人理解)
8.1.基本指令
-
1.ADD_DEFINITIONS
向 C/C++編譯器添加-D 定義,比如:
ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),參數(shù)之間用空格分割。
如果你的代碼中定義了#ifdef ENABLE_DEBUG #endif,這個(gè)代碼塊就會(huì)生效。
如果要添加其他的編譯器開(kāi)關(guān),可以通過(guò) CMAKE_C_FLAGS 變量和 CMAKE_CXX_FLAGS 變量設(shè)置。 -
2.ADD_DEPENDENCIES
定義 target 依賴(lài)的其他 target,確保在編譯本 target 之前,其他的 target 已經(jīng)被構(gòu)建。
ADD_DEPENDENCIES(target-name depend-target1 depend-target2 ...) -
3.ADD_EXECUTABLE、ADD_LIBRARY、ADD_SUBDIRECTORY 前面已經(jīng)介紹過(guò)了,這里不再羅唆。
-
4.ADD_TEST 與 ENABLE_TESTING 指令。
ENABLE_TESTING 指令用來(lái)控制 Makefile 是否構(gòu)建 test 目標(biāo),涉及工程所有目錄。語(yǔ)法很簡(jiǎn)單,沒(méi)有任何參數(shù),ENABLE_TESTING(),一般情況這個(gè)指令放在工程的主CMakeLists.txt 中.
ADD_TEST 指令的語(yǔ)法是:
ADD_TEST(testname Exename arg1 arg2 ...)
testname 是自定義的 test 名稱(chēng),Exename 可以是構(gòu)建的目標(biāo)文件也可以是外部腳本等等。后面連接傳遞給可執(zhí)行文件的參數(shù)。如果沒(méi)有在同一個(gè) CMakeLists.txt 中打開(kāi)ENABLE_TESTING()指令,任何 ADD_TEST都是無(wú)效的。
比如我們前面的 Helloworld 例子,可以在工程主 CMakeLists.txt 中添加
ADD_TEST(mytest ${PROJECT_BINARY_DIR}/bin/main)
ENABLE_TESTING()
生成 Makefile 后,就可以運(yùn)行 make test來(lái)執(zhí)行測(cè)試了。
-
5.AUX_SOURCE_DIRECTORY
基本語(yǔ)法是:
AUX_SOURCE_DIRECTORY(dir VARIABLE)
作用是發(fā)現(xiàn)一個(gè)目錄下所有的源代碼文件并將列表存儲(chǔ)在一個(gè)變量中,這個(gè)指令臨時(shí)被用來(lái)自動(dòng)構(gòu)建源文件列表。因?yàn)槟壳?cmake 還不能自動(dòng)發(fā)現(xiàn)新添加的源文件。
比如
AUX_SOURCE_DIRECTORY(. SRC_LIST)
ADD_EXECUTABLE(main ${SRC_LIST})
你也可以通過(guò)后面提到的 FOREACH 指令來(lái)處理這個(gè) LIST -
6.CMAKE_MINIMUM_REQUIRED
其語(yǔ)法為 CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])
比如 CMAKE_MINIMUM_REQUIRED(VERSION 2.5 FATAL_ERROR)
如果 cmake 版本小與 2.5,則出現(xiàn)嚴(yán)重錯(cuò)誤,整個(gè)過(guò)程中止。 -
7.EXEC_PROGRAM
在 CMakeLists.txt 處理過(guò)程中執(zhí)行命令,并不會(huì)在生成的 Makefile 中執(zhí)行。
具體語(yǔ)法為:
EXEC_PROGRAM(Executable [directory in which to run][ARGS <arguments to executable>][OUTPUT_VARIABLE <var>][RETURN_VALUE <var>])用于在指定的目錄運(yùn)行某個(gè)程序,通過(guò) ARGS 添加參數(shù),如果要獲取輸出和返回值,可通過(guò)OUTPUT_VARIABLE 和 RETURN_VALUE 分別定義兩個(gè)變量.
這個(gè)指令可以幫助你在 CMakeLists.txt 處理過(guò)程中支持任何命令,比如根據(jù)系統(tǒng)情況去修改代碼文件等等。
舉個(gè)簡(jiǎn)單的例子,我們要在 src 目錄執(zhí)行 ls 命令,并把結(jié)果和返回值存下來(lái)。
可以直接在 src/CMakeLists.txt 中添加:
在 cmake 生成 Makefile 的過(guò)程中,就會(huì)執(zhí)行 ls 命令,如果返回 0,則說(shuō)明成功執(zhí)行,那么就輸出ls *.c的結(jié)果。關(guān)于IF 語(yǔ)句,后面的控制指令會(huì)提到。
- 8.FILE 指令
文件操作指令,基本語(yǔ)法為:
這里的語(yǔ)法都比較簡(jiǎn)單,不再展開(kāi)介紹了,可參考這篇博客https://blog.csdn.net/gubenpeiyuan/article/details/51098116。
- 9.INCLUDE 指令,用來(lái)載入 CMakeLists.txt 文件,也用于載入預(yù)定義的 cmake 模塊.
INCLUDE(file1 [OPTIONAL])
INCLUDE(module [OPTIONAL])
[OPTIONAL] 參數(shù)的作用是文件不存在也不會(huì)產(chǎn)生錯(cuò)誤。
你可以指定載入一個(gè)文件,如果定義的是一個(gè)模塊,那么將在CMAKE_MODULE_PATH中搜索這個(gè)模塊并載入。
載入的內(nèi)容將在處理到 INCLUDE語(yǔ)句是直接執(zhí)行。
8.2.INSTALL指令
INSTALL 系列指令已經(jīng)在前面的章節(jié)有非常詳細(xì)的說(shuō)明,這里不在贅述,可參考前面的安裝部分。
8.3.FIND_xxx指令
FIND_系列指令主要包含一下指令:
FIND_FILE(<VAR> name1 path1 path2 ...)
VAR 變量代表找到的文件全路徑,包含文件名
FIND_LIBRARY(<VAR> name1 path1 path2 ...)
VAR 變量表示找到的庫(kù)全路徑,包含庫(kù)文件名
FIND_PATH(<VAR> name1 path1 path2 ...)
VAR 變量代表包含這個(gè)文件的路徑。
FIND_PROGRAM(<VAR> name1 path1 path2 ...)
VAR 變量代表包含這個(gè)程序的全路徑。
FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE] [[REQUIRED|COMPONENTS] [componets...]])
用來(lái)調(diào)用預(yù)定義在 CMAKE_MODULE_PATH下的Find<name>.cmake 模塊,你也可以自己定義Find<name>模塊,通過(guò) SET(CMAKE_MODULE_PATH dir)將其放入工程的某個(gè)目錄中供工程使用,我們?cè)诤竺娴恼鹿?jié)會(huì)詳細(xì)介紹 FIND_PACKAGE 的使用方法和Find 模塊的編寫(xiě)。
FIND_LIBRARY 示例:
FIND_LIBRARY(libX X11 /usr/lib) IF(NOT libX) MESSAGE(FATAL_ERROR “l(fā)ibX not found”) ENDIF(NOT libX)8.4.控制指令:
- 1.IF 指令,基本語(yǔ)法為:
另外一個(gè)指令是 ELSEIF,總體把握一個(gè)原則,凡是出現(xiàn)IF的地方一定要有對(duì)應(yīng)的ENDIF.出現(xiàn) ELSEIF 的地方,ENDIF是可選的。
表達(dá)式的使用方法如下:
IF(var),如果變量不是:空,0,N, NO, OFF, FALSE, NOTFOUND 或_NOTFOUND 時(shí),表達(dá)式為真。
IF(NOT var ),與上述條件相反。
IF(var1 AND var2),當(dāng)兩個(gè)變量都為真是為真。
IF(var1 OR var2),當(dāng)兩個(gè)變量其中一個(gè)為真時(shí)為真。
IF(COMMAND cmd),當(dāng)給定的 cmd 確實(shí)是命令并可以調(diào)用是為真。
IF(EXISTS dir)或者IF(EXISTS file),當(dāng)目錄名或者文件名存在時(shí)為真。
IF(file1 IS_NEWER_THAN file2),當(dāng) file1 比 file2 新,或者 file1/file2 其中有一個(gè)不存在時(shí)為真,文件名請(qǐng)使用完整路徑。
IF(IS_DIRECTORY dirname),當(dāng) dirname 是目錄時(shí),為真。
IF(variable MATCHES regex)
IF(string MATCHES regex)
當(dāng)給定的變量或者字符串能夠匹配正則表達(dá)式 regex 時(shí)為真。比如:
數(shù)字比較表達(dá)式:
IF(variable STRLESS string) IF(string STRLESS string) IF(variable STRGREATER string) IF(string STRGREATER string) IF(variable STREQUAL string) IF(string STREQUAL string)按照字母序的排列進(jìn)行比較.
IF(DEFINED variable),如果變量被定義,為真。
一個(gè)小例子,用來(lái)判斷平臺(tái)差異:
上述代碼用來(lái)控制在不同的平臺(tái)進(jìn)行不同的控制,但是,閱讀起來(lái)卻并不是那么舒服,
ELSE(WIN32)之類(lèi)的語(yǔ)句很容易引起歧義。
這就用到了我們?cè)凇俺S米兞俊币还?jié)提到的 CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS開(kāi)關(guān)。
可以SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
這時(shí)候就可以寫(xiě)成:
如果配合 ELSEIF 使用,可能的寫(xiě)法是這樣:
IF(WIN32) #do something related to WIN32 ELSEIF(UNIX) #do something related to UNIX ELSEIF(APPLE) #do something related to APPLE ENDIF(WIN32)- 2.WHILE
WHILE 指令的語(yǔ)法是:
其真假判斷條件可以參考 IF 指令。
- 3.FOREACH
FOREACH 指令的使用方法有三種形式:
(1)列表
像我們前面使用的 AUX_SOURCE_DIRECTORY的例子
AUX_SOURCE_DIRECTORY(. SRC_LIST) FOREACH(F ${SRC_LIST})MESSAGE(${F}) ENDFOREACH(F)(2)范圍
FOREACH(loop_var RANGE total) ENDFOREACH(loop_var)從 0 到 total 以1為步進(jìn)
舉例如下:
最終得到的輸出是:
0 1 2 3 4 5 6 7 8 9 10(3)范圍和步進(jìn)
FOREACH(loop_var RANGE start stop [step]) ENDFOREACH(loop_var)從 start 開(kāi)始到 stop 結(jié)束,以 step 為步進(jìn),
舉例如下
最終得到的結(jié)果是:
5 8 11 14這個(gè)指令需要注意的是,知道遇到 ENDFOREACH 指令,整個(gè)語(yǔ)句塊才會(huì)得到真正的執(zhí)行。
小結(jié):
本小節(jié)基本涵蓋了常用的 cmake 指令,包括基本指令、查找指令、安裝指令以及控制語(yǔ)句等,特別需要注意的是,在控制語(yǔ)句條件中使用變量,不能用${}引用,而是直接應(yīng)用變量名。
掌握了以上的各種控制指令,你應(yīng)該完全可以通過(guò) cmake 管理復(fù)雜的程序了,下一節(jié),我
們將介紹一個(gè)比較復(fù)雜的例子,通過(guò)他來(lái)演示本章的一些指令,并介紹模塊的概念。
九,復(fù)雜的例子:模塊的使用和自定義模塊
你現(xiàn)在還會(huì)覺(jué)得 cmake 簡(jiǎn)單嗎?
本章我們將著重介紹系統(tǒng)預(yù)定義的 Find模塊的使用以及自己編寫(xiě) Find 模塊,系統(tǒng)中提供了其他各種模塊,一般情況需要使用 INCLUDE指令顯式的調(diào)用,FIND_PACKAGE指令是一個(gè)特例,可以直接調(diào)用預(yù)定義的模塊.
其實(shí)使用純粹依靠 cmake 本身提供的基本指令來(lái)管理工程是一件非常復(fù)雜的事情,所以,cmake 設(shè)計(jì)成了可擴(kuò)展的架構(gòu),可以通過(guò)編寫(xiě)一些通用的模塊來(lái)擴(kuò)展 cmake.
在本章,我們準(zhǔn)備首先介紹一下 cmake 提供的FindCURL 模塊的使用。然后,基于我們前面的 libhello共享庫(kù),編寫(xiě)一個(gè)FindHello.cmake模塊.
9.1使用 FindCURL模塊
在/backup/cmake 目錄建立 t5 目錄,用于存放我們的 CURL 的例子。
建立 src 目錄,并建立 src/main.c,內(nèi)容如下:
這段代碼的作用是通過(guò) curl取回 www.linux-ren.org 的首頁(yè)并寫(xiě)入/tmp/curl-test文件中。
建立主工程文件 CMakeLists.txt
建立 src/CMakeLists.txt
ADD_EXECUTABLE(curltest main.c)
現(xiàn)在自然是沒(méi)辦法編譯的,我們需要添加 curl 的頭文件路徑和庫(kù)文件。
方法 1:
直接通過(guò) INCLUDE_DIRECTORIES和 TARGET_LINK_LIBRARIES 指令添加:
我們可以直接在 src/CMakeLists.txt 中添加:
然后建立 build 目錄進(jìn)行外部構(gòu)建即可。
現(xiàn)在我們要探討的是使用 cmake 提供的 FindCURL 模塊。
方法 2,使用 FindCURL 模塊。
向src/CMakeLists.txt 中添加:
對(duì)于系統(tǒng)預(yù)定義的 Find<name>.cmake 模塊,使用方法一般如上例所示:
每一個(gè)模塊都會(huì)定義以下幾個(gè)變量
你可以通過(guò)<name>_FOUND來(lái)判斷模塊是否被找到,如果沒(méi)有找到,按照工程的需要關(guān)閉某些特性、給出提醒或者中止編譯,上面的例子就是報(bào)出致命錯(cuò)誤并終止構(gòu)建。
如果<name>_FOUND 為真,則將<name>_INCLUDE_DIR 加入 INCLUDE_DIRECTORIES,將<name>_LIBRARY加入 TARGET_LINK_LIBRARIES中。
我們?cè)賮?lái)看一個(gè)復(fù)雜的例子,通過(guò)<name>_FOUND來(lái)控制工程特性:
通過(guò)判斷系統(tǒng)是否提供了 JPEG 庫(kù)來(lái)決定程序是否支持 JPEG 功能。
9.2,編寫(xiě)屬于自己的FindHello模塊。
我們?cè)诖饲暗?t3 實(shí)例中,演示了構(gòu)建動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)的過(guò)程并進(jìn)行了安裝。
接下來(lái),我們?cè)?t6 示例中演示如何自定義FindHELLO模塊并使用這個(gè)模塊構(gòu)建工程:
請(qǐng)?jiān)诮?backup/cmake/中建立 t6 目錄,并在其中建立 cmake 目錄用于存放我們自己定義的FindHELLO.cmake 模塊,同時(shí)建立 src 目錄,用于存放我們的源文件。
1,定義cmake/FindHELLO.cmake 模塊
FIND_PATH(HELLO_INCLUDE_DIR hello.h /usr/include/hello /usr/local/include/hello) FIND_LIBRARY(HELLO_LIBRARY NAMES hello PATH /usr/lib /usr/local/lib) IF (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)SET(HELLO_FOUND TRUE) ENDIF (HELLO_INCLUDE_DIR AND HELLO_LIBRARY) IF (HELLO_FOUND)IF (NOT HELLO_FIND_QUIETLY)MESSAGE(STATUS "Found Hello: ${HELLO_LIBRARY}")ENDIF (NOT HELLO_FIND_QUIETLY) ELSE (HELLO_FOUND)IF (HELLO_FIND_REQUIRED)MESSAGE(FATAL_ERROR "Could not find hello library")ENDIF (HELLO_FIND_REQUIRED) ENDIF (HELLO_FOUND)針對(duì)上面的模塊讓我們?cè)賮?lái)回顧一下 FIND_PACKAGE 指令:
FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE] [[REQUIRED|COMPONENTS] [componets...]])
前面的 CURL 例子中我們使用了最簡(jiǎn)單的FIND_PACKAGE 指令,其實(shí)他可以使用多種參數(shù),
QUIET 參數(shù),對(duì)應(yīng)與我們編寫(xiě)的FindHELLO 中的 HELLO_FIND_QUIETLY,如果不指定這個(gè)參數(shù),就會(huì)執(zhí)行:
MESSAGE(STATUS "Found Hello: ${HELLO_LIBRARY}")
REQUIRED 參數(shù),其含義是指這個(gè)共享庫(kù)是否是工程必須的,如果使用了這個(gè)參數(shù),說(shuō)明這個(gè)鏈接庫(kù)是必備庫(kù),如果找不到這個(gè)鏈接庫(kù),則工程不能編譯。對(duì)應(yīng)于
FindHELLO.cmake 模塊中的 HELLO_FIND_REQUIRED變量。
同樣,我們?cè)谏厦娴哪K中定義了 HELLO_FOUND,HELLO_INCLUDE_DIR,HELLO_LIBRARY 變量供開(kāi)發(fā)者在 FIND_PACKAGE 指令中使用。
OK,下面建立 src/main.c,內(nèi)容為:
建立 src/CMakeLists.txt 文件,內(nèi)容如下:
FIND_PACKAGE(HELLO) IF(HELLO_FOUND)ADD_EXECUTABLE(hello main.c)INCLUDE_DIRECTORIES(${HELLO_INCLUDE_DIR})TARGET_LINK_LIBRARIES(hello ${HELLO_LIBRARY}) ENDIF(HELLO_FOUND)為了能夠讓工程找到 FindHELLO.cmake 模塊(存放在工程中的 cmake 目錄)我們?cè)谥鞴こ涛募?CMakeLists.txt 中加入:
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
9.3,使用自定義的FindHELLO模塊構(gòu)建工程
仍然采用外部編譯的方式,建立 build 目錄,進(jìn)入目錄運(yùn)行:
cmake ..
我們可以從輸出中看到:
Found Hello: /usr/lib/libhello.so
如果我們把上面的 FIND_PACKAGE(HELLO)修改為FIND_PACKAGE(HELLO QUIET),則不會(huì)看到上面的輸出。
接下來(lái)就可以使用make命令構(gòu)建工程,運(yùn)行:
./src/hello 可以得到輸出Hello World。
說(shuō)明工程成功構(gòu)建。
四,如果沒(méi)有找到hello library 呢?
我們可以嘗試將/usr/lib/libhello.x移動(dòng)到/tmp目錄,這樣,按照 FindHELLO模塊的定義,就找不到hello library了,我們?cè)賮?lái)看一下構(gòu)建結(jié)果:
cmake ..
仍然可以成功進(jìn)行構(gòu)建,但是這時(shí)候是沒(méi)有辦法編譯的。
修改 FIND_PACKAGE(HELLO)為FIND_PACKAGE(HELLO REQUIRED),將 hello library定義為工程必須的共享庫(kù)。
這時(shí)候再次運(yùn)行 cmake ..
我們得到如下輸出:
因?yàn)檎也坏?libhello.x,所以,整個(gè)Makefile 生成過(guò)程被出錯(cuò)中止。
小結(jié):
在本節(jié)中,我們學(xué)習(xí)了如何使用系統(tǒng)提供的 Find<NAME>模塊并學(xué)習(xí)了自己編寫(xiě)
Find<NAME>模塊以及如何在工程中使用這些模塊。
后面的章節(jié),我們會(huì)逐漸學(xué)習(xí)更多的 cmake 模塊使用方法以及用 cmake 來(lái)管理 GTK 和 QT4工程。
總結(jié)
以上是生活随笔為你收集整理的【Tools】cmake 常用变量和常用环境变量查表手册---整理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【C++】43.使用【类对象】与 【类指
- 下一篇: 【Tools】CMAKE的使用