CMake路徑搜索

目錄:
cmake中定義搜索路徑
修改環(huán)境變量增加搜索路徑
FIND 系列指令尚洽,通過FIND尋找路徑并進行添加
大型開源庫路徑添加方式
find_package采用兩種模式搜索庫

路徑搜索,這里介紹頭文件的路徑搜索和庫文件的路徑搜索。

cmake中定義搜索路徑

cmake中定義頭文件的搜索路徑:INCLUDE_DIRECTORIES 命令添加搜索路徑
庫文件的搜索路徑是:LINK_DIRECTORIES 命令添加庫搜索路徑

link_libraries:(添加需要鏈接的庫文件路徑琉历,注意這里是全路徑)俩由,該用法已經(jīng)被廢棄馒索。
為最終目標鏈接庫使用: TARGET_LINK_LIBRARIES 鏈接庫(動態(tài)庫和靜態(tài)庫)
需要鏈接的庫,會根據(jù)系統(tǒng)動態(tài)庫的搜索路徑依次進行搜索铛绰。這里可以直接寫庫的名稱(程序定義路徑,環(huán)境變量定義的路徑产喉,系統(tǒng)默認搜索路徑)

target_link_libraries 要在 add_executable 之后捂掰,link_libraries 要在 add_executable 之前

修改環(huán)境變量增加搜索路徑

CMAKE_INCLUDE_PATH 和CMAKE_LIBRARY_PATH

特殊的環(huán)境變量CMAKE_INCLUDE_PATHCMAKE_LIBRARY_PATH務(wù)必注意,這兩個是環(huán)境變量而不是 cmake 變量曾沈。
使用方法是要在 bash 中用 export 或者在 csh 中使用 set 命令設(shè)置或者 CMAKE_INCLUDE_PATH=/home/include cmake ..等方式这嚣。如果頭文件沒有存放在常規(guī)路徑(/usr/include, /usr/local/include等), 則可以通過這些變量就行彌補晦譬。
為了將程序更智能一點疤苹,我們可以使用 CMAKE_INCLUDE_PATH 來進行,使用 bash 的方法 如下:
export CMAKE_INCLUDE_PATH=/usr/include/hello

eg:
設(shè)置export CMAKE_INCLUDE_PATH=/usr/include/hello
頭文件中將 INCLUDE_DIRECTORIES(/usr/include/hello)替換為: 
FIND_PATH(myHeader hello.h)
IF(myHeader)
INCLUDE_DIRECTORIES(${myHeader})
ENDIF(myHeader)

這里簡單說明一下敛腌,F(xiàn)IND_PATH 用來在指定路徑中搜索文件名卧土,比如:
FIND_PATH(myHeader NAMES hello.h PATHS /usr/include /usr/include/hello)
這里我們沒有指定路徑惫皱,但是,cmake 仍然可以幫我們找到 hello.h 存放的路徑尤莺,就是因為我們設(shè)置了環(huán)境變量 CMAKE_INCLUDE_PATH旅敷。
如果你不使用 FIND_PATHCMAKE_INCLUDE_PATH 變量的設(shè)置是沒有作用的颤霎,你不能指望它會直接為編譯器命令添加參數(shù)-I<CMAKE_INCLUDE_PATH>媳谁。
以此為例,CMAKE_LIBRARY_PATH 可以用在 FIND_LIBRARY 中友酱。
同樣晴音,因為這些變量直接為 FIND_ 指令所使用,所以所有使用 FIND_ 指令的 cmake 模塊都會受益缔杉。

FIND 系列指令锤躁,通過FIND尋找路徑并進行添加

FIND_系列指令主要包含一下指令:

FIND_FILE(<VAR> name1 path1 path2 ...)

VAR 變量代表找到的文件全路徑,包含文件名

FIND_LIBRARY(<VAR> name1 path1 path2 ...)

VAR 變量表示找到的庫全路徑或详,包含庫文件名
FIND_LIBRARY 示例:

FIND_LIBRARY(libX X11 /usr/lib) 
IF(NOT libX)
MESSAGE(FATAL_ERROR “l(fā)ibX not found”) 
ENDIF(NOT libX)
FIND_PATH(<VAR> name1 path1 path2 ...)

VAR 變量代表包含這個文件的路徑系羞。

FIND_PROGRAM(<VAR> name1 path1 path2 ...)

VAR 變量代表包含這個程序的全路徑。

FIND_PACKAGE
FIND_PACKAGE(<name> [major.minor]
        [QUIET] [NO_MODULE] 
        [[REQUIRED|COMPONENTS] [componets...]] )

FIND_PACKAGE 其實是系統(tǒng)與定義的cmake模塊霸琴。對于系統(tǒng)預(yù)定義的 Find<name>.cmake 模塊椒振,使用方法一般如上例所示: 每一個模塊都會定義以下幾個變量

  • <name>_FOUND
  • <name>_INCLUDE_DIR or <name>_INCLUDES
  • <name>_LIBRARY or <name>_LIBRARIES

你可以通過<name>_FOUND 來判斷模塊是否被找到,如果沒有找到梧乘,按照工程的需要關(guān)閉 某些特性澎迎、給出提醒或者中止編譯,上面的例子就是報出致命錯誤并終止構(gòu)建宋下。
如果<name>_FOUND 為真嗡善,則將<name>_INCLUDE_DIR 加入 INCLUDE_DIRECTORIES, 將<name>_LIBRARY 加入 TARGET_LINK_LIBRARIES 中学歧。
舉個例子:

FIND_PACKAGE(CURL)
IF(CURL_FOUND)
   INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})
   TARGET_LINK_LIBRARIES(curltest ${CURL_LIBRARY})
ELSE(CURL_FOUND)
     MESSAGE(FATAL_ERROR ”CURL library not found”)
ENDIF(CURL_FOUND)

FIND_PACKAGE 其實內(nèi)部主要還是通過FIND_PATH罩引,F(xiàn)IND_LIBRARY等基礎(chǔ)命令實現(xiàn)的。

大型開源庫路徑添加方式

如果是簡單的引入枝笨,可以直接通過指令I(lǐng)NCLUDE_DIRECTORIES袁铐,LINK_DIRECTORIES或者CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH進行設(shè)置。但是該方式存在缺點

  • 需要把路徑固定横浑,不宜遷移剔桨,修改麻煩
  • 如果存在大量的路徑的話,需要一次添加所有的路徑比較復(fù)雜

因此可以通過FIND 進行查找路徑徙融,通過FIND_PACKAGE 獲得所有的頭文件和庫文件路徑洒缀。
比如對于OpenCV,這樣的方式將會十分方便。這里介紹幾種常用的方式:

  1. 方式一:FIND_PACKAGE
    通過FIND_PACKAGE的方式树绩。
#添加OPENCV庫
#指定OpenCV版本萨脑,代碼如下
#find_package(OpenCV 3.3 REQUIRED)
#如果不需要指定OpenCV版本,代碼如下
find_package(OpenCV REQUIRED)

#添加OpenCV頭文件
include_directories(${OpenCV_INCLUDE_DIRS})

# 添加一個可執(zhí)行程序
# 語法:add_executable( 程序名 源代碼文件 )
add_executable( main main.cpp )

# 將庫文件鏈接到可執(zhí)行程序上
target_link_libraries( main ${OpenCV_LIBS})

要求opencv安裝在系統(tǒng)默認目錄下饺饭。

  1. 方式二:cmake 關(guān)PKG-CONFIG的指令方式
    其實和方式二一樣渤早,但是實現(xiàn)的方式上有出入。通過opencv自帶的pkg-config 提供的opencv.pc文件瘫俊。
# 編譯該工程CMAKE最低版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.2 FATAL_ERROR)
# 工程名字
PROJECT(MAIN)

#通過pkg-config管理的三方庫
# 非root下需要自己加入PKG_CONFIG_PATH鹊杖,不然報錯!!!
SET(ENV{PKG_CONFIG_PATH} /home/topeet/programfile/opencv2/lib/pkgconfig)
#PkgConfig名字是固定的蒋困,代表準備加入pkg-config模塊提茁,即查找/usr/bin/pkg-config
FIND_PACKAGE(PkgConfig REQUIRED) 
#通過執(zhí)行pkg-config程序,并指定我需要的模塊是opencv,注意opencv名字固定叉弦,是源于安裝OpenCV生成的opencv.pc胸哥,PKG_OPENCV是前綴(觀察下面)涯竟,
PKG_SEARCH_MODULE(PKG_OPENCV REQUIRED opencv)   

# 添加三方opencv的頭文件路徑-- -I/home/topeet/programfile/opencv2/include/opencv -I/home/topeet/programfile/opencv2/include
INCLUDE_DIRECTORIES(${PKG_OPENCV_INCLUDE_DIRS})

# 指定生成目標
ADD_EXECUTABLE(main main.cpp)
# 為指定的bin文件添加三方鏈接庫
TARGET_LINK_LIBRARIES(main detect ${PKG_OPENCV_LDFLAGS})

find_package采用兩種模式搜索庫

Module模式:搜索CMAKE_MODULE_PATH指定路徑下的FindXXX.cmake文件,執(zhí)行該文件從而找到XXX庫空厌。其中,具體查找?guī)觳⒔oXXX_INCLUDE_DIRS和XXX_LIBRARIES兩個變量賦值的操作由FindXXX.cmake模塊完成银酬。

Module 搜素路徑:

  • CMAKE_MODULE_PATH指定的路徑
  • <CMAKE_ROOT>/share/cmake-x.y/Mdodules (注意:x.y表示版本號嘲更。我的是3.10)。其中CMAKE_ROOT是你在安裝Cmake的時候的系統(tǒng)路徑揩瞪,因為我并沒有指定安裝路徑赋朦,所以是系統(tǒng)默認的路徑,在我的系統(tǒng)中(ubuntu16.04)系統(tǒng)的默認路徑是/usr/loacl李破,如果你在安裝的過程中使用了
    cmake -DCMAKE_INSTALL_PREFIX=自己dir路徑 宠哄,那么此時CMAKE_ROOT就代表那個你寫入的路徑 。($CMAKE_ROOT的具體值可以通過CMake中message命令輸出)嗤攻。這稱為模塊模式毛嫉。

Config模式:搜索XXX_DIR指定路徑下的XXXConfig.cmake文件,執(zhí)行該文件從而找到XXX庫妇菱。其中具體查找?guī)觳⒔oXXX_INCLUDE_DIRS和XXX_LIBRARIES兩個變量賦值的操作由XXXConfig.cmake模塊完成承粤。

Config 搜索路徑:

  • 搜索xxx_DIR 指定的路徑。如果在CMakeLists.txt中沒有設(shè)置這個cmake變量闯团。也就是說沒有下面的指令: set(xxx_DIR "xxxConfig.cmkae文件所在的路徑")那么Cmake就不會搜索xxx_DIR指定的路徑
  • Cmake 會在/usr/local/lib/cmake/xxx/ /usr/local/share/xxx 中的xxxConfig.cmake文件辛臊。這個路徑不同的操作系統(tǒng)存在差異。

兩種模式看起來似乎差不多房交,不過cmake默認采取Module模式彻舰,如果Module模式未找到庫,才會采取Config模式。若果在Module的搜索路徑中沒有找到對應(yīng)的cmake file刃唤,則使用config模式隔心。總之透揣,Config模式是一個備選策略济炎。通常,庫安裝時會拷貝一份XXXConfig.cmake到系統(tǒng)目錄中辐真,因此在沒有顯式指定搜索路徑時也可以順利找到须尚。

在我遇到的問題中,由于Caffe安裝時沒有安裝到系統(tǒng)目錄侍咱,因此無法自動找到CaffeConfig.cmake耐床,我在CMakeLists.txt最前面添加了一句話之后就可以了。

set(Caffe_DIR /home/wjg/projects/caffe/build)#添加CaffeConfig.cmake的搜索路徑find_package(Caffe REQUIRED)
if(NOT Caffe_FOUND)
  message(FATAL_ERROR"Caffe Not Found!")
endif(NOT Caffe_FOUND)
include_directories(${Caffe_INCLUDE_DIRS})
add_executable(useSSD ssd_detect.cpp)
target_link_libraries(useSSD${Caffe_LIBRARIES})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末楔脯,一起剝皮案震驚了整個濱河市撩轰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昧廷,老刑警劉巖堪嫂,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異木柬,居然都是意外死亡皆串,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門眉枕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恶复,“玉大人,你說我怎么就攤上這事速挑“担” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵姥宝,是天一觀的道長翅萤。 經(jīng)常有香客問我,道長伶授,這世上最難降的妖魔是什么断序? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮糜烹,結(jié)果婚禮上违诗,老公的妹妹穿的比我還像新娘。我一直安慰自己疮蹦,他們只是感情好诸迟,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般阵苇。 火紅的嫁衣襯著肌膚如雪壁公。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天绅项,我揣著相機與錄音紊册,去河邊找鬼。 笑死快耿,一個胖子當著我的面吹牛囊陡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掀亥,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼撞反,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搪花?” 一聲冷哼從身側(cè)響起遏片,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撮竿,沒想到半個月后吮便,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡幢踏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年线衫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惑折。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖枯跑,靈堂內(nèi)的尸體忽然破棺而出惨驶,到底是詐尸還是另有隱情,我是刑警寧澤敛助,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布粗卜,位于F島的核電站,受9級特大地震影響纳击,放射性物質(zhì)發(fā)生泄漏续扔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一焕数、第九天 我趴在偏房一處隱蔽的房頂上張望纱昧。 院中可真熱鬧,春花似錦堡赔、人聲如沸识脆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灼捂。三九已至离例,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悉稠,已是汗流浹背宫蛆。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留的猛,地道東北人耀盗。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像衰絮,于是被迫代替她去往敵國和親袍冷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 向您的項目添加 C 和 C++ 代碼 本文內(nèi)容 下載 NDK 和構(gòu)建工具 創(chuàng)建支持 C/C++ 的新項目 構(gòu)建和運...
    會飛的大象_閱讀 3,797評論 0 3
  • 注:首發(fā)地址 1. 前言 當在做 Android NDK 開發(fā)時猫牡,如果不熟悉用 CMake 來構(gòu)建胡诗,讀不懂 CMa...
    cfanr閱讀 24,430評論 1 53
  • 最近在負責一個大型工程的CMake編譯系統(tǒng)管理,整理一些工作過程中積累下來的知識片段和技巧淌友。CMake是一個跨平臺...
    啊呀喲嘿閱讀 8,855評論 0 2
  • 為了將C/C++代碼轉(zhuǎn)換為可以在硬件上運行的程序煌恢,需要經(jīng)過編譯和鏈接。編譯是將高級語言所寫的源程序翻譯成等價的機器...
    WalkeR_ZG閱讀 9,724評論 0 15
  • CMake學習 本篇分享一下有關(guān)CMake的一些學習心得以及相關(guān)使用震庭。 本文目錄如下: [1瑰抵、CMake介紹] [...
    AlphaGL閱讀 12,252評論 11 79