CMake手冊詳解 (十三)


CMD#31:find_package 為外部工程加載設置。

  find_package(<package> [version] [EXACT] [QUIET]
[[REQUIRED|COMPONENTS] [components...]]
[NO_POLICY_SCOPE])

  查找並加載外來工程的設置。該命令會設置<package>_FOUND變量,用來指示要找的包是否被找到了。如果這個包被找到了,與它相關的信息可以通過包自身記載的變量中得到。QUIET選項將會禁掉包沒有被發現時的警告信息。REQUIRED選項表示如果報沒有找到的話,cmake的過程會終止,並輸出警告信息。在REQUIRED選項之后,或者如果沒有指定REQUIRED選項但是指定了COMPONENTS選項,在它們的后面可以列出一些與包相關的部件清單(components list)。[version]參數需要一個版本號,它是正在查找的包應該兼容的版本號(格式是major[.minor[.patch[.tweak]]])。EXACT選項要求該版本號必須精確匹配。如果在find-module內部對該命令的遞歸調用沒有給定[version]參數,那么[version]和EXACT選項會自動地從外部調用前向繼承。對版本的支持目前只存在於包和包之間(詳見下文)。

  用戶代碼總體上應該使用上述的簡單調用格式查詢需要的包。本命令文檔的剩余部分則詳述了find_package的完整命令格式以及具體的查詢過程。期望通過該命令查找並提供包的項目維護人員,我們鼓勵你能繼續讀下去。

  該命令在搜索包時有兩種模式:“模塊”模式和“配置”模式。當該命令是通過上述的精簡格式調用的時候,合用的就是模塊模式。在該模式下,CMake搜索所有名為Find<package>.cmake的文件,這些文件的路徑由變量由安裝CMake時指定的CMAKE_MODULE_PATH變量指定。如果查找到了該文件,它會被CMake讀取並被處理。該模式對查找包,檢查版本以及生成任何別的必須信息負責。許多查找模塊(find-module)僅僅提供了有限的,甚至根本就沒有對版本化的支持;具體信息查看該模塊的文檔。如果沒有找到任何模塊,該命令會進入配置模式繼續執行。

   完整的配置模式下的命令格式是:

  find_package(<package> [version] [EXACT] [QUIET]
[[REQUIRED|COMPONENTS] [components...]] [NO_MODULE]
[NO_POLICY_SCOPE]
[NAMES name1 [name2 ...]]
[CONFIGS config1 [config2 ...]]
[HINTS path1 [path2 ... ]]
[PATHS path1 [path2 ... ]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_PACKAGE_REGISTRY]
[NO_CMAKE_BUILDS_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH])

  NO_MODULE可以用來明確地跳過模塊模式。它也隱含指定了不使用在精簡格式中使用的那些選項。

  配置模式試圖查找一個由待查找的包提供的配置文件的位置。包含該文件的路徑會被存儲在一個名為<package>_DIR的cache條目里。默認情況下,該命令搜索名為<package>的包。如果指定了NAMES選項,那么其后的names參數會取代<package>的角色。該命令會為每個在names中的name搜索名為<name>Config.cmake或者<name全小寫>-config.cmake的文件。通過使用CONFIGS選項可以改變可能的配置文件的名字。以下描述搜索的過程。如果找到了配置文件,它將會被CMake讀取並處理。由於該文件是由包自身提供的,它已經知道包中內容的位置。配置文件的完整地址存儲在cmake的變量<package>_CONFIG中。

  所有CMake要處理的配置文件將會搜索該包的安裝信息,並且將該安裝匹配的適當版本號(appropriate version)存儲在cmake變量<package>_CONSIDERED_CONFIGS中,與之相關的版本號(associated version)將被存儲在<package>_CONSIDERED_VERSIONS中。

  如果沒有找到包配置文件,CMake將會生成一個錯誤描述文件,用來描述該問題——除非指定了QUIET選項。如果指定了REQUIRED選項,並且沒有找到該包,將會報致命錯誤,然后配置步驟終止執行。如果設置了<package>_DIR變量被設置了,但是它沒有包含配置文件信息,那么CMake將會直接無視它,然后重新開始查找。

  如果給定了[version]參數,那么配置模式僅僅會查找那些在命令中請求的版本(格式是major[.minor[.patch[.tweak]]])與包請求的版本互相兼容的那些版本的包。如果指定了EXACT選項,一個包只有在它請求的版本與[version]提供的版本精確匹配時才能被找到。CMake不會對版本數的含義做任何的轉換。包版本號由包自帶的版本文件來檢查。對於一個備選的包配置文件<config-file>.cmake,對應的版本文件的位置緊挨着它,並且名字或者是<config-file>-version.cmake或者是<config-file>Version.cmake。如果沒有這個版本文件,那么配置文件就會認為不兼容任何請求的版本。當找到一個版本文件之后,它會被加載然后用來檢查(find_package)請求的版本號。版本文件在一個下述變量被定義的嵌套域中被加載:

   PACKAGE_FIND_NAME          = <package>名字。
PACKAGE_FIND_VERSION = 請求的完整版本字符串
PACKAGE_FIND_VERSION_MAJOR = 如果被請求了,那么它是major版本號,否則是0。
PACKAGE_FIND_VERSION_MINOR = 如果被請求了,那么它是minor版本號,否則是0。 PACKAGE_FIND_VERSION_PATCH = 如果被請求了,那么它是patch版本號,否則是0。
PACKAGE_FIND_VERSION_TWEAK = 如果被請求了,那么它是tweak版本號,否則是0。
PACKAGE_FIND_VERSION_COUNT = 版本號包含幾部分,0到4。

  版本文件會檢查自身是否滿足請求的版本號,然后設置了下面這些變量:

  PACKAGE_VERSION            = 提供的完整的版本字符串。
PACKAGE_VERSION_EXACT = 如果版本號精確匹配,返回true。
PACKAGE_VERSION_COMPATIBLE = 如果版本號相兼容,返回true。
PACKAGE_VERSION_UNSUITABLE = 如果不適合任何版本,返回true。

  下面這些變量將會被find_package命令檢查,用以確定配置文件是否提供了可接受的版本。在find_package命令返回后,這些變量就不可用了。如果版本可接受,下述的變量會被設置:

  <package>_VERSION       = 提供的完整的版本字符串。
<package>_VERSION_MAJOR = 如果被請求了,那么它是major版本號,否則是0。
<package>_VERSION_MINOR = 如果被請求了,那么它是minor版本號,否則是0。
<package>_VERSION_PATCH = 如果被請求了,那么它是patch版本號,否則是0。
<package>_VERSION_TWEAK = 如果被請求了,那么它是tweak版本號,否則是0。
<package>_VERSION_COUNT = 版本號包含幾部分,0到4。

然后,對應的包配置文件才會被加載。當多個包配置文件都可用時,並且這些包的版本文件都與請求的版本兼容,選擇哪個包將會是不確定的。不應該假設cmake會選擇最高版本或者是最低版本。(以上的若干段是對find_package中版本匹配步驟的描述,並不需要用戶干預——譯注。)

  配置模式提供了一種高級接口和搜索步驟的接口。這些被提供的接口的大部分是為了完整性的要求,以及在模塊模式下,包被find-module加載時供內部使用。大多數用戶僅僅應該調用:

  find_package(<package> [major[.minor]] [EXACT] [REQUIRED|QUIET])

來查找包。鼓勵那些需要提供CMake包配置文件的包維護人員應該命名這些文件並安裝它們,這樣下述的整個過程將會找到它們而不需要使用附加的選項。

  CMake為包構造了一組可能的安裝前綴。在每個前綴下,若干個目錄會被搜索,用來查找配置文件。下述的表格展示了待搜索的路徑。每個條目都是專門為Windows(W),UNIX(U)或者Apple(A)約定的安裝樹指定的。

    <prefix>/                                               (W)
<prefix>/(cmake|CMake)/ (W)
<prefix>/<name>*/ (W)
<prefix>/<name>*/(cmake|CMake)/ (W)
<prefix>/(share|lib)/cmake/<name>*/ (U)
<prefix>/(share|lib)/<name>*/ (U)
<prefix>/(share|lib)/<name>*/(cmake|CMake)/ (U)

  在支持OS X平台和Application Bundles的系統上,包含配置文件的框架或者bundles會在下述的路徑中被搜索:

    <prefix>/<name>.framework/Resources/                    (A)
<prefix>/<name>.framework/Resources/CMake/ (A)
<prefix>/<name>.framework/Versions/*/Resources/ (A)
<prefix>/<name>.framework/Versions/*/Resources/CMake/ (A)
<prefix>/<name>.app/Contents/Resources/ (A)
<prefix>/<name>.app/Contents/Resources/CMake/ (A)

  在所有上述情況下,<name>是區分大小寫的,並且對應於在<package>或者由NAMES給定的任何一個名字。

  這些路徑集用來與那些在各自的安裝樹上提供了配置文件的工程協作。上述路徑中被標記為(W)的是專門為Windows上的安裝設置的,其中的<prefix>部分可能是一個應用程序的頂層安裝路徑。那些被標記為(U)的是專門為UNIX平台上的安裝設置的,其中的<prefix>被多個包共用。這僅僅是個約定,因此,所有(W)和(U)路徑在所有平台上都仍然會被搜索。那些被標記為(A)的路徑是專門為Apple平台上的安裝設置的。CMake變量CMAKE_FIND_FRAMEWORK和CMAKE_FIND_APPBUNDLE確定了偏好的順序,如下所示:

  安裝前綴是通過以下步驟被構建出來的。如果指定了NO_DEFAULT_PATH選項,所有NO_*選項都會被激活。

  1、搜索在cmake特有的cache變量中指定的搜索路徑。這些變量是為了在命令行中用-DVAR=value選項指定而設計的。通過指定NO_CMAKE_PATH選項可以跳過該搜索路徑。搜索路徑還包括:

    CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH

  2、搜索cmake特有的環境變量。這些變量是為了在用戶的shell配置中進行配置而設計的。通過指定NO_CMAKE_ENVIRONMENT_PATH選項可以跳過該路徑。搜索的路徑包括:

   <package>_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH

  3、搜索HINTS選項指定的路徑。這些路徑應該是由操作系統內省時計算產生的,比如由其它已經找到的項的位置而提供的線索。硬編碼的參考路徑應該在PATHS選項中指定。

  4、搜索標准的系統環境變量。如果指定了NO_SYSTEM_ENVIRONMENT_PATH選項,這些路徑會被跳過。以"/bin"或"/sbin"結尾的路徑條目會被自動轉換為它們的父路徑。搜索的路徑包括:

   PATH

  5、搜索在CMake GUI中最新配置過的工程的構建樹。可以通過設置NO_CMAKE_BUILDS_PATH選項來跳過這些路徑。這是為了在用戶正在依次構建多個相互依賴的工程時而准備的。

  6、搜索存儲在CMake用戶包注冊表中的路徑。通過設置NO_CMAKE_PACKAGE_REGISTRY選項可以跳過這些路徑。當CMake嗲用export(PACKAGE<name>)配置一個工程時,這些路徑會被存儲在注冊表中。參見export(PACKAGE)命令的文檔閱讀更多細節。

  7、搜索在當前系統的平台文件中定義的cmake變量。可以用NO_CMAKE_SYSTEM_PATH選項跳過這些路徑。

   CMAKE_SYSTEM_PREFIX_PATH

CMAKE_SYSTEM_FRAMEWORK_PATH
CMAKE_SYSTEM_APPBUNDLE_PATH

  8、搜索由PATHS選項指定的路徑。這些路徑一般是硬編碼的參考路徑。

  在Darwin或者支持OS X 框架的系統上,cmake變量CMAKE_FIND_FRAMEWORK可以用來設置為空,或者下述值之一:
     "FIRST"  - 在標准庫或頭文件之前查找框架。在Darwin系統上這是默認選項。
  "LAST" - 在標准庫或頭文件之后查找框架。
  
"ONLY" - 僅僅查找框架。
  "NEVER" - 從不查找框架。

  在Darwin或者支持OS X Application Bundles的系統,cmake變量CMAKE_FIND_APPBUNDLE可以被設置為空或者下面這些值中的一個:

      "FIRST"  - 在標准庫或頭文件之前查找application bundles。在Darwin系統上這是默認選項。
  "LAST" - 在標准庫或頭文件之后查找application bundles。
  "ONLY" - 僅僅查找application bundles。
  "NEVER" - 從不查找application bundles。

  CMake變量CMAKE_FIND_ROOT_PATH指定了一個或者多個優先於其他搜索路徑的搜索路徑。該變量能夠有效地重新定位在給定位置下進行搜索的根路徑。該變量默認為空。當使用交叉編譯時,該變量十分有用:用該變量指向目標環境的根目錄,然后CMake將會在那里查找。默認情況下,在CMAKE_FIND_ROOT_PATH中列出的路徑會首先被搜索,然后是“非根”路徑。該默認規則可以通過設置CMAKE_FIND_ROOT_PATH_MODE_LIBRARY做出調整。在每次調用該命令之前,都可以通過設置這個變量來手動覆蓋默認行為。如果使用了NO_CMAKE_FIND_ROOT_PATH變量,那么只有重定位的路徑會被搜索。

  默認的搜索順序的設計邏輯是按照使用時從最具體到最不具體。通過多次調用find_library命令以及NO_*選項,可以覆蓋工程的這個默認順序:

     find_library(<VAR> NAMES name PATHS paths... NO_DEFAULT_PATH)
find_library(<VAR> NAMES name)

  只要這些調用中的一個成功返回,結果變量就會被設置並且被存儲到cache中;這樣隨后的調用都不會再行搜索。如果那找到的庫是一個框架,VAR將會被設置為指向框架“<完整路徑>/A.framework” 的完整路徑。當一個指向框架的完整路徑被用作一個庫文件,CMake將使用-framework A,以及-F<完整路徑>這兩個選項將框架連接到目標上。

  參見cmake_policy()命令的文檔中關於NO_POLICY_SCOPE選項討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM