更改 CMAKE_CXX_FLAGS_DEBUG 和 CMake 中朋友的默认值

2023-11-25

我想更改默认值CMAKE_CXX_FLAGS_RELEASE or CMAKE_CXX_FLAGS_DEBUG在 CMake 中。基本上,我有一些项目默认值与 CMake 的默认值略有不同(例如,对于发布),我不应该问自己“哦,当使用 add_compile_options 添加时,他们的 -O3 还是我们的 -O2 优先。”

现在,我知道如何设置这些值,但我不知道如何使用户可以通过两种常用方式编辑它们:通过使用 -DCMAKE_CXX_FLAGS_DEBUG=yourflags在命令行上或通过使用 ccmake 或 CMakeSetup 进行配置。

问题在于 CMAKE 设置并缓存其自己的默认值,如果您尝试在不使用 FORCE 的情况下覆盖变量,则“默认值”永远不会更改。如果我在 set 命令中使用 FORCE:set(CMAKE_CXX_FLAGS_DEBUG blah CACHE STRING "" FORCE),每次运行脚本时它都会覆盖它,从而消除了用户根据需要更改它的可能性。

我设法通过执行以下操作来破解它以与 CCMAKE 一起使用,但这仍然不起作用cmake -DCMAKE_CXX_FLAGS_DEBUG因为它会在完成后覆盖用户更改:

set(DEFAULTS_SET FALSE CACHE BOOL "")
set(CMAKE_CXX_FLAGS_DEBUG "-this -that" CACHE STRING "" FORCE)
set(DEFAULTS_SET TRUE CACHE BOOL "" FORCE)

显然,这是一个令人讨厌的黑客行为,并且不能完全起作用(在 cmake -Dwhatever=thisorthat 的情况下)。我也可以添加其他构建类型,但我真的不明白为什么仅仅为了改变一些简单的事情就需要这样做。

2015年3月1日编辑:

我已经创建了一个有效的解决方案,尽管我仍然对我必须做的事情不太兴奋。我看过其他解决设置问题的评论CMAKE_CXX_FLAGS_DEBUG和朋友,而不让它们被破坏,但这最初对我不起作用,因为我试图根据正在使用的编译器来选择它们。然而,编译器直到它已经为我填充了变量才确定。我使用的技巧如下。您必须在项目命令之前将标志变量设置为“特殊”。

set(CMAKE_CXX_FLAGS_DEBUG "_UNSET" CACHE STRING "")
project(your_project C CXX)

if(${CMAKE_CXX_FLAGS_DEBUG} STREQUAL "_UNSET")
    # Do some compiler switching here and then set your flags with FORCE.
    set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "" FORCE)
endif()

现在,我可以选择通过命令行使用 -D 或在 cmake-gui 中完全覆盖的默认值。


我只是想添加我看到的四种可能性:

  1. 拥有自己的工具链文件,其中包含您支持的每个编译器的预设,例如:

    GNU工具链.cmake

     set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "")
    

    然后使用它

     cmake -DCMAKE_TOOLCHAIN_FILE:string=GNUToolchain.cmake ...
    
  2. 您可以尝试通过检查来确定编译器CMAKE_GENERATOR(在之前有效project()命令):

    CMakeLists.txt

     if("${CMAKE_GENERATOR}" MATCHES "Makefiles" OR 
        ("${CMAKE_GENERATOR}" MATCHES "Ninja" AND NOT WIN32))
         set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "")
     endif()
    
     project(your_project C CXX)
    
  3. 您可以使用CMAKE_USER_MAKE_RULES_OVERRIDE给你自己的脚本..._INIT values:

    它在 CMake 的内置编译器和平台信息模块加载之后但在使用信息之前加载。该文件可以设置平台信息变量来覆盖 CMake 的默认值。

    MyInitFlags.cmake

     # Overwrite the init values choosen by CMake
     if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
         set(CMAKE_CXX_FLAGS_DEBUG_INIT "-ggdb3 -O0")
     endif()
    

    CMakeLists.txt

     set(CMAKE_USER_MAKE_RULES_OVERRIDE "MyInitFlags.cmake")
    
     project(your_project C CXX)
    
  4. 从 3 月 1 日起,您可以通过检查来简化您的解决方案..._INIT编译器标志变量的变体:

    CMakeLists.txt

     project(your_project C CXX)
    
     if (DEFINED CMAKE_CXX_FLAGS_DEBUG_INIT AND  
         "${CMAKE_CXX_FLAGS_DEBUG_INIT}" STREQUAL "${CMAKE_CXX_FLAGS_DEBUG}")
         # Overwrite the init values choosen by CMake
         if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
             set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "" FORCE)
         endif()
     endif()
    

Comments:

我更喜欢并使用工具链变体。但我承认它的缺点是必须手动提供工具链文件(如果您不调用cmake通过脚本/批处理文件)。

参考:

  • CMake:文件按什么顺序解析(缓存、工具链等)?
  • cmake - 全局链接器标志设置(对于目录中的所有目标)
  • 使用 CMake 在 GCC 和 Clang/LLVM 之间切换
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 CMAKE_CXX_FLAGS_DEBUG 和 CMake 中朋友的默认值 的相关文章

  • boost::asio + std::future - 关闭套接字后访问冲突

    我正在编写一个简单的 TCP 客户端来发送和接收单行文本 异步操作由 std future 处理 以便于超时阻塞查询 不幸的是 我的测试应用程序在破坏服务器对象时因访问冲突而崩溃 这是我的代码 TCP客户端 hpp ifndef TCPCL
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 将内置类型转换为向量

    我的 TcpClient 类接受vector
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • 在 Unity 进程和另一个 C# 进程之间进行本地 IPC 的最快方法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我希望每秒大约 30 次从 C 应用程序向我的 Unity 应用程序传送大量数据 由于 Unity 不支持映射内存和管道 我考虑了 t
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何使用 Mongodb C# 驱动程序连接多个集合

    我需要将 3 个集合与多个集合合并在一起 lookup我在 C 驱动程序中尝试过 它允许我 lookup用户采集但无法执行秒 lookup用于设置集合 有人可以帮忙吗 db Transactions aggregate lookup fro
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐

  • 如何利用转义来防止XSS攻击?

    为了防止XSS攻击 输出 已启用转义 上面来自symfony 但我不明白 XSS 是 跨站脚本 的缩写 当您设法将脚本 通常是 javascript 偷偷溜到其他人的网站上并在那里恶意运行时 就会发生跨站点脚本攻击 当用户向网站输入内容时
  • 这个 Dictionary 异常怎么可能?

    给出以下堆栈跟踪 MESSAGE Value cannot be null Parameter name key SOURCE mscorlib TARGETSITE Void ThrowArgumentNullException Syst
  • 如何在 Flutter 中使用 Firebase 更改密码

    我想在 Flutter 中使用 Firebase 更改当前用户密码 任何人都可以帮助我如何实施更改密码方法吗 我知道这是一篇迟到的文章 但现在可以更改登录用户的密码 请务必通知用户重新登录 因为这是敏感操作 void changePassw
  • urlopen 返回有效链接的重定向错误

    我正在用 python 构建一个损坏的链接检查器 构建正确识别使用浏览器访问时无法解析的链接的逻辑变得很繁琐 我找到了一组链接 我可以在这些链接中始终使用抓取工具重现重定向错误 但在浏览器中访问时可以完美解决 我希望我能在这里找到一些见解
  • 为什么我无法与 GTX 480 和 CUDA 5 重叠数据传输和计算?

    我尝试将内核执行与 memcpyasync 重叠 但它不起作用 我遵循编程指南中的所有建议 使用固定内存 不同的流等 我看到内核执行确实重叠 但与内存传输无关 我知道我的卡只有一个复制引擎和一个执行引擎 但是执行和传输应该重叠 对吧 看来
  • 使用 VBA 将单元格格式化为任意货币,无论区域设置如何

    这真的让我很烦恼 因为它的工作方式似乎很不合逻辑 我有一个宏 可以使用一些代码将单元格格式化为货币来获取货币符号 这是涉及的代码 Dim sym As String sym reportConstants ISOcode Just use
  • 更改窗户的 Aero 玻璃颜色?

    我在用着DwmExtendFrameIntoClientArea在我的 WPF 应用程序中获得玻璃效果 这工作正常 我想做的是改变玻璃使用的颜色 我正在编写一个倒计时器 我希望窗口在大多数情况下都是正常的玻璃颜色 然后变成红色 但是仍然有玻
  • 如何在NotificationCompat.Builder.setLargeIcon()中加载Glide缓存图像?

    喜欢这张图片我正在尝试将通知大图标设置为用户个人资料缩略图 像 Whatsapp 或其他聊天应用程序 我努力了 Glide with context asBitmap load messageNotification getLargeIco
  • Swift 视频调整器 AVAsset

    我有这段代码可以将视频大小从 1280 x 720 调整为 640 x 360 但我想要调整大小而不裁剪 有没有办法完全调整大小而不裁剪 这是代码 class func resizer inputURL NSURL completion o
  • babel-preset-env 不使用 webpack 转译箭头函数

    我正在将 babel 与 webpack 一起使用 我试图使箭头函数与 Internet Explorer 一起使用 但我无法让它工作 这是我的包 json开发依赖 devDependencies babel core 6 26 3 bab
  • Android - 如何管理具有不同内容的单个片段的多个实例?

    我希望能够设置各个片段的视图的 setText 和 getText 就像现在一样 当我设置 Framgent 的 TextView 的文本时 它会更改所有片段中该视图的文本 我一直在尝试移动东西 但这是我目前的代码 片段类 public c
  • Python WX - 从 wx 对话框返回用户输入

    我是 Python 和 WX 的新手 我创建了一个简单的测试对话框 如下所示 用组合框提示用户 我想从主程序中的组合框中捕获值 我如何从我的主程序中调用它 这就是我打算如何调用它来显示对话框 但当前不捕获组合框中的值 import high
  • ArgumentParser:具有可选值的可选参数

    如果我有一个带有可选参数值的可选参数 有没有办法在未给出值时验证该参数是否已设置 例如 parser argparse ArgumentParser parser add argument abc nargs args parser par
  • OpenERP 始终显示继承视图而不是原始视图

    原始观点
  • SQL Server - 由于“ARITHABORT”而导致 INSERT 失败

    我使用 NHibernate 和 SQL Server 2005 并且在我的一张表的计算列上有一个索引 我的问题是 当我向该表插入一条记录时 出现以下错误 INSERT 失败 因为以下 SET 选项设置不正确 ARITHABORT I us
  • 从数据框中删除仅包含 0 或仅包含单个 0 的行

    我正在尝试在 R 中创建一个函数 该函数允许我根据行是否包含带有零的单列来过滤数据集 此外 有时我只想删除所有列中为零的行 另外 这就是有趣的地方 并非所有列都包含数字 并且列数可能会有所不同 我尝试将一些数据与我想要获得的结果粘贴到此处
  • 如何编写程序来查找某些单词是否相似?

    即 学院 和 学业 和 学院 属于同一集群 essay scholarships money 这些词也属于同一簇 这是 ML 或 NLP 问题吗 这取决于你的定义有多严格similar is 机器学习技术 As others已经指出 你可以
  • 如何在 laravel dompdf 中为每页添加页码?

    我从这里得到 https github com barryvdh laravel dompdf 我的控制器是这样的 public function listdata pdf PDF loadView print tests test pdf
  • 如何正确关闭数据源连接?

    我有这个类 但我不确定如何正确关闭连接 因为即使我只有 3 个用户登录但有多个 sql 查询 我仍然遇到此错误 gt com mysql jdbc exceptions jdbc4 MySQLNonTransientConnectionEx
  • 更改 CMAKE_CXX_FLAGS_DEBUG 和 CMake 中朋友的默认值

    我想更改默认值CMAKE CXX FLAGS RELEASE or CMAKE CXX FLAGS DEBUG在 CMake 中 基本上 我有一些项目默认值与 CMake 的默认值略有不同 例如 对于发布 我不应该问自己 哦 当使用 add