CMake使用
CMake是一个跨平台的自动化构建系统,用于管理软件构建过程。以下是CMake书写的主要指南和最佳实践:
一、基本结构
1. 基本命令
cmake_minimum_required(VERSION x.x)
-
指定 CMake 的最低版本要求
-
示例:
cmake_minimum_required(VERSION 3.10)
project(<PROJECT-NAME> [LANGUAGES] [VERSION])
-
定义项目名称和相关属性
-
示例:
project(MyProject VERSION 1.0 LANGUAGES CXX)
add_executable(<name> [source1] [source2 ...])
-
添加可执行文件目标
-
示例:
add_executable(myapp main.cpp utils.cpp)
add_library(<name> [STATIC|SHARED|MODULE] [source1] [source2 ...])
-
添加库目标
-
示例:
cmake
add_library(mylib STATIC lib1.cpp lib2.cpp) # 静态库 add_library(mylib SHARED lib1.cpp lib2.cpp) # 动态库
target_link_libraries(<target> [item1] [item2 ...])
-
为指定目标添加链接库
-
示例:
target_link_libraries(myapp PRIVATE mylib)
cmake 示例
cmake_minimum_required(VERSION 3.10) # 指定最低CMake版本
project(MyProject VERSION 1.0 LANGUAGES CXX) # 定义项目名称和语言# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 添加可执行文件
add_executable(my_app main.cpp)# 添加库
add_library(my_lib STATIC lib.cpp)
2. 变量使用
set(<variable> <value>)
-
设置变量
-
示例:
cmake
set(SOURCES main.cpp utils.cpp) set(CMAKE_CXX_STANDARD 17)
unset(<variable>)
-
取消设置变量
list(APPEND <list> <element> [<element> ...])
-
向列表变量追加元素
-
示例:
list(APPEND SOURCES extra.cpp)
option(<option_variable> "help string" [initial value])
-
提供用户可配置选项
-
示例:
option(BUILD_TESTS "Build the tests" ON)
cmake 示例
# 设置变量
set(MY_VARIABLE "value")# 使用变量
message(STATUS "Value is ${MY_VARIABLE}")# 列表变量
set(MY_LIST a b c)
list(APPEND MY_LIST d) # 追加元素
二、控制流命令
1. 条件语句 if()/elseif()/else()/endif()
cmake
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")# Linux特定设置
elseif(WIN32)# Windows特定设置
else()message(WARNING "Unsupported system")
endif()
2. 循环 foreach()/endforeach()和 while()/endwhile()
cmake
foreach(file ${SOURCE_FILES})message(STATUS "Processing ${file}")
endforeach()while(condition)# 循环体
endwhile()
3. 函数和宏
cmake
# 定义函数
function(print_target_properties target)get_target_property(target_type ${target} TYPE)message(STATUS "Target ${target} is of type ${target_type}")
endfunction()# 定义宏
macro(setup_test test_name)add_executable(${test_name} ${ARGN})add_test(NAME ${test_name} COMMAND ${test_name})
endmacro()
4. 查找与包含
find_package(<包名> [版本号] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [组件列表...]]
[OPTIONAL_COMPONENTS 组件列表...]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
[GLOBAL]
[NO_DEFAULT_PATH]
[PATHS 路径列表...]
[PATH_SUFFIXES 后缀列表...]
[CONFIG|NO_MODULE]
[NO_CMAKE_PACKAGE_REGISTRY]
[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
[NO_CMAKE_BUILDS_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH])
主要参数说明
-
版本控制
-
[version]
:指定所需的最低版本号(如2.6.3
) -
EXACT
:要求版本必须精确匹配
-
-
查找模式
-
MODULE
:仅使用 FindModule 模式 -
CONFIG
:仅使用 Config 模式 -
默认会先尝试 Module 模式,再尝试 Config 模式
-
-
输出控制
-
QUIET
:禁止输出信息 -
REQUIRED
:如果找不到包则报错终止
-
-
组件支持
-
COMPONENTS
:指定必须找到的组件 -
OPTIONAL_COMPONENTS
:指定可选组件
-
-
查找外部依赖包
-
示例:
find_package(OpenCV REQUIRED)
include(<file|module>)
-
包含其他 CMake 文件或模块
-
示例:
include(CTest)
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
-
添加头文件搜索路径(现代 CMake 推荐使用
target_include_directories()
)
link_directories([AFTER|BEFORE] directory1 [directory2 ...])
-
添加库文件搜索路径(现代 CMake 推荐使用
target_link_directories()
)
5. 目标属性设置
target_include_directories(<target> [SYSTEM] [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...])
-
为目标指定包含目录
-
示例:
cmake
target_include_directories(mylib PUBLIC include # 公开头文件目录 PRIVATE src # 私有头文件目录 )
target_compile_definitions(<target> <INTERFACE|PUBLIC|PRIVATE> [items1...])
-
为目标添加编译定义
-
示例:
target_compile_definitions(mylib PRIVATE USE_DEBUG=1)
target_compile_options(<target> [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...])
-
为目标添加编译选项
-
示例:
target_compile_options(mylib PRIVATE -Wall -Wextra)
6. 文件操作
file(GLOB <va