<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 3.10 檢測外部庫:Ⅱ. 自定義find模塊 **NOTE**:*此示例代碼可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe-10 中找到,包含一個C的示例。該示例在CMake 3.5版(或更高版本)中是有效的,并且已經在GNU/Linux、macOS和Windows上進行過測試。* 此示例補充了上一節的示例,我們將展示如何編寫一個`find`模塊來定位系統上的ZeroMQ消息庫,以便能夠在非Unix操作系統上檢測該庫。我們重用服務器-客戶端示例代碼。 ## 如何實施 這是一個C項目,使用C99標準,并逐步構建CMakeLists.txt文件: 1. 聲明一個C項目,并要求符合C99標準: ```cmake cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(recipe-10 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_STANDARD_REQUIRED ON) ``` 2. 將當前源目錄`CMAKE_CURRENT_SOURCE_DIR`,添加到CMake將查找模塊的路徑列表`CMAKE_MODULE_PATH`中。這樣CMake就可以找到,我們自定義的`FindZeroMQ.cmake`模塊: ```cmake list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) ``` 3. 現在`FindZeroMQ.cmake`模塊是可用的,可以通過這個模塊來搜索項目所需的依賴項。由于我們沒有使用`QUIET`選項來查找`find_package`,所以當找到庫時,狀態消息將自動打印: ```cmake find_package(ZeroMQ REQUIRED) ``` 4. 我們繼續添加`hwserver`可執行目標。頭文件包含目錄和鏈接庫是使用`find_package`命令成功后,使用`ZeroMQ_INCLUDE_DIRS`和`ZeroMQ_LIBRARIES`變量進行指定的: ```cmake add_executable(hwserver hwserver.c) target_include_directories(hwserver PRIVATE ${ZeroMQ_INCLUDE_DIRS} ) target_link_libraries(hwserver PRIVATE ${ZeroMQ_LIBRARIES} ) ``` 5. 最后,我們對`hwclient`可執行目標執行相同的操作: ```cmake add_executable(hwclient hwclient.c) target_include_directories(hwclient PRIVATE ${ZeroMQ_INCLUDE_DIRS} ) target_link_libraries(hwclient PRIVATE ${ZeroMQ_LIBRARIES} ) ``` 此示例的主`CMakeLists.txt`在使用`FindZeroMQ.cmake`時,與前一個示例中使用的`CMakeLists.txt`不同。這個模塊使用`find_path`和`find_library` CMake內置命令,搜索ZeroMQ頭文件和庫,并使用`find_package_handle_standard_args`設置相關變量,就像我們在第3節中做的那樣。 1. `FindZeroMQ.cmake`中,檢查了`ZeroMQ_ROOT`變量是否設置。此變量可用于ZeroMQ庫的檢測,并引導到自定義安裝目錄。用戶可能設置了`ZeroMQ_ROOT`作為環境變量,我們也會進行檢查了: ```cmake if(NOT ZeroMQ_ROOT) set(ZeroMQ_ROOT "$ENV{ZeroMQ_ROOT}") endif() ``` 2. 然后,搜索系統上`zmq.h`頭文件的位置。這是基于`_ZeroMQ_ROOT`變量和`find_path`命令進行的: ```cmake if(NOT ZeroMQ_ROOT) find_path(_ZeroMQ_ROOT NAMES include/zmq.h) else() set(_ZeroMQ_ROOT "${ZeroMQ_ROOT}") endif() find_path(ZeroMQ_INCLUDE_DIRS NAMES zmq.h HINTS ${_ZeroMQ_ROOT}/include) ``` 3. 如果成功找到頭文件,則將`ZeroMQ_INCLUDE_DIRS`設置為其位置。我們繼續通過使用字符串操作和正則表達式,尋找相應版本的ZeroMQ庫: ```cmake set(_ZeroMQ_H ${ZeroMQ_INCLUDE_DIRS}/zmq.h) function(_zmqver_EXTRACT _ZeroMQ_VER_COMPONENT _ZeroMQ_VER_OUTPUT) set(CMAKE_MATCH_1 "0") set(_ZeroMQ_expr "^[ \\t]*#define[ \\t]+${_ZeroMQ_VER_COMPONENT}[ \\t]+([0-9]+)$") file(STRINGS "${_ZeroMQ_H}" _ZeroMQ_ver REGEX "${_ZeroMQ_expr}") string(REGEX MATCH "${_ZeroMQ_expr}" ZeroMQ_ver "${_ZeroMQ_ver}") set(${_ZeroMQ_VER_OUTPUT} "${CMAKE_MATCH_1}" PARENT_SCOPE) endfunction() _zmqver_EXTRACT("ZMQ_VERSION_MAJOR" ZeroMQ_VERSION_MAJOR) _zmqver_EXTRACT("ZMQ_VERSION_MINOR" ZeroMQ_VERSION_MINOR) _zmqver_EXTRACT("ZMQ_VERSION_PATCH" ZeroMQ_VERSION_PATCH) ``` 4. 然后,為`find_package_handle_standard_args`準備`ZeroMQ_VERSION`變量: ```cmake if(ZeroMQ_FIND_VERSION_COUNT GREATER 2) set(ZeroMQ_VERSION "${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}.${ZeroMQ_VERSION_PATCH}") else() set(ZeroMQ_VERSION "${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}") endif() ``` 5. 使用`find_library`命令搜索ZeroMQ庫。因為庫的命名有所不同,這里我們需要區分Unix的平臺和Windows平臺: ```cmake if(NOT ${CMAKE_C_PLATFORM_ID} STREQUAL "Windows") find_library(ZeroMQ_LIBRARIES NAMES zmq HINTS ${_ZeroMQ_ROOT}/lib ${_ZeroMQ_ROOT}/lib/x86_64-linux-gnu ) else() find_library(ZeroMQ_LIBRARIES NAMES libzmq "libzmq-mt-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}" "libzmq-${CMAKE_VS_PLATFORM_TOOLSET}-mt-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}" libzmq_d "libzmq-mt-gd-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}" "libzmq-${CMAKE_VS_PLATFORM_TOOLSET}-mt-gd-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}" HINTS ${_ZeroMQ_ROOT}/lib ) endif() ``` 6. 最后,包含了標準` FindPackageHandleStandardArgs.cmake`,并調用相應的CMake命令。如果找到所有需要的變量,并且版本匹配,則將`ZeroMQ_FOUND`變量設置為`TRUE`: ```cmake include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ZeroMQ FOUND_VAR ZeroMQ_FOUND REQUIRED_VARS ZeroMQ_INCLUDE_DIRS ZeroMQ_LIBRARIES VERSION_VAR ZeroMQ_VERSION ) ``` **NOTE**:*剛才描述的`FindZeroMQ.cmake`模塊已經在 https://github.com/zeromq/azmq/blob/master/config/FindZeroMQ.cmake 上進行了修改。* ## 工作原理 `find-module`通常遵循特定的模式: 1. 檢查用戶是否為所需的包提供了自定義位置。 2. 使用`find_`家族中的命令搜索所需包的必需組件,即頭文件、庫、可執行程序等等。我們使用`find_path`查找頭文件的完整路徑,并使用`find_library`查找庫。CMake還提供`find_file`、`find_program`和`find_package`。這些命令的簽名如下: ```cmake find_path(<VAR> NAMES name PATHS paths) ``` 3. 如果搜索成功,`<VAR>`將保存搜索結果;如果搜索失敗,則會設置為`<VAR>-NOTFOUND `。`NAMES`和`PATHS`分別是CMake應該查找的文件的名稱和搜索應該指向的路徑。 4. 初步搜索的結果中,可以提取版本號。示例中,ZeroMQ頭文件包含庫版本,可以使用字符串操作和正則表達式提取庫版本信息。 5. 最后,調用`find_package_handle_standard_args`命令。處理`find_package`命令的`REQUIRED`、`QUIET`和版本參數,并設置`ZeroMQ_FOUND`變量。 **NOTE**:*任何CMake命令的完整文檔都可以從命令行獲得。例如,`cmake --help-command find_file`將輸出`find_file`命令的手冊頁。對于CMake標準模塊的手冊,可以在CLI使用`--help-module`看到。例如,`cmake --help-module FindPackageHandleStandardArgs`將輸出`FindPackageHandleStandardArgs.cmake`的手冊頁面。* ## 更多信息 總而言之,有四種方式可用于找到依賴包: 1. 使用由包供應商提供CMake文件` <package>Config.cmake` ,`<package>ConfigVersion.cmake`和`<package>Targets.cmake`,通常會在包的標準安裝位置查找。 2. 無論是由CMake還是第三方提供的模塊,為所需包使用`find-module`。 3. 使用`pkg-config`,如本節的示例所示。 4. 如果這些都不可行,那么編寫自己的`find`模塊。 這四種可選方案按相關性進行了排序,每種方法也都有其挑戰。 目前,并不是所有的包供應商都提供CMake的Find文件,不過正變得越來越普遍。因為導出CMake目標,使得第三方代碼很容易使用它所依賴的庫和/或程序附加的依賴。 從一開始,`Find-module`就一直是CMake中定位依賴的主流手段。但是,它們中的大多數仍然依賴于設置依賴項使用的變量,比如`Boost_INCLUDE_DIRS`、`PYTHON_INTERPRETER`等等。這種方式很難在第三方發布自己的包時,確保依賴關系被滿足。 使用`pkg-config`的方法可以很好地進行適配,因為它已經成為Unix系統的標準。然而,也由于這個原因,它不是一個完全跨平臺的方法。此外,如CMake文檔所述,在某些情況下,用戶可能會意外地覆蓋檢測包,并導致`pkg-config`提供不正確的信息。 最后的方法是編寫自己的查找模塊腳本,就像本示例中那樣。這是可行的,并且依賴于`FindPackageHandleStandardArgs.cmake `。然而,編寫一個全面的查找模塊腳本絕非易事;有需要考慮很多可能性,我們在Unix和Windows平臺上,為查找ZeroMQ庫文件演示了一個例子。 所有軟件開發人員都非常清楚這些問題和困難,正如CMake郵件列表上討論所示: https://cmake.org/pipermail/cmake/2018-May/067556.html 。`pkg-config`在Unix包開發人員中是可以接受的,但是它不能很容易地移植到非Unix平臺。CMake配置文件功能強大,但并非所有軟件開發人員都熟悉CMake語法。公共包規范項目是統一用于包查找的`pkg-config`和CMake配置文件方法的最新嘗試。您可以在項目的網站上找到更多信息: https://mwoehlke.github.io/cps/ 在第10章中將討論,如何使用前面討論中概述的第一種方法,使第三方應用程序,找到自己的包:為項目提供自己的CMake查找文件。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看