CMake API使用指南

文章目录

  • CMake 的基本语法和用法
      • 1. CMakeLists.txt 基本结构
      • 2. 变量和宏
      • 3. 条件语句
      • 4. 循环语句
      • 5. 定义和使用函数
      • 6. 导入库和链接库
      • 7. 设置编译器选项
  • message
      • 1. 显示普通消息:
      • 2. 显示带模式的消息:
      • 3. 显示变量值:
      • 4. 显示多行消息:
      • 5. 显示条件消息:
  • set的常见用法
      • 1. 简单的变量定义:
      • 2. 定义列表变量:
      • 3. 引用变量的值:
      • 4. 添加到已有变量:
      • 5. 条件设置:
      • 6. 缓存变量:
  • file
      • 1. 复制文件
      • 2. 创建目录
      • 3. 移动文件
      • 4. 移除文件
      • 5. 读取文件内容
      • 6. 写入文件内容
  • add_library
      • 1. 添加静态库:
      • 2. 添加共享库:
      • 3. 添加模块库:
      • 4. 添加源文件到现有库:
  • target_sources
  • target_include_directories
  • target_link_libraries
      • 1. 链接到其他库:
      • 2. 链接到多个库:
      • 3. 链接到系统库:
      • 4. 链接到第三方库:
      • 5. 链接到其他目标:
      • 6. 指定链接选项:
  • PUBLIC关键字
  • 参考

CMake(Cross-platform Make,跨平台构建)是一个跨平台的构建工具,用于管理项目的构建过程。它使用简单的配置文件(CMakeLists.txt)来生成本地化的构建文件,如 Makefile 或 Visual Studio 解决方案。

以下是 CMake 的基本语法和用法:

CMake 的基本语法和用法

1. CMakeLists.txt 基本结构

一个简单的 CMakeLists.txt 文件通常包含以下基本结构:

# 最小版本要求
cmake_minimum_required(VERSION 3.10)# 项目名称
project(MyProject)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)# 添加可执行文件或库的源文件
add_executable(MyExecutable main.cpp)# 添加子目录,进入子目录继续构建
add_subdirectory(subdirectory_name)

2. 变量和宏

# 定义变量
set(SOURCES file1.cpp file2.cpp)# 使用变量
add_executable(MyExecutable ${SOURCES})# 定义宏
macro(my_macro arg1 arg2)# 宏体message("Arguments: ${arg1}, ${arg2}")
endmacro()# 使用宏
my_macro(value1 value2)

3. 条件语句

# 条件语句
if(CONDITION)# 条件成立时执行的命令
elseif(ANOTHER_CONDITION)# 另一个条件成立时执行的命令
else()# 如果所有条件都不成立时执行的命令
endif()

4. 循环语句

# 循环语句
foreach(item IN LISTS my_list)# 循环体message(${item})
endforeach()

5. 定义和使用函数

# 定义函数
function(my_function arg1 arg2)# 函数体message("Arguments: ${arg1}, ${arg2}")
endfunction()# 使用函数
my_function(value1 value2)

6. 导入库和链接库

# 导入库
find_library(MY_LIBRARY my_library)# 链接库
target_link_libraries(MyExecutable ${MY_LIBRARY})

7. 设置编译器选项

# 设置编译器选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")# 或者
add_compile_options(-Wall)

message

message 命令用于在 CMake 构建过程中输出信息。它对于调试和显示构建脚本中的信息非常有用。基本语法如下:

message([<mode>] "message to display" ...)

其中:

  • <mode> 是可选的,用于指定消息的模式,可以是 STATUSWARNINGAUTHOR_WARNINGSEND_ERRORFATAL_ERRORDEPRECATION。如果省略 <mode>,则默认为 STATUS
  • "message to display" 是要显示的消息字符串。

以下是一些 message 命令的使用示例:

1. 显示普通消息:

message("This is a normal message.")

2. 显示带模式的消息:

message(STATUS "This is a status message.")
message(WARNING "This is a warning message.")
message(SEND_ERROR "This is an error message.")
message(FATAL_ERROR "This is a fatal error message.")

3. 显示变量值:

set(my_variable "Hello, CMake!")
message("Value of my_variable: ${my_variable}")

4. 显示多行消息:

message(STATUS "This is a multi-line message.\n""It spans multiple lines.")

5. 显示条件消息:

if(MY_CONDITION)message("Condition is true.")
else()message("Condition is false.")
endif()

message 命令对于调试 CMakeLists.txt 文件和构建过程中的问题非常有帮助。通过在适当的位置添加消息,可以更容易地理解 CMake 脚本的执行过程,以及在构建时的一些关键信息。

set的常见用法

在 CMake 中,set 命令用于定义变量。这个命令的基本语法是:

set(variable_name value1 value2 ...)

其中,variable_name 是变量的名称,而 value1 value2 ... 是变量的值。可以通过空格分隔多个值。

以下是一些 set 命令的常见用法:

1. 简单的变量定义:

set(my_variable "Hello, CMake!")

2. 定义列表变量:

set(my_list_variable "item1" "item2" "item3")

3. 引用变量的值:

message("Value of my_variable: ${my_variable}")

4. 添加到已有变量:

set(my_variable "Hello")
set(my_variable "${my_variable}, CMake!")

5. 条件设置:

if(SOME_CONDITION)set(my_variable "Value1")
else()set(my_variable "Value2")
endif()

6. 缓存变量:

set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type (Debug/Release)" FORCE)

在这个例子中,CMAKE_BUILD_TYPE 是一个缓存变量,用于指定构建类型。FORCE 选项表示如果已经存在这个缓存变量,就覆盖它。

更多的使用场景和用法可以在CMake 官方文档中查看更详细的信息:

CMake - set Command。

file

在 CMake 中,file 命令用于操作文件系统。这个命令有多个子命令,用于执行不同的文件操作。以下是一些常见的 file 命令的用法:

1. 复制文件

file(COPY source_file DESTINATION destination_directory)

这个命令用于将文件从一个位置复制到另一个位置。例如:

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

2. 创建目录

file(MAKE_DIRECTORY directory_path)

这个命令用于创建目录。例如:

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/my_directory)

3. 移动文件

file(RENAME old_name new_name)

这个命令用于移动或重命名文件。例如:

file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/file.txt ${CMAKE_CURRENT_BINARY_DIR}/new_file.txt)

4. 移除文件

file(REMOVE [files...])

这个命令用于移除文件。例如:

file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/unnecessary_file.txt)

5. 读取文件内容

file(READ filename variable)

这个命令用于读取文件的内容并存储到一个变量中。例如:

file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version.txt VERSION)
message("Version: ${VERSION}")

6. 写入文件内容

file(WRITE filename content)

这个命令用于将指定的内容写入文件。例如:

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/output.txt "Hello, CMake!")

以上是 file 命令的一些常见用法,还有其他更多的子命令和选项,可以在 CMake 官方文档中查看更详细的信息:
CMake - file Command。

add_library

在 CMake 中,add_library 命令用于定义和构建一个库。这个命令的基本语法如下:

add_library(<library_name> [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL]source1 [source2 ...])

其中:

  • <library_name> 是库的名称,可以在后续的 target_link_libraries 命令中使用这个名称引用这个库。
  • [STATIC | SHARED | MODULE] 用于指定库的类型,可以是静态库(STATIC,默认),共享库(SHARED),或模块库(MODULE)。
  • [EXCLUDE_FROM_ALL] 是一个可选项,如果指定了,将把这个库从构建过程的默认目标中排除。

以下是一些 add_library 命令的用法示例:

1. 添加静态库:

add_library(my_static_lib STATIC source1.cpp source2.cpp)

2. 添加共享库:

add_library(my_shared_lib SHARED source1.cpp source2.cpp)

3. 添加模块库:

add_library(my_module_lib MODULE source1.cpp source2.cpp)

4. 添加源文件到现有库:

add_library(my_static_lib STATIC source1.cpp)
add_library(my_shared_lib SHARED source2.cpp)# 添加 source2.cpp 到 my_static_lib 和 my_shared_lib
target_sources(my_static_lib PRIVATE source2.cpp)
target_sources(my_shared_lib PRIVATE source2.cpp)

在上述示例中,my_static_libmy_shared_lib 是库的名称,source1.cppsource2.cpp 是库的源文件。

可以在 CMake 官方文档中查看更详细的信息:
CMake - add_library。

target_sources

target_sources 命令用于将源文件添加到一个已经存在的 CMake 目标(例如,可执行文件、库)。这个命令的基本语法如下:

target_sources(target_namePRIVATE source1 [source2 ...]PUBLIC source3 [source4 ...]INTERFACE source5 [source6 ...]
)
  • target_name 是目标的名称,可以是可执行文件或库的名称,由 add_executableadd_library 命令定义。
  • PRIVATE, PUBLIC, 和 INTERFACE 是关键字,用于指定添加源文件的属性。

PRIVATE, PUBLIC, 和 INTERFACE 关键字分别表示:

  • PRIVATE: 源文件只会在目标的编译和链接阶段中可见,不会传递给依赖此目标的其他目标。
  • PUBLIC: 源文件会在目标的编译和链接阶段中可见,并且会传递给依赖此目标的其他目标。
  • INTERFACE: 源文件不会被添加到目标的编译和链接阶段中,但会传递给依赖此目标的其他目标。

以下是一些 target_sources 命令的使用示例:

# 添加私有源文件到目标
target_sources(my_executable PRIVATE source1.cpp source2.cpp)# 添加公共源文件到目标
target_sources(my_library PUBLIC source3.cpp source4.cpp)# 添加接口源文件到目标
target_sources(my_interface_library INTERFACE source5.cpp source6.cpp)

在上述示例中,my_executablemy_library、和 my_interface_library 是目标的名称,source1.cppsource6.cpp 是源文件的名称。

target_sources 命令使得在 CMakeLists.txt 文件中添加源文件更加灵活,可以将源文件与目标关联起来,而不是直接将它们列在 add_executableadd_library 命令中。这样可以更容易地组织代码,并且在不同目标之间共享源文件。

target_include_directories

target_include_directories 用于向一个目标(例如可执行文件或库)添加头文件目录。这个命令的基本语法如下:

target_include_directories(target_name[SYSTEM] [BEFORE]INTERFACE|PUBLIC|PRIVATE[items1...][INTERFACE|PUBLIC|PRIVATE[items2]...]
)

其中:

  • target_name 是目标的名称,可以是可执行文件或库的名称,由 add_executableadd_library 命令定义。
  • SYSTEM 关键字用于将目录标记为系统目录,通常用于禁止特定编译器的警告。
  • BEFORE 关键字用于将目录添加到当前目录列表的前面,而不是后面。

INTERFACE, PUBLIC, 和 PRIVATE 关键字的含义与 target_sources 中的相同:

  • INTERFACE: 目录不会被添加到目标的编译和链接阶段中,但会传递给依赖此目标的其他目标。
  • PUBLIC: 目录会在目标的编译和链接阶段中可见,并会传递给依赖此目标的其他目标。
  • PRIVATE: 目录只会在目标的编译和链接阶段中可见,不会传递给依赖此目标的其他目标。

以下是一些 target_include_directories 命令的使用示例:

# 添加私有头文件目录到目标
target_include_directories(my_executable PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)# 添加公共头文件目录到目标
target_include_directories(my_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)# 添加接口头文件目录到目标
target_include_directories(my_interface_library INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)

在上述示例中,my_executablemy_librarymy_interface_library 是目标的名称,${CMAKE_CURRENT_SOURCE_DIR}/include 是头文件目录的路径。

target_include_directories 的主要目的是确保正确的头文件路径在编译和链接阶段中可用,并且能够传递给依赖此目标的其他目标。这有助于更好地组织项目中的头文件和确保正确的构建过程。

target_link_libraries

target_link_libraries 是 CMake 中的一个关键命令,用于指定一个目标(例如可执行文件或库)所依赖的其他库。这个命令的基本语法如下:

target_link_libraries(target_nameitem1item2...
)

其中:

  • target_name 是目标的名称,可以是可执行文件或库的名称,由 add_executableadd_library 命令定义。
  • item1, item2, … 是目标所依赖的其他库或库的名称。

以下是一些 target_link_libraries 命令的使用示例:

1. 链接到其他库:

# 链接到名为 my_library 的库
target_link_libraries(my_executable my_library)

2. 链接到多个库:

# 链接到名为 my_library1 和 my_library2 的库
target_link_libraries(my_executable my_library1 my_library2)

3. 链接到系统库:

# 链接到系统库,例如 pthread
target_link_libraries(my_executable pthread)

4. 链接到第三方库:

# 链接到第三方库,例如 Boost
target_link_libraries(my_executable Boost::filesystem)

5. 链接到其他目标:

# 链接到另一个目标
target_link_libraries(my_executable my_other_target)

6. 指定链接选项:

# 指定链接选项
target_link_libraries(my_executable PRIVATE -Wl,-rpath,/custom/library/path)

上述示例中,my_executable 是目标的名称,my_library, my_library1, my_library2, pthread, Boost::filesystem, my_other_target 是目标依赖的库或目标。

target_link_libraries 命令用于确保在链接目标时正确地包含所需的库。这对于确保可执行文件或库在构建和运行时都能正确链接到依赖项非常重要。

PUBLIC关键字

下面以target_link_libraries 为例,分析PUBLIC关键字。

target_link_libraries 命令中的 PUBLIC 关键字用于指定库的依赖关系,并将这些依赖关系传递给依赖于当前目标的其他目标。用于确保在链接时包含正确的依赖项。

基本语法如下:

target_link_libraries(target_namePUBLIC item1PUBLIC item2...
)

使用 PUBLIC 关键字的效果是,item1, item2, … 这些库将不仅会被链接到当前目标,还会传递给依赖于当前目标的其他目标。

示例:

# 定义一个库
add_library(my_library STATIC my_library.cpp)# 定义一个可执行文件,链接到 my_library
add_executable(my_executable main.cpp)
target_link_libraries(my_executable PUBLIC my_library)

示例中,my_executable 依赖于 my_library,而且 my_library 中的依赖项也会传递给 my_executable

使用 PUBLIC 关键字还允许在 INTERFACEPRIVATE 之间共享依赖关系。例如,PUBLIC 的依赖项既会被当前目标使用,也会被依赖于当前目标的其他目标使用。

参考

https://cmake.org/documentation/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/167143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ptpd2提示failed to join the multicast group (strerror: No buffer space available)

下载交叉编译ptpd-ptpd-2.3.1源码&#xff0c;在IMX6板子上面运行ptpd2提示错误如下&#xff1a; rootimx6qsabresd_genvict:~# ./ptpd2 -C -m -i eth0 2023-11-24 14:30:21.484399 ptpd2[6512].startup (info) (___) Configuration OK 2023-11-24 14:30:21.487152 ptpd2…

3ds Max 电脑配置建议 | 建模+渲染选专业显卡or游戏显卡?

&#xfeff;使用3ds Max进行建模和渲染时&#xff0c;选择合适的电脑配置非常重要。比如在硬件选择上&#xff0c;究竟选购游戏显卡还是专业显卡呢&#xff1f;本文将为你详细介绍游戏显卡和专业显卡的区别&#xff0c;并提供配置建议&#xff0c;助你作出明智的决策。 &#…

gcc编译优化

优化选项 -flto Whole Program Mode&#xff08;整个程序模式&#xff09;&#xff1a;在这种模式下&#xff0c;编译器对整个程序进行优化。它通过将所有源文件合并成一个单独的中间表示&#xff08;IR&#xff09;文件&#xff0c;然后进行全局的优化和代码生成。这种模式可…

手把手用GPT开发小程序全流程!就是这么easy~

大家好&#xff0c;我是五竹。 前段时间用GPT开发了一款小程序:GPT真牛批&#xff01;三天开发一个小程序&#xff0c;三天积累了2000的用户&#xff0c;上周末抽空又接入了流量主&#xff0c;感兴趣的同学可以围观一下。 今天就来带大家走一遍用GPT开发一款小程序的全过程&a…

为什么选择美国VPS服务器

企业、个人和组织都需要一个稳定高效的服务器来托管他们的网站、应用程序和数据。而对于中国用户来说&#xff0c;寻找一个性价比高的便宜美国VPS服务器&#xff0c;既能满足需求&#xff0c;又能节约成本&#xff0c;成为了一个非常重要的问题。 VPS即虚拟专用服务器&#xf…

Sulfo-Cy3-COOH荧光染料的合成和反应机制

Sulfo-Cy3-COOH**(源自星戈瑞的花菁染料)**荧光染料的合成通常涉及多个步骤&#xff0c;其中包括官能团的引入、染料核心的合成以及亲水性修饰等。 官能团引入&#xff1a; 合成Sulfo-Cy3-COOH的第一步通常是引入羧酸&#xff08;COOH&#xff09;官能团。这可以通过对已有的C…

C++算法 —— 贪心(3)

文章目录 1、买卖股票的最佳时机2、买卖股票的最佳时机Ⅱ3、K次取反后最大化的数组和4、按身高排序5、优势洗牌6、最长回文串7、增减字符串匹配 1、买卖股票的最佳时机 121. 买卖股票的最佳时机 这里最容易想到的就是暴力枚举&#xff0c;两层for循环&#xff0c;i 0&#xf…

RTMP直播应用与延时分析

直播应用中&#xff0c;RTMP和HLS基本上可以覆盖所有客户端观看&#xff0c; HLS主要是延时比较大&#xff0c;RTMP主要优势在于延时低。 一、应用场景 低延时应用场景包括&#xff1a; . 互动式直播&#xff1a;譬如2013年大行其道的美女主播&#xff0c;游戏直播等等各种…

TFA-Net

TFA SCA means ‘Self-Context Aggregation’ 作者未提供代码

一文讲明Mybatis 的使用 超详细 【爆肝两万字教程】

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; &#x1f383; 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 &#x1f3f7;️ 标签 | 男 自律狂人 目标明确 责任心强 ✈️公…

数据字典回显功能设计与实现

数据字典回显功能设计与实现 文章目录 数据字典回显功能设计与实现1. 业务场景2. 实现设计2.1 注解AOP切面2.2 注解mybatis拦截器2.3 注解序列化2.4 涉及字段直接申明成字典引用类型mybatis拦截器反序列化处理 3. 具体实现 1. 业务场景 我们日常开发中经常会遇到&#xff1a;数…

羊大师教你,什么搭配羊奶能够带来全方位的营养?

羊奶作为一种营养价值极高的乳制品&#xff0c;其丰富的营养成分对人体健康有着诸多益处。然而&#xff0c;不同的食物搭配会对羊奶的营养吸收产生不同的影响。为了让大家更好地利用羊奶的营养价值&#xff0c;下面小编羊大师将为大家介绍一些与羊奶搭配的食物&#xff0c;帮助…

Qt实现画的图片移动

要实现左键点击鼠标时图片跟着鼠标移动&#xff0c;可以通过以下步骤来实现&#xff1a;1. 在QGraphicsView的构造函数中设置鼠标跟踪属性&#xff0c;以便能够捕获鼠标事件。cpp QGraphicsView::QGraphicsView(QWidget *parent) : QGraphicsView(parent) {setMouseTracking(tr…

Leetcode617合并二叉树

理解题意&#xff1a;相同节点位置上&#xff0c;都有数据的话&#xff0c;节点值相加&#xff0c;只有一方有数据的话&#xff0c;把有数据的部分及相关子树保留下来。 考察操作两棵二叉树&#xff0c;二叉树的遍历。 一般有两种解决方式&#xff1a; 递归|迭代。 区别&#x…

element 中文地址

Element - The worlds most popular Vue UI framework 2 Menu 菜单 | Element Plus 3 侦听器 | Vue.js vue中文官网

软件测试职业规划导图

公司开发的产品专业性较强&#xff0c;软件测试人员需要有很强的专业知识&#xff0c;现在软件测试人员发展出现了一种测试管理者不愿意看到的景象&#xff1a; 1、开发技术较强的软件测试人员转向了软件开发(非测试工具开发)&#xff1b; 2、业务能力较强的测试人员转向了软件…

ubuntu创建新用户, 并赋予root权限

在Ubuntu上创建新用户可以通过adduser命令来完成。以下是创建新用户的基本步骤&#xff1a; 打开终端&#xff1a;你可以按下Ctrl Alt T来打开终端。 使用sudo命令以管理员权限执行adduser命令。例如&#xff0c;如果你要创建一个名为newuser的新用户&#xff0c;运行以下命…

【EI会议征稿】第三届电子信息技术国际学术会议(EIT 2024)

The 3rd International Conference on Electronic Information Technology 第三届电子信息技术国际学术会议&#xff08;EIT 2024&#xff09; 电子信息工程在我国信息化产业的发展过程中举足轻重&#xff0c;且随着现代社会的发展&#xff0c;航空航天领域、制造业领域和智能…

LSTM+CNN实现时间序列预测(负荷预测)

文章目录 LSTM+CNN实现时间序列预测(PyTorch版)基于PyTorch搭建LSTM+CNN模型实现风速时间序列预测配置类时序数据集的制作数据归一化数据集加载器搭建LSTM+CNN模型定义模型、损失函数、优化器模型训练可视化结果十、完整源码LSTM+CNN实现时间序列预测(Keras版)源码模型训练绘制…