目錄
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.cmake
、FetchContent.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_path
、find_library
?等命令實現查找,并暴露統一的接口變量(如?XXX_INCLUDE_DIRS
、XXX_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.cmake
、CTest.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