【Cmake 增加编译参数 】cmake增加编译参数和预处理指令的几种方法

简介: 【Cmake 增加编译参数 】cmake增加编译参数和预处理指令的几种方法

简述几种方法

CMake是一个跨平台的构建系统,它允许开发者编写一种简单的文件来描述所有平台的构建过程。在CMake中,你可以通过以下方式增加编译参数和预处理指令:

  1. 添加编译参数:
  • 使用add_compile_options命令。这个命令将添加到所有的目标上。例如:
add_compile_options(-Wall)
  • 使用target_compile_options命令。这个命令只会添加到指定的目标上。例如:
target_compile_options(target PRIVATE -Wall)
  • set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ...")是另一种常见的添加编译参数的方法。这种方法直接修改了CMake的全局变量,所以它会影响到所有的目标。
    例如,如果你想添加-Wall编译选项,你可以这样写:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
  • 这行代码的意思是,将-Wall添加到CMAKE_CXX_FLAGS变量中。CMAKE_CXX_FLAGS变量包含了C++编译器的编译选项。
    同样的,对于C编译器,你可以使用CMAKE_C_FLAGS
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
  • 这种方法的一个缺点是,它会影响到所有的目标,而不仅仅是一个特定的目标。如果你只想为一个特定的目标添加编译选项,你应该使用target_compile_options命令。
  1. 添加预处理指令:
  • 使用add_definitions命令。这个命令将添加到所有的目标上。例如:
add_definitions(-DDEBUG)
  • 使用target_compile_definitions命令。这个命令只会添加到指定的目标上。例如:
target_compile_definitions(target PRIVATE DEBUG)
  1. 在上述两个例子中,DEBUG是一个预处理指令,它会在编译时被定义。

注意,PRIVATEPUBLICINTERFACE这些关键字的含义:

  • PRIVATE:只有目标自己会使用这些编译参数。
  • PUBLIC:目标自己和其他依赖这个目标的目标都会使用这些编译参数。
  • INTERFACE:只有其他依赖这个目标的目标会使用这些编译参数。

以上就是在CMake中增加编译参数和预处理指令的所有方法。

add_definitions 解析

根据CMake官方文档,add_definitions命令用于向源文件的编译中添加-D定义标志。这个命令可以用来添加任何标志,但它主要是用来添加预处理器定义的。

例如,add_definitions(-DFOO -DBAR ...)会将定义添加到当前目录中的目标的编译器命令行,无论这个命令是在添加目标之前还是之后调用的,以及在此命令调用后添加的子目录中的目标。

然而,这个命令已经被以下的替代方法取代:

  • 使用add_compile_definitions()来添加预处理器定义。
  • 使用include_directories()来添加包含目录。
  • 使用add_compile_options()来添加其他选项。

以-D或/D开头的标志,看起来像预处理器定义的,会自动添加到当前目录的COMPILE_DEFINITIONS目录属性中。具有非平凡值的定义可能会保留在标志集中,而不是被转换,这是出于向后兼容性的考虑。

因此,你的说法是正确的,add_definitions命令可以用于添加编译器标志,但这并不是它的主要用途,而且在某些情况下可能会导致问题。对于编译器标志,如-Wall和-g,更推荐使用add_compile_options()命令。

add_compile_options 解析

add_compile_options命令用于向源文件的编译中添加选项。这些选项会被添加到COMPILE_OPTIONS目录属性中,这些选项在编译当前目录及其子目录中的目标时会被使用。需要注意的是,这些选项在链接时不会被使用,链接时的选项需要使用add_link_options()命令来添加。

add_compile_options命令的参数可以使用生成器表达式,最终用于目标的选项集是通过从当前目标和其依赖项的使用要求中累积选项来构造的,选项集会进行去重以避免重复。

例如,你可以在特定的编译器条件下使用这个命令:

if (MSVC)
 # warning level 4
 add_compile_options(/W4)
else()
 # additional warnings
 add_compile_options(-Wall -Wextra -Wpedantic)
endif()

如果你想要为特定的目标添加编译选项,你应该使用target_compile_options命令。例如,如果你有一个目标叫做my_target,你可以这样为它添加编译选项:

target_compile_options(my_target PRIVATE -Wall -Wextra -Wpedantic)

在这个例子中,-Wall -Wextra -Wpedantic这些编译选项只会被添加到my_target这个目标,而不会影响到其他的目标。

不同用法 的 区别

CMAKE_<LANG>_FLAGS是用于所有配置时构建语言的全局标志。这些标志将被传递给编译器的所有调用,包括驱动编译和驱动链接的调用。

对于每种语言,如果这个变量没有被定义,它会使用环境变量和CMake的工具链内置默认值进行初始化并存储在缓存中。例如,CMAKE_CXX_FLAGS会被CXXFLAGS环境变量初始化。

这个值是一个命令行字符串片段,因此,多个选项应该由空格分隔,带有空格的选项应该被引用。

这个变量中的标志将在每个配置的CMAKE_<LANG>_FLAGS_<CONFIG>变量中的标志之前被传递。在驱动编译的调用中,这两个变量中的标志都会在add_compile_options()target_compile_options()等命令添加的标志之前被传递。在驱动链接的调用中,它们会在add_link_options()target_link_options()等命令添加的标志之前被传递。

因此,add_compile_optionsset(CMAKE_CXX_FLAGS ...)都可以用来添加编译选项,但是它们的使用场景和影响范围是不同的。add_compile_options更加灵活,可以在特定条件下添加选项,而set(CMAKE_CXX_FLAGS ...)则是全局设置,会影响所有的目标。这两个命令可以同时使用,它们的效果是累积的,不会互相覆盖。

结语

在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。

这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。

我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。

目录
相关文章
|
自然语言处理 安全 C++
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
9318 4
|
设计模式 编译器 API
【C/C++ Pimpl模式】隐藏实现细节的高效方式 (Pimpl Idiom: An Efficient Way to Hide Implementation Details)
【C/C++ Pimpl模式】隐藏实现细节的高效方式 (Pimpl Idiom: An Efficient Way to Hide Implementation Details)
1589 1
|
编解码 Linux Android开发
安卓投屏神器 Scrcpy 安装与使用(支持 Mac、Windows、Linux)
安卓投屏神器 Scrcpy 安装与使用(支持 Mac、Windows、Linux)
43908 1
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
636 0
|
IDE 数据可视化 Java
5款经典代码阅读器的使用方案对比
代码阅读是技术人的必备技能之一,高效地梳理代码能够极大程度上提高开发人员的工作效率,进一步为业务创造新价值。
12925 0
5款经典代码阅读器的使用方案对比
|
10月前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
11791 46
|
Unix 编译器 开发工具
Cmake 命令行参数:探索 Cmake 的设置和配置选项
Cmake 命令行参数:探索 Cmake 的设置和配置选项
2216 1
|
11月前
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
5026 6
|
Web App开发
如何设置谷歌浏览器在新窗口中打开链接?如何设置谷歌浏览器在新标签页中打开链接?
一、快捷键方式:  1、左键单击 ==》 在当前窗口中打开目标网页。  2、Shift + 左键单击 ==》 在新窗口中打开目标网页。  3、Ctrl + 左键单击 ==》 在新标签页中打开目标网页。  4、鼠标中键点击书签即打开新的标签页,在新的标签页中显示指定的网页。
59246 0
|
算法 编译器 C语言
【CMake install 命令】精通CMake安装:灵活、高效的构建和部署
【CMake install 命令】精通CMake安装:灵活、高效的构建和部署
3216 0