目录


一、速查手册

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_VERSIONcmake 主版本号
CMAKE_MINOR_VERSIONcmake 次版本号
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 构建系统,根据项目需求进行组合使用,可以大大提高项目的构建和管理效率。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐