GNU開發(fā)工具——CMake模塊-創(chuàng)新互聯(lián)

GNU開發(fā)工具——CMake模塊

一、find_packge高級功能

1、find_package的模式

find_package()有Module模式(基本用法)和Config模式(完全用法),其中Module模式是基礎(chǔ),Config模式則提供復(fù)雜高級功能。
find_package是否使用Config模式可以通過下列條件判斷:
(1)find_package()中指定CONFIG關(guān)鍵字
(2)find_package()中指定NO_MODULE關(guān)鍵字
(3)find_package()中使用了不再Module模式下所有支持配置的關(guān)鍵字

成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計、成都網(wǎng)站建設(shè)公司、微信開發(fā)、微信小程序開發(fā)、集團成都定制網(wǎng)站等服務(wù)項目。核心團隊均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗,服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:成都混凝土攪拌站等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗,同時也獲得了客戶的一致稱譽!

2、find_package工作流程

GNU開發(fā)工具——CMake模塊

3、find_package的Module模式

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])

version和EXACT,可選,version指定版本,如果指定就必須檢查找到的包的版本是否和version兼容。如果指定EXACT則表示必須完全匹配的版本而不是兼容版本就可以。
QUIET,可選字段,表示如果查找失敗,不會在屏幕進行輸出(但如果指定了REQUIRED字段,則QUIET無效,仍然會輸出查找失敗提示語)。
MODULE,可選字段。前面提到說“如果Module模式查找失敗則回退到Config模式進行查找”,但是假如設(shè)定了MODULE選項,那么就只在Module模式查找,如果Module模式下查找失敗并不回落到Config模式查找。
REQUIRED可選字段。表示一定要找到包,找不到的話就立即停掉整個cmake。而如果不指定REQUIRED則cmake會繼續(xù)執(zhí)行。
COMPONENTS,components:可選字段,表示查找的包中必須要找到的組件(components),如果有任何一個找不到就算失敗,類似于REQUIRED,導(dǎo)致cmake停止執(zhí)行。
Module模式下需要查找到名為FindPackageName.cmake的文件。
先在CMAKE_MODULE_PATH變量對應(yīng)的路徑中查找。如果路徑為空,或者路徑中查找失敗,則在cmake module directory(cmake安裝時的Modules目錄,比如/usr/local/share/cmake/Modules)查找。

4、find_package的Config模式

find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED] [[COMPONENTS] [components...]]
[CONFIG|NO_MODULE]
[NO_POLICY_SCOPE]
[NAMES name1 [name2 ...]]
[CONFIGS config1 [config2 ...]]
[HINTS path2 [path3 ... ]]
[PATHS path2 [path3 ... ]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_PACKAGE_REGISTRY]
[NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
[NO_CMAKE_SYSTEM_PATH]
[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH])

Config模式下的查找順序,比Module模式下要多得多,新版本的CMake比老版本的有更多的查找順序(新增的在最優(yōu)先的查找順序)。Config模式下需要查找到名為lower-case-package-name-config.cmake或PackageNameConfig.cmake文件。查找順序如下:
(1)名為PackageName_ROOT的cmake變量或環(huán)境變量。CMake3.12新增。設(shè)定CMP0074 Policy來關(guān)閉。如果定義了PackageName_DIR?cmake變量,那么PackageName_ROOT?不起作用。

cmake_minimum_required(VERSION 3.13)
project(OpenCVDemo)
set(OpenCV_ROOT "/usr/local/lib/opencv_249/build")
set(OpenCV_DIR "/usr/local/lib/opencv_300/build")

find_package(OpenCV QUIET
    NO_MODULE
    NO_DEFAULT_PATH
    NO_CMAKE_PATH
    NO_CMAKE_ENVIRONMENT_PATH
    NO_SYSTEM_ENVIRONMENT_PATH
    NO_CMAKE_PACKAGE_REGISTRY
    NO_CMAKE_BUILDS_PATH
    NO_CMAKE_SYSTEM_PATH
    NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
)
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

上述代碼會找到opencv300,OpenCV_DIR變量的值有效OpenCV_ROOT變量無效。
(2)cmake特定的緩存變量

CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH

可以通過設(shè)定NO_CMAKE_PATH來關(guān)閉特定緩存變量的查找順序
(3)CMake特定的環(huán)境變量

PackageName_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH

可以通過NO_CMAKE_ENVIRONMENT_PATH來跳過。
(4)HINT字段指定的路徑
(5)搜索標(biāo)準(zhǔn)的系統(tǒng)環(huán)境變量PATH。
其中如果是以/bin或者/sbin結(jié)尾的,會自動轉(zhuǎn)化為其父目錄。
通過指定NO_SYSTEM_ENVIRONMENT_PATH來跳過。
(6)存儲在CMake的"User Package Registry"(用戶包注冊表)中的路徑。
通過設(shè)定NO_CMAKE_PACKAGE_REGISTRY,或設(shè)定CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY為true,來避開。
(7)設(shè)定為當(dāng)前系統(tǒng)定義的cmake變量:
CMAKE_SYSTEM_PREFIX_PATH
CMAKE_SYSTEM_FRAMEWORK_PATH
CMAKE_SYSTEM_APPBUNDLE_PATH
通過設(shè)定NO_CMAKE_SYSTEM_PATH來跳過。
(8)在cmake的"System Package Registry"(系統(tǒng)包注冊表)中查找。
通過設(shè)定NO_CMAKE_SYSTEM_PACKAGE_REGISTRY跳過,或者通過設(shè)定CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY為true避開。
(9)從PATHS字段指定的路徑中查找。

二、CMake自定義模塊

1、find_xxx指令

FIND_FILE(VAR name path2 path3 …)
VAR變量代表找到的文件全路徑,包含文件名。
FIND_LIBRARY(VAR name path2 path3 …)
VAR變量代表找到的庫全路徑,包含庫文件名。
FIND_PATH(VAR name path2 path3 …)
VAR變量代表包含文件的路徑
FIND_PROGRAM(VAR name path2 path3 …)
VAR變量代表包含程序的全路徑
FIND_PACKAGE(&lt;name&gt; [major.minor] [QUIET] [NO_MODULE] [[REQUIRED | COMPONENTS] [componets …]])
用來調(diào)用預(yù)定義在CMAKE_MODULE_PATH下的Findname.cmake模塊,可以自己定義Findname模塊,通過SET(CMAKE_MODULE_PATH dir)將其放入工程的某個目錄供工程使用。

FIND_LIBRARY(libX X11 /usr/lib)
IF (NOT libx)
    MESSAGE(FATAL_ERROR "libX not found")
ENDIF(NOT libX)

2、系統(tǒng)預(yù)定義模塊使用

系統(tǒng)預(yù)定義了各種模塊,通常需要使用INCLUDE指令顯式的調(diào)用, 但FIND_PACKAGE指令是一個特例,可以直接調(diào)用預(yù)定義的模塊。
每一個模塊都會定義以下3個變量:

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

因此,可以通過name_FOUND來判斷模塊是否被找到,如果沒有找到,按照工程的需要關(guān)閉某些特性、給出提醒或者中止構(gòu)建。
對于系統(tǒng)預(yù)定義的Findname.cmake模塊,使用方法如下:

FIND_PACKAGE(NAME)
IF(NAME_FOUND)
    INCLUDE_DIRECTORIES(${NAME_INCLUDE_DIR})
    TARGET_LINK_LIBRARIES(targetname ${NAME_LIBRARY})
ELSE(NAME_FOUND)
    MESSAGE(FATAL_ERROR ”NAME library not found”)
ENDIF(NAME_FOUND)

工程實踐中使用示例如下:

#通過<name>_FOUND來控制工程特性:
SET(SOURCES Viewer.cpp)
SET(OptionalSources)
SET(OptionalLibs)
FIND_PACKAGE(JPEG)
IF(JPEG_FOUND)
    SET(OptionalSources ${OptionalSources} JPEGView.cpp)
    INCLUDE_DIRECTORIES( ${JPEG_INCLUDE_DIR} )
    SET(optionalLibs ${OptionalLibs} ${JPEG_LIBRARIES} )
    ADD_DEFINITIONS(-DENABLE_JPEG_SUPPORT)
ENDIF(JPEG_FOUND)

IF(PNG_FOUND)
    SET(OptionalSources ${OptionalSources} PNGView.cpp)
    INCLUDE_DIRECTORIES( ${PNG_INCLUDE_DIR} )
    SET(OptionalLibs ${OptionalLibs} ${PNG_LIBRARIES} )
    ADD_DEFINITIONS(-DENABLE_PNG_SUPPORT)
ENDIF(PNG_FOUND)

ADD_EXECUTABLE(viewer ${SOURCES} ${OptionalSources} )
TARGET_LINK_LIBRARIES(Viewer ${OptionalLibs})
#通過判斷系統(tǒng)是否提供了JPEG、PNG模塊來決定程序是否支持JPEG、PNG功能。

3、自定義模塊實現(xiàn)

本文基于libHello動態(tài)庫,編寫一個FindHelo.cmake模塊。
創(chuàng)建一個FindHello項目目錄,進入FindHello。
創(chuàng)建一個Hello目錄,進入Hello目錄,創(chuàng)建FindHelo.cmake文件,F(xiàn)indHelo.cmake文件如下:

#查找hello庫頭文件的安裝路徑
FIND_PATH(HELLO_INCLUDE_DIR Hello.h /usr/local/include/hello)
#查找hello庫的安裝路徑
FIND_LIBRARY(HELLO_LIBRARY NAMES hello /usr/local/lib/libhello.so)

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)

返回FindHello目錄,創(chuàng)建main.cpp文件:

#include <Hello.h>

int main(int argc, char* argv[])
{
    Hello hello;
    hello.Print();
    return 0;
}

創(chuàng)建工程CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 2.8)
PROJECT(FindHello)
# 設(shè)置自定義模塊路徑
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/Hello/")
MESSAGE(STATUS "CMAKE_MODULE_PATH " ${PROJECT_SOURCE_DIR}/Hello)
#查找自定義Hello模塊
FIND_PACKAGE(Hello)
IF(HELLO_FOUND)
    ADD_EXECUTABLE(hello main.cpp)
    INCLUDE_DIRECTORIES(${HELLO_INCLUDE_DIR})
    MESSAGE(STATUS "LINK " ${HELLO_LIBRARY})
    TARGET_LINK_LIBRARIES(hello ${HELLO_LIBRARY})
ELSE(HELLO_FOUND)
    MESSAGE(STATUS "Could not find hello library")
ENDIF(HELLO_FOUND)

創(chuàng)建build目錄,進行build目錄進行構(gòu)建。
cmake ../
make
./hello
結(jié)果打印出Hello world.

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)頁題目:GNU開發(fā)工具——CMake模塊-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://muchs.cn/article2/eegoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、網(wǎng)站收錄網(wǎng)站改版、網(wǎng)頁設(shè)計公司定制開發(fā)、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)