CMake 構建系統重點內容
1 基本語法與結構
cmake_minimum_required()
指定使用的最低 CMake 版本,防止不同版本行為不一致:
cmake_minimum_required(VERSION 3.16)
project()
定義項目名稱、語言和版本:
project(MyApp VERSION 1.0 LANGUAGES C CXX)
add_executable()
添加一個可執行文件目標:
add_executable(myapp main.cpp)
add_library()
添加一個靜態或動態庫:
add_library(mylib STATIC lib.cpp)
# 或
add_library(mylib SHARED lib.cpp)
target_include_directories()
指定目標使用的頭文件搜索路徑:
target_include_directories(myappPRIVATE ${CMAKE_SOURCE_DIR}/include
)
PRIVATE
: 僅本目標使用PUBLIC
: 本目標及依賴它的目標都使用INTERFACE
: 只導出給依賴者,不用于本身
target_link_libraries()
鏈接庫或其他目標:
target_link_libraries(myappPRIVATE mylibPRIVATE pthread
)
target_compile_options()
添加編譯選項:
target_compile_options(myapp PRIVATE -Wall -O2)
target_compile_definitions()
添加宏定義(等價于 -D
):
target_compile_definitions(myapp PRIVATE VERSION="1.0")
2 構建類型(Build Type)
通過 CMAKE_BUILD_TYPE
控制不同構建模式:
cmake -DCMAKE_BUILD_TYPE=Release ..
構建類型 | 描述 |
---|---|
Debug | 含調試信息,關閉優化,默認編譯 -g |
Release | 啟用優化 -O3 ,無調試信息 |
RelWithDebInfo | 含調試信息 + 優化(適合性能調試) |
MinSizeRel | 最小二進制文件(嵌入式) |
3 編譯器檢測與選項控制
CMake 可檢測編譯器與平臺差異,并根據平臺設置不同選項:
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")target_compile_options(myapp PRIVATE -Wall -Wextra)
endif()if (MSVC)target_compile_options(myapp PRIVATE /W4)
endif()
4 子模塊與子項目支持
add_subdirectory()
添加子模塊項目:
add_subdirectory(thirdparty/mylib)
target_link_libraries(myapp PRIVATE mylib)
- 要求子目錄下有
CMakeLists.txt
FetchContent
(現代推薦)
自動下載第三方依賴并引入構建流程:
include(FetchContent)
FetchContent_Declare(jsonGIT_REPOSITORY https://github.com/nlohmann/json.gitGIT_TAG v3.11.2
)
FetchContent_MakeAvailable(json)
target_link_libraries(myapp PRIVATE nlohmann_json::nlohmann_json)
適合構建階段臨時獲取依賴而不污染系統環境。
5 外部項目支持:ExternalProject_Add
用于構建不能直接作為子目錄添加的外部項目(適用于非 CMake 項目):
include(ExternalProject)
ExternalProject_Add(extlibURL https://example.com/extlib.tar.gzCONFIGURE_COMMAND ./configureBUILD_COMMAND makeINSTALL_COMMAND make install
)
可用于引入 Autotools / Makefile 項目。
6 安裝與導出
install()
設置安裝路徑規則:
install(TARGETS myapp DESTINATION bin)
install(FILES include/mylib.h DESTINATION include)
安裝到 CMAKE_INSTALL_PREFIX
,默認是 /usr/local
執行安裝命令:
cmake --install build
export()
與配置導出
為了支持 目標被其他 CMake 項目 find_package 使用,需要導出配置:
install(TARGETS mylib EXPORT mylibTargets DESTINATION lib)
install(EXPORT mylibTargetsFILE mylibTargets.cmakeNAMESPACE mylib::DESTINATION lib/cmake/mylib
)
配合生成配置文件 mylibConfig.cmake
:
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/mylibConfigVersion.cmake"VERSION 1.0COMPATIBILITY SameMajorVersion
)
install(FILES"${CMAKE_CURRENT_SOURCE_DIR}/mylibConfig.cmake""${CMAKE_CURRENT_BINARY_DIR}/mylibConfigVersion.cmake"DESTINATION lib/cmake/mylib
)
這樣就能在其他項目中使用:
find_package(mylib REQUIRED)
target_link_libraries(app PRIVATE mylib::mylib)
總結
CMake 總體結構
├── 項目定義與語法
│ ├── cmake_minimum_required()
│ ├── project()
│ ├── add_executable / add_library
│ ├── target_* APIs
├── 構建類型與選項
│ ├── CMAKE_BUILD_TYPE
│ ├── target_compile_options / definitions
├── 多模塊與依賴
│ ├── add_subdirectory
│ ├── FetchContent_Declare
│ └── ExternalProject_Add
├── 安裝與包導出
│ ├── install()
│ ├── export()
│ └── CMakePackageConfigHelpers