經(jīng)常在Linux下面寫C++程序钓丰,尤其是需要集成各種第三方庫的工程躯砰,肯定對find_package指令不陌生。
這是條很強大的指令携丁∽列可以直接幫我們解決整個工程的依賴問題,自動把頭文件和動態(tài)鏈接文件配置好梦鉴。比如說李茫,在Linux下面工程依賴了OpenCV,只需要下面幾行就可以完全配置好:
add_executable(my_bin src/my_bin.cpp)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(my_bin, ${OpenCV_LIBS})
工作流程如下:
find_package
在一些目錄中查找OpenCV的配置文件肥橙。
找到后魄宏,find_package會將頭文件目錄設(shè)置到${OpenCV_INCLUDE_DIRS}
中,將鏈接庫設(shè)置到${OpenCV_LIBS}
中存筏。
設(shè)置可執(zhí)行文件的鏈接庫和頭文件目錄宠互,編譯文件味榛。
到現(xiàn)在為止出現(xiàn)了第一個問題。那就是:
find_package會在哪些目錄下面尋找OpenCV的配置文件予跌?
find_package目錄
為什么我們要知道這個問題呢搏色?因為很多庫,我們都是自己編譯安裝的匕得。比如說继榆,電腦中同時編譯了OpenCV2和OpenCV3,我該如何讓cmake知道到底找哪個呢汁掠?
其實這個問題在CMake官方文檔中有非常詳細的解答略吨。
首先是查找路徑的根目錄。我把幾個重要的默認查找目錄總結(jié)如下:
<package>_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
PATH
其中考阱,PATH中的路徑如果以bin或sbin結(jié)尾翠忠,則自動回退到上一級目錄。
找到根目錄后乞榨,cmake會檢查這些目錄下的
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/
<prefix>/(lib/<arch>|lib|share)/<name>*/
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/
cmake找到這些目錄后秽之,會開始依次找<package>Config.cmake或Find<package>.cmake文件。找到后即可執(zhí)行該文件并生成相關(guān)鏈接信息吃既。
現(xiàn)在回過頭來看查找路徑的根目錄考榨。我認為最重要的一個是PATH。由于/usr/bin/在PATH中鹦倚,cmake會自動去/usr/(lib/<arch>|lib|share)/cmake/<name>*/尋找模塊河质,這使得絕大部分我們直接通過apt-get安裝的庫可以被找到。
另外一個比較重要的是<package>_DIR震叙。我們可以在調(diào)用cmake時將這個目錄傳給cmake掀鹅。由于其優(yōu)先級最高,因此cmake會優(yōu)先從該目錄中尋找媒楼,這樣我們就可以隨心所欲的配置cmake使其找到我們希望它要找到的包乐尊。而且除上述指定路徑外,cmake還會直接進入<package>_DIR下尋找划址。如我在3rd_parties目錄下編譯了一個OpenCV扔嵌,那么執(zhí)行cmake時可以使用
OpenCV_DIR=../../3rd-party/opencv-3.3.4/build/ cmake ..
這樣做以后,cmake會優(yōu)先從該目錄尋找OpenCV夺颤。