CMake指令详解
CMake是一个跨平台的自动化构建系统,它使用平台无关的CMakeLists.txt文件来控制软件编译过程。以下是CMake核心指令的详细说明:
1. 基本项目配置指令
cmake_minimum_required()
指定CMake的最低版本要求
cmake_minimum_required(VERSION 3.5)
project()
定义项目基本信息
project(MyProject
VERSION 1.0.0
DESCRIPTION "A sample CMake project"
LANGUAGES CXX
)
2. 可执行文件和库指令
add_executable()
添加可执行文件目标
add_executable(my_app main.cpp utils.cpp)
add_library()
添加库目标
add_library(my_lib STATIC lib.cpp) # 静态库
add_library(my_shared_lib SHARED shared.cpp) # 共享库
3. 目录和文件操作指令
include_directories()
添加头文件搜索路径
include_directories(${PROJECT_SOURCE_DIR}/include)
target_include_directories()
为目标添加头文件搜索路径
target_include_directories(my_lib PUBLIC include)
4. 链接指令
target_link_libraries()
为目标添加链接库
target_link_libraries(my_app PRIVATE my_lib pthread)
5. 变量和选项指令
set()
设置变量
set(SOURCES main.cpp utils.cpp)
set(CMAKE_CXX_STANDARD 17)
option()
定义用户选项
option(BUILD_TESTS "Build the testing tree" ON)
6. 查找和包管理指令
find_package()
查找外部依赖包
find_package(OpenCV REQUIRED)
FetchContent
从外部获取内容
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz
)
FetchContent_MakeAvailable(googletest)
7. 条件控制指令
if()
条件判断
if(UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
foreach()
循环遍历
foreach(source ${SOURCES})
message(STATUS "Source file: ${source}")
endforeach()
8. 安装指令
install()
定义安装规则
install(TARGETS my_app
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
9. 生成器表达式
CMake提供强大的生成器表达式
target_compile_definitions(my_app PRIVATE
$<$<CONFIG:Debug>:DEBUG_MODE=1>
)
这些指令构成了CMake的基本框架,实际使用时可以根据项目需求组合这些指令来构建复杂的构建系统。CMake的核心指令包括:
- 项目定义指令:
project()
:定义项目名称、版本和使用的编程语言(如C、C++)cmake_minimum_required()
:指定最低要求的CMake版本
- 可执行文件和库指令:
add_executable()
:创建可执行文件add_library()
:创建静态库或动态库target_link_libraries()
:链接依赖库
- 变量和控制流指令:
set()
:定义变量if()
/else()
/endif()
:条件控制foreach()
/endforeach()
:循环控制
- 查找和包含指令:
find_package()
:查找外部依赖包include_directories()
:添加头文件搜索路径target_include_directories()
:为目标添加包含目录
实际应用场景示例:
- 简单项目:
cmake_minimum_required(VERSION 3.10)
project(MyApp VERSION 1.0)
add_executable(myapp main.cpp)
- 复杂项目:
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.2 LANGUAGES C CXX)
# 设置编译选项
set(CMAKE_CXX_STANDARD 17)
# 添加子目录
add_subdirectory(src)
add_subdirectory(libs)
# 查找依赖
find_package(OpenCV REQUIRED)
# 创建可执行文件
add_executable(main main.cpp)
# 链接库
target_link_libraries(main PRIVATE
mylib
OpenCV::OpenCV
)
通过灵活组合这些指令,可以构建从简单到复杂的各种项目,包括多目录结构、多目标构建、条件编译等复杂场景。
CMake相关命令详解
基本命令
cmake_minimum_required(VERSION x.x)
指定CMake的最低版本要求。例如:
cmake_minimum_required(VERSION 3.10)
如果系统安装的CMake版本低于此要求,CMake会报错终止。
project(<PROJECT-NAME> [LANGUAGES] [VERSION])
定义项目名称和相关信息。例如:
project(MyProject VERSION 1.0 LANGUAGES CXX)
可选参数:
VERSION
:指定项目版本号LANGUAGES
:指定项目使用的编程语言,如C、CXX(即C++)等
构建目标命令
add_executable(<name> [source1...])
创建可执行文件目标。例如:
add_executable(myapp main.cpp utils.cpp)
可以指定多个源文件,CMake会自动处理编译依赖关系。
add_library(<name> [STATIC|SHARED|MODULE] [source1...])
创建库目标。库类型可以是:
STATIC
:静态库(.a或.lib)SHARED
:动态库(.so或.dll)MODULE
:模块库(插件)
例如:
add_library(mylib STATIC src1.cpp src2.cpp)
查找和包含命令
find_package(<PackageName> [version] [EXACT] [REQUIRED])
查找外部依赖包。例如:
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
常见参数:
REQUIRED
:如果找不到包则报错COMPONENTS
:指定需要的组件version
:指定最低版本要求EXACT
:要求版本完全匹配
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
添加头文件搜索路径。例如:
include_directories(${PROJECT_SOURCE_DIR}/include)
AFTER
或BEFORE
控制路径添加顺序,SYSTEM
标记为系统目录。
target_include_directories(<target> [SYSTEM] [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...])
为目标添加头文件搜索路径。例如:
target_include_directories(mylib PUBLIC include)
作用域说明:
PRIVATE
:仅当前目标使用PUBLIC
:当前目标及其依赖者使用INTERFACE
:仅依赖者使用
链接命令
target_link_libraries(<target> [item1...] [<debug|optimized|general> <item>...])
为目标添加链接库。例如:
target_link_libraries(myapp PRIVATE mylib ${Boost_LIBRARIES})
可以指定链接类型的修饰符:
debug
:仅Debug配置下链接optimized
:仅Release配置下链接general
:所有配置都链接
变量操作命令
set(<variable> <value> [CACHE <type> <docstring> [FORCE]])
设置变量。例如:
set(MY_VAR "value" CACHE STRING "Description")
使用CACHE
会将变量存入CMake缓存中,FORCE
会覆盖已有值。
option(<variable> "<help_text>" [value])
定义用户可配置的选项。例如:
option(BUILD_TESTS "Build test cases" ON)
在命令行可使用-D
选项修改这些值。
流程控制命令
if()/elseif()/else()/endif()
条件判断。例如:
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Linux-specific settings
elseif(APPLE)
# Mac-specific settings
endif()
foreach()/endforeach()
循环遍历列表。例如:
foreach(file IN LISTS SOURCE_FILES)
# 处理每个源文件
endforeach()
生成器表达式
CMake提供强大的生成器表达式,用于在生成构建系统时动态计算值。例如:
target_compile_definitions(mylib PRIVATE $<$<CONFIG:Debug>:DEBUG_MODE=1>)
这个表达式表示在Debug配置下添加DEBUG_MODE=1
定义。
常用生成器表达式:
$<CONFIG:cfg>
:当前构建配置是否为cfg$<TARGET_EXISTS:target>
:目标是否存在$<BOOL:...>
:转换为布尔值
其他实用命令
configure_file(<input> <output> [@ONLY] [ESCAPE_QUOTES])
复制并替换文件中的变量。例如:
configure_file(config.h.in config.h)
文件中的@VAR@
或${VAR}
会被替换为当前CMake变量的值。
add_custom_command()/add_custom_target()
添加自定义构建步骤。例如:
add_custom_command(
OUTPUT generated.cpp
COMMAND generator input.txt generated.cpp
DEPENDS input.txt
)
add_custom_target
创建一个始终构建的目标。
file()
文件操作命令。常见用法:
file(GLOB SOURCES "src/*.cpp") # 获取文件列表
file(MAKE_DIRECTORY ${OUTPUT_DIR}) # 创建目录
file(COPY ${DATA_FILES} DESTINATION ${INSTALL_DIR}) # 复制文件
install()
定义安装规则。例如:
install(TARGETS myapp mylib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
可安装目标、文件或目录,并指定不同类型文件的安装位置。