CMake進階: CMake Modules---簡化CMake配置的利器

目錄

1.簡介

2.為什么需要 CMake Modules?

3.內置模塊:開箱即用的工具

3.1.依賴查找模塊(FindXXX.cmake)

3.2.功能檢測模塊(CheckXXX.cmake)

3.3.通用工具模塊(如?FetchContent.cmake、CTest.cmake)

4.自定義模塊:封裝項目特有邏輯

5.注意事項

6.總結

相關鏈接


1.簡介

????????CMake Modules(CMake 模塊)是一系列預定義或自定義的?.cmake?腳本文件,用于封裝可重用的 CMake 邏輯(如依賴查找、功能檢測、自定義命令等)。它們是簡化 CMake 配置、實現代碼復用和跨項目一致性的核心工具,尤其在大型項目或多項目管理中能顯著提升配置效率。

????????CMake 模塊是擴展名為?.cmake?的文本文件,包含 CMake 命令、函數、宏或變量定義,用于封裝特定功能(如 “查找 OpenSSL 庫”“設置通用編譯選項”“生成版本文件” 等)。

  • 內置模塊:CMake 自帶大量預定義模塊(如?FindZLIB.cmakeFetchContent.cmake),位于 CMake 安裝目錄的?Modules?文件夾下(可通過?cmake --help-module-list?查看所有內置模塊)。

文件夾如下面的目錄:

  • 自定義模塊:用戶可根據項目需求編寫自己的模塊,放在項目目錄中(如?cmake/Modules/),供多個子項目或目標復用。

2.為什么需要 CMake Modules?

1.代碼復用:將重復的配置邏輯(如依賴查找、編譯選項設置)封裝到模塊中,避免在多個?CMakeLists.txt?中重復編寫。

2.簡化主配置:主?CMakeLists.txt?只需通過?include(ModuleName)?調用模塊,聚焦項目核心邏輯,減少冗余代碼。

3.跨項目一致性:同一團隊或生態的多個項目可共享模塊,確保依賴管理、編譯標準等配置統一。

4.隱藏復雜性:將復雜邏輯(如跨平臺適配、條件檢測)封裝在模塊中,主配置文件更簡潔易懂。

3.內置模塊:開箱即用的工具

CMake 內置了數百個模塊,覆蓋常見依賴查找、功能檢測、平臺適配等場景,無需手動編寫復雜邏輯。

3.1.依賴查找模塊(FindXXX.cmake

最常用的一類模塊,用于查找系統中的第三方庫(如 ZLIB、OpenSSL、Python 等),內部通過?find_pathfind_library?等命令實現查找,并暴露統一的接口變量(如?XXX_INCLUDE_DIRSXXX_LIBRARIES)。

CMake指令:find_package_cmake find package-CSDN博客

示例:使用?FindZLIB.cmake?查找 zlib 庫

# 主 CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(MyProject)# 加載內置的 FindZLIB.cmake 模塊(無需手動 include,find_package 自動查找)
find_package(ZLIB REQUIRED)  # 內部調用 FindZLIB.cmake# 使用模塊提供的變量
add_executable(myapp main.cpp)
target_include_directories(myapp PRIVATE ${ZLIB_INCLUDE_DIRS})
target_link_libraries(myapp PRIVATE ${ZLIB_LIBRARIES})

FindZLIB.cmake?模塊已封裝了所有查找邏輯(如適配不同平臺的庫名、路徑),用戶無需關心底層細節,直接使用即可。

3.2.功能檢測模塊(CheckXXX.cmake

用于檢測編譯器特性、函數 / 頭文件是否存在等,輔助條件編譯。

CMake進階: 檢查函數/符號存在性、檢查類型/關鍵字/表達式有效性和檢查編譯器特性-CSDN博客

CMake進階:檢查頭文件存在性(check_include_file 和 check_include_fileCXX)_cmake編譯頭文件的查找-CSDN博客

示例:使用?CheckFunctionExists.cmake?檢測函數是否存在

include(CheckFunctionExists)  # 加載內置模塊# 檢測系統是否有 posix_memalign 函數
check_function_exists(posix_memalign HAVE_POSIX_MEMALIGN)# 根據檢測結果設置宏,供代碼中使用
if(HAVE_POSIX_MEMALIGN)add_definitions(-DHAVE_POSIX_MEMALIGN=1)
endif()

代碼中可通過宏判斷是否使用該函數:

#ifdef HAVE_POSIX_MEMALIGN// 使用 posix_memalign
#else// 備選實現
#endif

3.3.通用工具模塊(如?FetchContent.cmakeCTest.cmake

提供通用功能,如下載依賴、集成測試等。

CMake進階: 使用FetchContent方法基于gTest的C++單元測試_cmake fetchcontent-CSDN博客

示例:使用?FetchContent.cmake?下載外部依賴

include(FetchContent)  # 加載內置模塊# 下載并集成 googletest
FetchContent_Declare(googletestGIT_REPOSITORY https://github.com/google/googletest.gitGIT_TAG v1.15.0
)
FetchContent_MakeAvailable(googletest)  # 自動下載、配置、構建

4.自定義模塊:封裝項目特有邏輯

CMake基礎:宏(macro)和函數(function)_cmake macro-CSDN博客

當內置模塊無法滿足需求(如項目特有依賴、自定義工具鏈)時,可編寫自定義模塊,實現邏輯復用。

1.自定義模塊的創建步驟

步驟 1:創建模塊文件(.cmake

在項目中新建?cmake/Modules?目錄,創建模塊文件(如?AddMyTest.cmake),封裝自定義邏輯(如簡化測試用例添加):

# cmake/Modules/AddMyTest.cmake
# 自定義函數:簡化測試用例添加,自動鏈接 gtest 并設置屬性
function(add_my_test test_name test_src)add_executable(${test_name} ${test_src})target_link_libraries(${test_name} PRIVATE gtest_main)set_target_properties(${test_name} PROPERTIESCXX_STANDARD 17CXX_STANDARD_REQUIRED ON)add_test(NAME ${test_name} COMMAND ${test_name})
endfunction()

步驟 2:指定模塊路徑

在主?CMakeLists.txt?中通過?CMAKE_MODULE_PATH?告訴 CMake 去哪里查找自定義模塊:

# 主 CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(MyProject)# 添加自定義模塊路徑(${CMAKE_CURRENT_SOURCE_DIR} 是當前 CMakeLists.txt 所在目錄)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")

步驟 3:使用自定義模塊

# 加載自定義模塊
include(AddMyTest)# 調用模塊中的 add_my_test 函數(無需重復編寫測試配置)
add_my_test(test1 tests/test1.cpp)
add_my_test(test2 tests/test2.cpp)

2.自定義模塊的典型場景

  • 封裝項目通用編譯選項:如?SetCompilerFlags.cmake,統一設置?-Wall-O2?等編譯 flags。
  • 處理項目特有依賴:如?FindMySDK.cmake,查找團隊內部 SDK 的頭文件和庫。
  • 生成自定義文件:如?GenerateVersion.cmake,封裝?configure_file?邏輯生成版本頭文件。

5.注意事項

1.命名規范

  • 內置模塊通常遵循?FindXXX.cmake(查找依賴)、CheckXXX.cmake(功能檢測)等命名。
  • 自定義模塊建議使用項目相關前綴(如?MyProjectUtils.cmake),避免與內置模塊重名。

2.路徑管理

  • 自定義模塊統一放在項目的?cmake/Modules?目錄,便于維護。
  • 通過?CMAKE_MODULE_PATH?動態添加路徑(而非硬編碼),確保模塊可被正確找到。

3.接口設計

  • 模塊中定義的函數 / 宏應清晰易懂,參數明確(如?add_my_test(test_name src_files))。
  • 暴露的變量建議添加前綴(如?MY_MODULE_XXX),避免與其他模塊沖突。

4.文檔說明

在模塊開頭添加注釋,說明模塊功能、使用方法、依賴項(如?# AddMyTest.cmake: 簡化 GTest 測試用例添加,依賴 googletest)。

6.總結

CMake Modules 是簡化配置的 “瑞士軍刀”:

  • 內置模塊提供開箱即用的功能(依賴查找、特性檢測等),避免重復造輪子;
  • 自定義模塊封裝項目特有邏輯,提升配置復用性和一致性。

通過合理使用模塊,可將復雜的 CMake 配置簡化為 “引入模塊 + 調用接口” 的簡潔形式,尤其適合大型項目或多項目管理,顯著降低維護成本。

相關鏈接

  • CMake 官網?CMake - Upgrade Your Software Build System
  • CMake 官方文檔:CMake Tutorial — CMake 4.1.0 Documentation
  • CMake 源碼:https://github.com/Kitware/CMake
  • CMake 源碼:CMake · GitLab
  • 中文版基礎介紹:?CMake 入門實戰 | HaHack
  • wiki:?Home · Wiki · CMake / Community · GitLab
  • Modern CMake 簡體中文版:??Introduction · Modern CMake

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94040.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94040.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94040.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Docker】Ubuntu上安裝Docker(網絡版)

【Docker】Ubuntu上安裝Docker注意:一、環境準備1. 系統要求2. 卸載舊版本二、安裝步驟1.配置倉庫源2.安裝 Docker引擎3.驗證安裝情況三、解決報錯1、檢查網絡連接2、檢查Docker服務狀態3、換源4.重載生效、重啟服務、查看是否配置成功5.驗證解決情況四、權限與配置…

Socket 編程 TCP

TCP 網絡程序 和剛才 UDP 類似. 實現一個簡單的英譯漢的功能。TCP是面向字節流的可靠傳輸,如同前文的管道流,只要是流,它的操作就是文件的寫出與讀入。TCP socket API 詳解下面介紹程序中用到的 socket API,這些函數都在 sys/socket.h 中。so…

使用AWS S3 + Lambda + MediaConvert 實現上傳視頻文件并自動轉碼

前言 最近團隊在做短視頻平臺的技術調研,其中有一個環節便是音視頻開發,即對用戶上傳的視頻進行自適應轉碼。自適應的原理其實就是預先將視頻轉換為幾個常用的分辨率,app端根據用戶手機分辨率拉取相應分辨率的視頻。 目前嘗試了兩種方案&…

QT之QWaitCondition降低cpu占用率,從忙等待到高效同步

在多線程編程中,線程間的同步是一個核心問題。在處理線程等待時,經常會寫出高CPU占用率的代碼,其中最典型的就是使用忙等待(busy waiting)。本文將詳細介紹如何使用Qt框架中的QWaitCondition類來優雅地解決這一問題&am…

pcl求平面點云的邊界凸包點

基本流程1,讀入點云,并去除無效點2,擬合平面3,去除離平面距離較遠的點4,對點云進行平面投影5,進行convex_hull運算初學者,暫時不知道能用來干嘛。練手還是非常不錯的!#define _CRT_S…

Windows系統上使用GIT

首先破除一下畏懼心理:在Windows上使用git和在linux系統中的使用方法是一樣的,只是安裝方式沒那么便捷,畢竟linux中安裝git只需要一行命令 GIT下載地址 如果你的電腦的CPU是64位的,就點擊: Git-2.50.1-64-bit.exe 如果…

《設計模式之禪》筆記摘錄 - 17.模板方法模式

模板方法模式的定義模板方法模式(Template Method Pattern)是如此簡單,以致讓你感覺你已經能夠掌握其精髓了。其定義如下:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.Template Method lets subclasses r…

SpreadJS 協同服務器 MongoDB 數據庫適配支持

為了支持 SpreadJS 協同編輯場景,協同服務器需要持久化存儲文檔、操作、快照及里程碑數據。本文介紹了 MongoDB 數據庫適配器的實現方法,包括集合初始化、適配器接口實現以及里程碑存儲支持。 一、MongoDB 集合初始化 協同編輯服務需要以下集合&#x…

Ubuntu 主機名:精通配置與管理

主機名(hostname)是Linux系統中用于標識網絡上特定設備的名稱,它在網絡通信、服務配置(如 Kubernetes 集群、數據庫)以及日志記錄中扮演著至關重要的角色。對于初學者來說,配置主機名似乎很簡單&#xff0c…

C/C++ 協程:Stackful 手動控制的工程必然性

🚀 C/C 協程:Stackful 手動控制的工程必然性 引用: C/C 如何正確的切換協同程序?(基于協程的并行架構) #mermaid-svg-SXgplRf3WRYc8A7l {font-family:"trebuchet ms",verdana,arial,sans-serif;…

新手向:使用STM32通過RS485通信接口控制步進電機

新手向:使用STM32通過RS485通信接口控制步進電機 準備工作 本文使用的STM32芯片是STM32F407ZGTx,使用的電機是57步進電機,驅動器是用的是時代超群的RS485總線一體化步進電機驅動器(42 型:ZD-M42P-485)。使…

設計模式筆記_行為型_命令模式

1.命令模式介紹命令模式(Command Pattern)是一種行為設計模式,它將請求或操作封裝為對象,使得可以用不同的請求對客戶端進行參數化。命令模式的核心思想是將方法調用、請求或操作封裝到一個獨立的命令對象中,從而使得客…

詳解MySQL中的多表查詢:多表查詢分類講解、七種JOIN操作的實現

精選專欄鏈接 🔗 MySQL技術筆記專欄Redis技術筆記專欄大模型搭建專欄Python學習筆記專欄深度學習算法專欄 歡迎訂閱,點贊+關注,每日精進1%,與百萬開發者共攀技術珠峰 更多內容持續更新中!希望能給大家帶來…

vue3+elemeent-plus, el-tooltip的樣式修改不生效

修改后的樣式&#xff0c;直接貼圖&#xff0c;經過刪除出現懸浮1、在書寫代碼的時候切記effect“light”&#xff0c;如果你需要的是深色的樣式:disabled"!multiple" 是否禁用<el-tooltip effect"light" placement"top" content"請先選…

網頁作品驚艷亮相!這個浪浪山小妖怪網站太治愈了!

大家好呀&#xff01;今天要給大家分享一個超級治愈的網頁作品——浪浪山小妖怪主題網站&#xff01;這個純原生開發的項目不僅顏值在線&#xff0c;功能也很能打哦&#xff5e;至于靈感來源的話&#xff0c;要從一部動畫說起。最近迷上了治愈系動畫&#xff0c;就想做一個溫暖…

搭建最新--若依分布式spring cloudv3.6.6 前后端分離項目--步驟與記錄常見的坑

首先 什么拉取代碼&#xff0c;安裝數據庫&#xff0c;安裝redis&#xff0c;安裝jdk這些我就不說了 導入數據庫 &#xff1a;數據庫是分庫表的 &#xff0c;不要建錯了 【一定要注意&#xff0c;不然nacos讀取不到配置文件】這個是給nacos用的這個是給項目配置或項目用的2. 服…

分布式唯一 ID 生成方案

在復雜分布式系統中&#xff0c;往往需要對大量的數據和消息進行唯一標識。如在美團點評的金融、支付、餐飲、酒店、貓眼電影等產品的系統中&#xff0c;數據日漸增長&#xff0c;對數據分庫分表后需要有一個唯一 ID 來標識一條數據或消息&#xff0c;數據庫的自增 ID 顯然不能…

飛算JavaAI賦能高吞吐服務器模擬:從0到百萬級QPS的“流量洪峰”征服之旅

引言&#xff1a;當“流量洪峰”來襲&#xff0c;如何用低代碼馴服高并發&#xff1f; 在數字化時代&#xff0c;從電商平臺的“雙11”大促到社交網絡的突發熱點事件&#xff0c;再到金融系統的實時交易高峰&#xff0c;服務器時刻面臨著**高吞吐量&#xff08;High Throughput…

C#數據訪問幫助類

一.中文注釋using System; using System.Data; using System.Xml; using System.Data.SqlClient; using System.Collections;namespace Microsoft.ApplicationBlocks.Data.Ch {/// <summary>/// SqlServer數據訪問幫助類/// </summary>public sealed class SqlHelp…

B站 韓順平 筆記 (Day 21)

目錄 1&#xff08;面向對象高級部分練習題&#xff09; 1.1&#xff08;題1&#xff09; 1.2&#xff08;題2&#xff09; 1.3&#xff08;題3&#xff09; Vehicles接口類&#xff1a; Horse類&#xff1a; Boat類&#xff1a; Plane類&#xff1a; VehiclesFactory…