Cmake使用教程
CMake是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个库。
目录
- 一、速查手册
- 二、基本用法
- 三、进阶用法
- 四、语法规则
- 五、常用函数
- 1. `project()`
- 2. `cmake_minimum_required()`
- 3. `add_executable()`
- 4. `add_library()`
- 5. `target_link_libraries()`
- 6. `find_package()`
- 7. `include_directories()`
- 8. `set()`
- 9. `add_subdirectory()`
- 10. `install()`
- 11. `configure_file()`
- 12. `message()`
- 13. `option()`
- 14. `if()`, `elseif()`, `else()`, `endif()`
- 15. `file()`
- 16. `list()`
- 17. `foreach()`
- 18. `while()`
- 19. `math()`
- 20. `add_custom_command()`
- 21. `add_custom_target()`
- 22. `add_definitions()`
- 23. `add_compile_options()`
- 24. `export()`
- 25. `find_file()`
- 26. `find_library()`
- 27. `find_path()`
- 28. `find_program()`
- 29. `include()`
- 30. `enable_testing()` 和 `add_test()`
- 31. `ctest`
- 32. `target_include_directories()`
- 33. `target_compile_definitions()`
- 34. `target_compile_options()`
- 35. `target_sources()`
- 36. `try_compile()`
- 37. `try_run()`
一、速查手册
1. 常用命令
命令 | 作用 |
---|---|
cmake … | 使用默认参数执行构建 |
cmake -D CMAKE_BUILD_TYPE=Debug … | 构建带调试信息的程序或库 |
cmake -G Ninja … | 指定生成器为Ninja |
cmake --build . | 根据默认构建系统生成程序 |
cmake -version | 查看cmake版本 |
-B
用于指定构建目录-D
用于定义Cmake变量-E
调用Cmake内置命令的参数-G
用于指定生成器-S
用于指定源代码目录,此目录包含了CMakeLists.txt
文件
2. 常用变量
变量名 | 含义 |
---|---|
CMAKE_SOURCE_DIR | 最顶层CmakeLists.txt所在目录,CHAN |
CMAKE_CURRENT_SOURCE_DIR | 当前CMakeLists.txt 所在路径 |
PROJECT_SOURCE_DIR | 工程的根目录 |
CMAKE_ARCHIVE_OUTPUT_DIRECTORY | 静态库的输出目录 |
CMAKE_LIBRARY_OUTPUT_DIRECTORY | 动态库的输出目录 |
CMAKE_RUNTIME_OUTPUT_DIRECTORY | 可执行文件的输出路径 |
3. 基本模板
cmake_minimum_required (VERSION 3.5)
project (Test)
# 设置头文件目录
include_directories(${PROJECT_SOURCE_DIR}/inc INC_DIR)
# 设置源文件目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC_DIR)
# 添加可执行文件
add_executable(helloworld hello.cpp)
# 链接库
target_link_libraries(helloworld ${CMAKE_SOURCE_DIR}/add.a)
cmake_minimum_required (VERSION 3.5)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
project (Test)
# 设置头文件目录
include_directories(${PROJECT_SOURCE_DIR}/inc INC_DIR)
# 设置源文件目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC_DIR)
# 添加可执行文件
add_executable(helloworld hello.cpp)
# 链接库
target_link_libraries(helloworld ${CMAKE_SOURCE_DIR}/add.a)
二、基本用法
1. 单个源文件
1.1 目录结构
.
├── build
├── CMakeLists.txt
└── hello.cpp
1.2 CmakeLists.txt
cmake_minimum_required (VERSION 3.5)
project (LearnCmake)
add_executable(helloworld hello.cpp)
1.3 编译步骤
cd build
cmake ..
make
2. 多个源文件
2.1 目录结构
Project
├── build
├── add.cpp
├── add.hpp
├── CMakeLists.txt
└── hello.cpp
2.2 CmakeLists.txt
cmake_minimum_required (VERSION 3.5)
project (LearnCmake)
add_executable(helloworld hello.cpp add.cpp)
2.3 编译步骤
cd build
cmake ..
make
3. 编译动态库
3.1 目录结构
├── build
├── CMakeLists.txt
├── hello.cpp
├── hello.hpp
└── main.cpp
3.2 CmakeLists.txt
cmake_minimum_required (VERSION 3.5)
project (LearnCmake)
# 创建共享库目标
add_library(hello SHARED hello.hpp hello.cpp)
# 设置库的最终生成路径
set(LIBRARY_OUTPUT_PATH ./lib)
3.3 编译步骤
cd build
cmake ..
make
4. 编译静态库
4.1 目录结构
Project
├── build
├── CMakeLists.txt
├── hello.cpp
├── hello.hpp
└── main.cpp
4.2 CmakeLists.txt
cmake_minimum_required (VERSION 3.5)
project (LearnCmake)
# 创建共享库目标
add_library(hello STATIC hello.hpp hello.cpp)
# 设置库的最终生成路径
set(LIBRARY_OUTPUT_PATH ./lib)
4.3 编译步骤
cd build
cmake ..
make
5. 综合案例
5.1 目录结构
Project
├── build/
├── CMakeLists.txt
├── inc/
│ └── hello.hpp
├── src/
│ ├── hello.cpp
│ └── main.cpp
└── thirdparty/
├── opencv4/
└── eigen/
5.2 CmakeLists.txt
# 设置最低版本
cmake_minimum_required (VERSION 3.5)
# 设置项目名称
project (LearnCmake)
# 设置OpenCV库的路径
set(OpenCV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/thirdparty/opencv/include")
set(OpenCV_LIBS
"${CMAKE_SOURCE_DIR}/thirdparty/opencv/lib/opencv_core.lib"
"${CMAKE_SOURCE_DIR}/thirdparty/opencv/lib/opencv_imgproc.lib"
"${CMAKE_SOURCE_DIR}/thirdparty/opencv/lib/opencv_highgui.lib"
)
# 设置头文件目录
include_directories(
${PROJECT_SOURCE_DIR}/inc
${OpenCV_INCLUDE_DIRS}
)
# 设置源文件目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC_DIR)
# 创建共享库目标
add_library(hello_shared SHARED ${SRC_DIR})
# 创建静态库目标
add_library(hello_static STATIC ${SRC_DIR})
# 设置库的最终生成路径
set(LIBRARY_OUTPUT_PATH ../lib)
# 创建可执行文件
add_executable(main main.cpp)
# 链接库文件
target_link_libraries(main hello_static ${OpenCV_LIBS})
5.3 编译步骤
mkdir -p build
cd build
cmake ..
cmake --build .
三、进阶用法
1. 编译选项
有时因为一些特殊需要,为了实现自定义的编译,我们需要指定编译选项,这时我们可使用 add_compile_options
来添加编译选项,如下:
add_compile_options(-std=c++11 -Wall)
2. 控制选项
有时希望在编译代码时只编译一些指定的源码,可以使用cmake的option命令,主要遇到的情况分为2种:
- 本来要生成多个bin或库文件,现在只想生成部分指定的bin或库文件
- 对于同一个bin文件,只想编译其中部分代码(使用宏来控制)
3. 设置目录
aux_source_directory(dir var)
可把dir目录中的所有源文件都储存在var变量中include_directories ( dir )
,其作用类似gcc中的 gcc -I dir
设置指定头文件及源文件目录的示例CMakeLists.txt
文件如下:
# 设置最低版本
cmake_minimum_required (VERSION 3.5)
# 设置项目名称
project (LearnCmake)
# 设置头文件目录
include_directories(./include1 ./include2)
# 设置源文件目录
aux_source_directory(src1 SRC1_DIR)
aux_source_directory(src2 SRC2_DIR)
aux_source_directory(main MAIN_DIR)
# 生成可执行文件
add_executable(helloworld ${SRC1_DIR} ${SRC2_DI} ${MAIN_DIR})
4. 编译类型
1. Debug: `-O0 -g`
2. Release: `-O3 -DNDEBUG`
3. MinSizeRel: `-Os -DNDEBUG`
4. RelWithDebInfo: `-O2 -g -DNDEBUG`
4.1 C编译标志相关变量
CMAKE_C_FLAGS
CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
4.2 C++编译标志相关变量
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]或 CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO] 则指定特定构建类型的编译标志,这些编译标志将被加入到 CMAKE_C_FLAGS 或 CMAKE_CXX_FLAGS 中去,例如,如果构建类型为 DEBUG,那么 CMAKE_CXX_FLAGS_DEBUG 将被加入到 CMAKE_CXX_FLAGS中去
4.3 链接标志相关变量
CMAKE_EXE_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
CMAKE_MODULE_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
CMAKE_SHARED_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
它们类似于编译标志相关变量
debug版的项目生成的可执行文件需要有调试信息并且不需要进行优化,而release版的不需要调试信息但需要优化。这些特性在gcc/g++中是通过编译时的参数决定的,如果将优化程度调到最高需要设置-O3,最低-O0即不做优化;添加调试信息的参数是-g -ggdb,如果不添加这个参数,调试信息就不会被包含在生成的二进制文件中。
CMake中有一个变量CMAKE_BUILD_TYPE,可以的取值是Debug、Release、RelWithDebInfo和MinSizeRel。当这个变量值为Debug的时候,CMake会使用变量CMAKE_CXX_FLAGS_DEBUG和 CMAKE_C_FLAGS_DEBUG中的字符串作为编译选项生成Makefile ,当这个变量值为 Release 的时候,工程会使用变量 CMAKE_CXX_FLAGS_RELEASE 和CMAKE_C_FLAGS_RELEASE 选项生成 Makefile。
project(main)
cmake_minimum_required(version 2.6)
set(CMAKE_SOURCE_DIR .)
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") # 设置debug编译选项
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") # 设置release编译选项
ADD_EXECUTABLE(main ${DIR_SRCS})
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
5. 多层目录
顶层目录 CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(helloworld)
# 添加源代码目录
aux_source_directory(. DIRSRCS)
# 添加头文件
include_directories(./ ./hello ./world)
# 添加子目录
add_subdirectory(hello)
add_subdirectory(world)
# 添加可执行文件并链接子目录的库
add_executable(helloworld ${DIRSRCS})
target_link_libraries(helloworld hello world)
hello子目录 CMakeLists.txt
aux_source_directory(. DIR_HELLO_SRCS)
add_library(hello ${DIR_HELLO_SRCS})
world子目录 CMakeLists.txt
aux_source_directory(. DIR_WORLD_SRCS)
add_library(world ${DIR_WORLD_SRCS})
四、语法规则
Cmake的指令是大小写无关的,但建议全部使用大写指令。
1. 注释
单行注释
# 注释内容
多行注释
# [[
注释内容
]]
2. 变量
Cmake中所有的变量都是string
类型
set(变量名 变量值) # 声明一个变量
unset(变量) # 移除一个变量
${变量名} # 引用变量
message("变量名=${变量名}") # 打印一个变量值
3. 列表
列表也是字符串,可以把列表看作是一个特殊的变量,这个变量包含多个值,其语法格式如下:
# 定义列表
set(列表名 值1 值2 值3 ...) # 方式一
set(列表名 "值1;值2;值3;...") # 方式二
# 引用列表
${列表名}
# 打印列表
message("列表名=${列表名}")
# 追加内容
list(APPEND my_list "item1" "item2")
# 获取长度
list(LENGTH my_list my_list_length)
4. 作用域
4.1 全局作用域
- 在顶层 CMakeLists.txt 中定义的变量默认具有全局作用域
- 全局变量在所有子目录和包含的文件中都可以访问和修改
- 使用 CACHE 关键字定义的变量也是全局变量,并且会存储在 CMakeCache.txt 文件中,可以跨多个 CMake 运行访问
set(GLOBAL_VAR "global value") # 全局变量
set(CACHED_VAR "cached value" CACHE STRING "A cached variable") # 缓存变量
4.2 目录作用域
- 每个目录都有自己的作用域,包括使用 add_subdirectory() 添加的子目录
- 目录作用域变量只在当前目录及其子目录中可见,父目录中无法访问
# 顶层 CMakeLists.txt
set(DIR_VAR "directory value") # 在顶层目录定义
add_subdirectory(subdir)
# subdir/CMakeLists.txt
message(STATUS "DIR_VAR in subdir: ${DIR_VAR}") # 可以访问
set(SUBDIR_VAR "subdirectory value")
4.3 函数作用域
- 在函数中定义的变量仅在函数内部可见,函数结束后变量被销毁。
- 可以使用 PARENT_SCOPE 关键字将变量设置到调用函数的父作用域。
function(MyFunction)
set(FUNC_VAR "function value") # 函数作用域变量
set(PARENT_VAR "parent value" PARENT_SCOPE) # 设置到父作用域
endfunction()
MyFunction()
message(STATUS "FUNC_VAR: ${FUNC_VAR}") # 无法访问 FUNC_VAR
message(STATUS "PARENT_VAR: ${PARENT_VAR}") # 可以访问 PARENT_VAR
4.4 子范围
- 某些命令(如 if()、foreach()、while() 等)会创建子范围,子范围中的变量在子范围结束后被销毁。
- 子范围中的变量可以遮蔽父范围中的同名变量。
set(VAR "original value")
if(TRUE)
set(VAR "sub-scope value")
message(STATUS "VAR in sub-scope: ${VAR}") # sub-scope value
endif()
message(STATUS "VAR: ${VAR}") # original value
5. 判断语句
在 CMake 中,可以使用 if 语句来进行条件判断。CMake 提供了多种条件判断操作符和函数,用于比较字符串、数值、文件属性等。
5.1 比较操作符
CMake的比较操作符如下:
EQUAL
:检查是否相等LESS
:检查是否小于GREATER
:检查是否大于LESS_EQUAL
:检查是否小于或等于GREATER_EQUAL
:检查是否大于或等于STREQUAL
:检查字符串是否相等STRLESS
:检查字符串是否小于(按字典顺序)STRGREATER
:检查字符串是否大于(按字典顺序)EXISTS
:检查文件或目录是否存在IS_DIRECTORY
:检查是否是目录IS_SYMLINK
:检查是否是符号链接IS_ABSOLUTE
:检查路径是否是绝对路径
5.2 逻辑操作符
AND
:逻辑与OR
:逻辑或NOT
:逻辑非
5.3 使用示例
以下是 CMake 中条件判断语句的详细介绍和示例。
if(condition)
# Commands to execute if the condition is true
elseif(another_condition)
# Commands to execute if the another condition is true
else()
# Commands to execute if none of the above conditions are true
endif()
示例代码如下:
# 字符串比较
if(variable STREQUAL "value")
message(STATUS "Variable equals 'value'")
endif()
# 数值比较
if(variable EQUAL 10)
message(STATUS "Variable equals 10")
elseif(variable GREATER 10)
message(STATUS "Variable is greater than 10")
else()
message(STATUS "Variable is less than 10")
endif()
# 文件目录检查
if(EXISTS "path/to/file_or_directory")
message(STATUS "File or directory exists")
endif()
if(IS_DIRECTORY "path/to/directory")
message(STATUS "It is a directory")
endif()
if(IS_SYMLINK "path/to/symlink")
message(STATUS "It is a symbolic link")
endif()
# 逻辑操作
if(variable AND another_variable)
message(STATUS "Both variables are true")
endif()
if(variable OR another_variable)
message(STATUS "At least one of the variables is true")
endif()
if(NOT variable)
message(STATUS "Variable is false")
endif()
更加复杂的示例如下:
操作系统检测
cmake_minimum_required(VERSION 3.0)
project(OSDetection)
if(WIN32)
message(STATUS "This is Windows")
elseif(UNIX)
message(STATUS "This is Unix or Unix-like (including Linux and macOS)")
if(APPLE)
message(STATUS "This is macOS")
else()
message(STATUS "This is Linux or another Unix-like system")
endif()
else()
message(STATUS "Unknown operating system")
endif()
C++标准支持
cmake_minimum_required(VERSION 3.0)
project(CppStandardCheck)
set(CMAKE_CXX_STANDARD 11)
if(CMAKE_CXX_STANDARD EQUAL 11)
message(STATUS "Using C++11")
elseif(CMAKE_CXX_STANDARD EQUAL 14)
message(STATUS "Using C++14")
elseif(CMAKE_CXX_STANDARD EQUAL 17)
message(STATUS "Using C++17")
else()
message(STATUS "Using an unknown or unsupported C++ standard")
endif()
配置选项和条件编译
cmake_minimum_required(VERSION 3.0)
project(ConfigOptions)
option(USE_FEATURE_X "Enable feature X" OFF)
option(USE_FEATURE_Y "Enable feature Y" ON)
if(USE_FEATURE_X)
add_definitions(-DUSE_FEATURE_X)
message(STATUS "Feature X enabled")
endif()
if(USE_FEATURE_Y)
add_definitions(-DUSE_FEATURE_Y)
message(STATUS "Feature Y enabled")
endif()
6. 循环语句
6.1 foreach
用于遍历列表中的每个元素或特定范围的值。
# 遍历一组数值
foreach(v arg1 arg2 ...)
# Commands to execute for each element
endforeach()
# 遍历列表变量
foreach(v IN LISTS list_var)
# Commands to execute for each element in list_var
endforeach()
示例如下
cmake_minimum_required(VERSION 3.0)
project(ForeachExample)
foreach(i 1 2 3 4 5)
message(STATUS "Number: ${i}")
endforeach()
set(my_list a b c d e)
foreach(item IN LISTS my_list)
message(STATUS "Item: ${item}")
endforeach()
6.2 while
用于在给定条件为真时重复执行命令。它的基本用法如下:
while(condition)
# Commands to execute while condition is true
endwhile()
示例如下:
cmake_minimum_required(VERSION 3.0)
project(WhileExample)
set(i 0)
while(i LESS 5)
message(STATUS "Number: ${i}")
math(EXPR i "${i} + 1")
endwhile()
7. 定义函数
在 CMake 中,可以使用 function 关键字来定义函数。函数允许你封装一段逻辑,以便在多个地方重复使用。定义函数的基本语法如下:
function(FunctionName arg1 arg2 ...)
# Commands that the function executes
endfunction()
示例如下:
cmake_minimum_required(VERSION 3.0)
project(FunctionExample)
# 定义普通函数
function(PrintMessage msg)
message(STATUS "Message: ${msg}")
endfunction()
# 调用函数
PrintMessage("Hello, World!")
PrintMessage("This is a custom function in CMake.")
# 定义带有默认值的函数
function(PrintWithPrefix msg prefix)
if(NOT prefix)
set(prefix "DefaultPrefix")
endif()
message(STATUS "${prefix}: ${msg}")
endfunction()
# 调用函数
PrintWithPrefix("Hello, World!" "Greeting")
PrintWithPrefix("This is a message without a prefix")
# 定义函数并设置返回值
function(AddNumbers a b result)
math(EXPR sum "${a} + ${b}")
set(${result} ${sum} PARENT_SCOPE)
endfunction()
# 调用函数并获取返回值
AddNumbers(3 4 result)
message(STATUS "The sum is: ${result}")
# 定义处理列表的函数
function(PrintList mylist)
foreach(item IN LISTS mylist)
message(STATUS "Item: ${item}")
endforeach()
endfunction()
# 调用函数
set(mylist a b c d e)
PrintList(mylist)
8. 定义宏
9. 预设变量
变量 | 作用 |
---|---|
CMAKE_MAJOR_VERSION | cmake 主版本号 |
CMAKE_MINOR_VERSION | cmake 次版本号 |
CMAKE_C_FLAGS | 设置 C 编译选项 |
CMAKE_CXX_FLAGS | 设置 C++ 编译选项 |
PROJECT_SOURCE_DIR | 工程的根目录 |
PROJECT_BINARY_DIR | 运行 cmake 命令的目录 |
CMAKE_CURRENT_SOURCE_DIR | 当前CMakeLists.txt 所在路径 |
CMAKE_CURRENT_BINARY_DIR | 目标文件编译目录 |
EXECUTABLE_OUTPUT_PATH | 重新定义目标二进制可执行文件的存放位置 |
LIBRARY_OUTPUT_PATH | 重新定义目标链接库文件的存放位置 |
UNIX | 如果为真,表示为UNIX-like的系统,包括AppleOSX和CygWin |
WIN32 | 如果为真,表示为 Windows 系统,包括 CygWin |
APPLE | 如果为真,表示为 Apple 系统 |
CMAKE_SIZEOF_VOID_P | 表示void*的大小(例如为4或者8),可以使用其来判断当前构建为32位还是64位 |
CMAKE_CURRENT_LIST_DIR | 表示正在处理的CMakeLists.txt文件所在目录的绝对路径 |
CMAKE_ARCHIVE_OUTPUT_DIRECTORY | 用于设置ARCHIVE目标的输出路径 |
CMAKE_LIBRARY_OUTPUT_DIRECTORY | 用于设置LIBRARY目标的输出路径 |
CMAKE_RUNTIME_OUTPUT_DIRECTORY | 用于设置RUNTIME目标的输出路径 |
五、常用函数
以下是一些常用的 CMake 函数:
1. project()
- 定义项目的名称、版本和语言。
project(MyProject VERSION 1.0 LANGUAGES C CXX)
2. cmake_minimum_required()
- 设置所需的最低 CMake 版本。
cmake_minimum_required(VERSION 3.10)
3. add_executable()
- 定义一个可执行目标。
add_executable(MyExecutable main.cpp)
4. add_library()
- 定义一个库目标,可以是静态库或动态库。
add_library(MyLibrary STATIC mylib.cpp)
5. target_link_libraries()
- 为目标添加链接库,依赖的库放在后面。
target_link_libraries(MyExecutable PRIVATE MyLibrary)
# 多层依赖关系(方式一)
target_link_libraries(MyLibrary ${OpenCV_LIBS})
target_link_libraries(AnotherLibrary ${Boost_LIBRARIES})
target_link_libraries(MyExecutable MyLibrary AnotherLibrary)
# 多层依赖关系(方式二)
target_link_libraries(MyExecutable
MyLibrary
AnotherLibrary
${OpenCV_LIBS}
${Boost_LIBRARIES}
)
6. find_package()
- 查找并加载外部包。
find_package(OpenCV REQUIRED)
7. include_directories()
- 添加头文件搜索路径。
include_directories(${OpenCV_INCLUDE_DIRS})
8. set()
- 设置变量的值。
set(CMAKE_CXX_STANDARD 11)
9. add_subdirectory()
- 添加子目录,并在该目录中执行
CMakeLists.txt
。
add_subdirectory(src)
10. install()
- 定义安装规则。
install(TARGETS MyExecutable DESTINATION bin)
install(FILES MyHeader.h DESTINATION include)
11. configure_file()
- 配置文件并将其复制到指定位置。
configure_file(config.h.in config.h)
12. message()
- 在配置过程中显示信息。
message(STATUS "Building MyProject")
13. option()
- 定义一个选项变量,可以在 CMake 配置时进行开关。
option(USE_MYLIB "Use MyLibrary" ON)
14. if()
, elseif()
, else()
, endif()
- 条件语句,用于条件性地执行指令。
if(USE_MYLIB)
add_definitions(-DUSE_MYLIB)
endif()
这些是 CMake 中一些常见和基本的函数。CMake 还支持更多高级功能和模块,根据项目的需求可以进一步深入学习和使用。
15. file()
- 文件操作,如读取、写入、复制等。
file(WRITE ${CMAKE_BINARY_DIR}/output.txt "Hello, World!")
16. list()
- 列表操作,如追加、获取长度、获取元素等。
list(APPEND my_list "item1" "item2")
list(LENGTH my_list my_list_length)
17. foreach()
- 遍历列表或范围。
foreach(item IN LISTS my_list)
message(STATUS "Item ${item}")
endforeach()
18. while()
- 循环执行,直到条件为假。
set(count 0)
while(count LESS 5)
message(STATUS "Count: ${count}")
math(EXPR count "${count} + 1")
endwhile()
19. math()
- 执行数学运算。
math(EXPR result "5 * 2")
20. add_custom_command()
- 添加自定义命令,生成文件或执行命令。
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/generated_file
COMMAND ${CMAKE_COMMAND} -E echo "Generating file"
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/generated_file
)
21. add_custom_target()
- 定义一个自定义目标。
add_custom_target(
MyTarget ALL
DEPENDS ${CMAKE_BINARY_DIR}/generated_file
)
22. add_definitions()
- 添加预处理定义。
add_definitions(-DDEBUG)
23. add_compile_options()
- 添加编译选项。
add_compile_options(-Wall -Wextra)
24. export()
- 导出目标到一个文件中,供其他项目使用。
export(TARGETS MyLibrary FILE MyLibraryTargets.cmake)
25. find_file()
- 查找文件。
find_file(MY_HEADER NAMES myheader.h PATHS /usr/include /usr/local/include)
26. find_library()
- 查找库文件。
find_library(MY_LIB NAMES mylib PATHS /usr/lib /usr/local/lib)
27. find_path()
- 查找包含路径。
find_path(MY_INCLUDE_DIR NAMES myheader.h PATHS /usr/include /usr/local/include)
28. find_program()
- 查找可执行文件。
find_program(MY_PROGRAM NAMES myprogram PATHS /usr/bin /usr/local/bin)
29. include()
- 包含另一个 CMake 脚本。
include(AnotherCMakeScript.cmake)
30. enable_testing()
和 add_test()
- 启用测试和添加测试。
enable_testing()
add_test(NAME MyTest COMMAND MyExecutable --test)
31. ctest
- CMake 自带的测试工具,用于运行和管理测试。
32. target_include_directories()
- 为目标添加头文件目录。
target_include_directories(MyExecutable PRIVATE ${CMAKE_SOURCE_DIR}/include)
33. target_compile_definitions()
- 为目标添加编译定义。
target_compile_definitions(MyExecutable PRIVATE MY_DEFINE)
34. target_compile_options()
- 为目标添加编译选项。
target_compile_options(MyExecutable PRIVATE -Wall -Wextra)
35. target_sources()
- 为目标添加源文件。
target_sources(MyExecutable PRIVATE src/main.cpp)
36. try_compile()
- 尝试编译一段代码以检查编译器特性或库。
try_compile(COMPILE_RESULT ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/test.cpp)
37. try_run()
- 尝试编译和运行一段代码以检查运行时行为。
try_run(RUN_RESULT COMPILE_RESULT ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/test.cpp)
这些函数和命令可以帮助你构建更复杂和强大的 CMake 构建系统,根据项目需求进行组合使用,可以大大提高项目的构建和管理效率。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)