CMake:为每个项目设置编译选项和编译功能

2024-01-18

我有一个代码库(例如,存储库),其中包含多个软件组件(可执行文件、库)。所有内容都是使用 CMake 构建的,每个组件都有单独的目标。

现在,我知道设置编译器标志的现代方法是特定于目标的:

target_compile_options(foo PRIVATE -Werror -Wall -Wextra -pedantic)
target_compile_features(foo PRIVATE cxx_std_17)

但是,我希望整个项目中的所有目标都具有相同的标志。为每个目标编写这些行会导致代码重复并且容易出错(尤其是当标志数量增加时)。有没有某种方法可以将编译器标志附加到项目而不是目标?

我知道我可以向顶级目录添加选项,如下所示:

add_compile_options(-Werror -Wall -Wextra -pedantic)

但我不确定这是否是正确的方法,而且我也不确定如何对编译功能执行相同的操作(cxx_std_17).


现在,我知道设置编译器标志的现代方法是特定于目标的:

target_compile_options(foo PRIVATE -Werror -Wall -Wextra -pedantic)
target_compile_features(foo PRIVATE cxx_std_17)

这实际上不是最好/最现代的方式。如果您使用的是 CMake 3.19+,最好的办法是创建一个preset https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html.

创建一个名为CMakePresets.json在你的顶层旁边CMakeLists.txt包含以下内容:

{
  "version": 1,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 19,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "displayName": "Default",
      "description": "Default build using Ninja",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_CXX_FLAGS": "-Werror -Wall -Wextra -pedantic",
        "CMAKE_CXX_STANDARD": "17",
        "CMAKE_CXX_STANDARD_REQUIRED": "YES",
        "CMAKE_CXX_EXTENSIONS": "OFF"
      }
    }
  ]
}

然后配置:

$ cmake --preset=default

The reason以这种方式做事是因为(理想情况下)CMakeLists.txt 中不应该有任何不存在的内容绝对地构建您的项目所需的。警告标志不在该集合中,因此它们属于此处。否则,您会给最终用户带来潜在无效的标志。这在警告标志中非常常见。有些标志仅适用于 GCC 或 Clang,其他标志已被删除或重命名,还有一些标志的敏感性在各个版本之间发生了变化。如果您的用户手动添加-Werror via CMAKE_CXX_FLAGS如果您以其他方式添加标志,则可能会出现问题。

这确实意味着对于图书馆,通常适当设置cxx_std_NN via target_compile_features, where NN is the minimum兼容的 C++ 版本(不是首选版本,尽管它们可能一致)的库。这是因为该功能可以在INTERFACE(相当于。PUBLIC) 属性,以确保被链接者对库的标题使用足够新的版本。如果两者都CMAKE_CXX_STANDARD和编译功能已设置,将使用最大值。

在旧版本的 CMake 中,工具链文件 https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html可以用于同样的目的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake:为每个项目设置编译选项和编译功能 的相关文章

随机推荐

  • GHC 外部 hs_init/hs_add_root 崩溃

    不必要的我就不重复了 简单总结一下 继Adder本教程中的示例 http blogs msdn com b satnam singh archive 2011 04 19 creating a windows dll from a hask
  • Spring Boot 1.4.0:REST 控制器未将原因设置为 HTTP 响应

    我有 2 个使用 Spring Tool Suite Spring Starter Project 创建的项目 第一个项目 Spring Boot 1 3 7 发布 Web 第二个项目 Spring Boot 1 4 0 发布 Web 我更
  • 为什么 ConcurrentBag 不实现 ICollection

    我有一个方法需要IList
  • 使用 TinyXML 解析 XML 元素

    更新 仍然无法工作 我已经更新了代码部分以反映我当前拥有的内容 对于使用过 TinyXML 的人来说 这应该是一个相当简单的问题 我正在尝试使用 TinyXML 来解析 XML 文档并提取一些值 我昨天弄清楚了如何在库中添加 并且我已经成功
  • Ruby 1.9 中的自动加载是线程安全的吗?

    在我看来 自从 Ruby 社区开始对自动加载感到有点害怕这个著名的线程 http www ruby forum com topic 172385 出于线程安全原因不鼓励使用它 有谁知道这在 Ruby 1 9 1 或 1 9 2 中是否不再是
  • 使用 python 进行非线性回归 - 有什么简单的方法可以更好地拟合这些数据?

    我有一些想要拟合的数据 这样我就可以对给定特定温度的物理参数的值进行一些估计 我使用 numpy polyfit 作为二次模型 但拟合效果并不像我希望的那么好 而且我在回归方面没有太多经验 我已经包含了散点图和 numpy 提供的模型 S
  • MSVC++7.1 中的 ifstream.read() 与 ifstream.readsome()

    我只是采用了在 Linux 下开发的文件阅读器的一些旧代码 并尝试在使用 MSVC 7 1 编译的 Windows 项目中使用相同的代码 代码编译没有任何问题 但根据 Windows 上的文件阅读器 该文件似乎是空的 我跟踪问题到 ifst
  • Azure 流量管理器 SSL 设置(非经典)

    我有一个 Azure API 应用服务 我想为其配置 优先 流量管理 这是新的流量管理器 不是经典的 我已将该服务部署到两个独立的 Azure 区域 并配置了流量管理器实例以执行到两个服务实例的优先级路由 这些服务具有以下自定义域配置 fo
  • 在asp.net应用程序上显示sql数据库中存储的UTC时间的本地时间

    我已经将时间以 utc 格式保存在 SQL 数据库中 我在网格视图上显示这些时间 但它们仍然是 UTC 格式 我想将它们转换为客户端浏览器的本地时间 问题是 虽然我可以获得仅适用于当前日期 时间的时区偏移量 如果未来的某些日期最终发生在夏令
  • 如何在 Angular 2 最终版本中编写 HTTP 模拟单元测试?

    我已从 RC4 迁移到最终版本 2 1 0 并且正在重构我的单元测试以符合 2 1 0 语法 除了 HTTP 模拟之外 这很容易 我找不到任何关于如何在 2 1 0 中模拟 HTTP 请求的示例 这是一个 RC4 HTTP 单元测试 我将如
  • 使用 msbuild 从网站部署中排除文件

    我有一个使用 msbuild 部署的网站项目 在项目中 有一些构建所需的文件和文件夹 例如 web config 部分替换文件 但我不想将其部署到目标站点 我能想到的最好的办法是删除这些文件的构建后目标 但我想知道是否有办法让这些文件不复制
  • 由于占用率低而导致 GPU 利用率不足是什么意思?

    我正在使用 NUMBA 和 cupy 来执行 GPU 编码 现在我已将代码从 V100 NVIDIA 卡切换到 A100 但是随后我收到以下警告 NumbaPerformanceWarning 网格大小 27 NumbaPerformanc
  • VSCode Flutter Dart 慢的建议

    我使用 Visual Studio Code 进行 flutter 编程 并且没有使用很多扩展 我喜欢代码补全 但通常太慢 显示所有建议大约需要 1 2 秒 这个问题有什么解决办法吗 这是我已安装的扩展的列表 我被告知要添加此配置 dart
  • 什么是 WCF 服务参考 .datasource 文件?

    Visual Studio 中 创建服务引用 自动生成的 datasource 文件是什么 文件中的注释是这样的 该文件是自动生成的 由 Visual Studio Net 提供 这是 用于存储通用对象数据源配置信息 重命名文件扩展名或编辑
  • FormData 键作为数组

    我正在尝试使用 FormData html5 api 设置多个文件上传 问题是我无法删除 FormData 键上的数组索引 前任 if editor frmData editor frmData append upload files 0
  • IntelliJ Idea Android 项目包括 apk 中不受监管的文件

    我有一个复杂的应用程序结构 主项目有 android 库 它们有自己的 android 库和 jar 主要工程 Libs Android Lib project A Jars Android Lib项目B Jars 为了澄清起见 我有一个
  • 如何在 Sphinx 文档中显示类的继承成员?

    我想记录一些类 这些类都派生自具有一些公共属性的同一基类 并且我想重复子类中每个属性的文档 以便我可以在一个位置看到一个类的所有属性 例如我有这样的代码 class Base object Base class First attribut
  • 构建 .NET Core 控制台应用程序以输出 EXE

    对于面向 NET Core 1 0 的控制台应用程序项目 我无法弄清楚如何在构建期间输出 exe 该项目在调试中运行良好 我尝试过发布该项目 但这也不起作用 这是有道理的 因为 EXE 文件是特定于平台的 但必须有一种方法 我的搜索仅找到对
  • 如何检查设备是否需要 SafeArea? (需要底部/顶部填充)

    有没有一种方法可以检查运行该应用程序的设备是否需要 SafeArea 我需要根据这个 true 或 false 值运行代码 我不需要使用 SafeArea 小部件 如果设备需要填充 我所需要的只是正确或错误的答案 例如 像iPhone 8这
  • CMake:为每个项目设置编译选项和编译功能

    我有一个代码库 例如 存储库 其中包含多个软件组件 可执行文件 库 所有内容都是使用 CMake 构建的 每个组件都有单独的目标 现在 我知道设置编译器标志的现代方法是特定于目标的 target compile options foo PR