CMake 行为:使用 Visual Studio 的自定义配置类型需要多次运行 cmake 才能正确显示。这是故意的吗?

2024-02-27

Context:

我正在将一个项目从普通 Makefile 迁移到 CMake,以添加对多个编译器 (gfortran + ifort) 和操作系统 (Windows + Linux) 的支持。当我完成整个事情时,我正在尝试简化 CMake 行为并为用户提供一些额外的功能。

在跨操作系统和使用的编译器的可能组合规范和调整编译器选项之后,添加用户定义的构建类型“DEBUGVERBOSE”并启用所有检查和警告似乎是合理的。因为我们正在处理非常旧的旧版 Fortran 77 代码,所以这些设置会生成 >3000 个警告,这就是为什么我不想在标准调试构建类型中包含所有警告。对于未来的代码清理和调试来说,这似乎是合适的。


Issue:

我想将这个用户定义的构建类型“DEBUGVERBOSE”添加到 Visual Studio 2012 中的可用配置列表中。同时我想摆脱 cmake 生成的构建类型“MinSizeRel”和“RelWithDebInfo”以简化用户界面(因为我们从不使用这些配置)。

根据CMake-Wiki - 如何使用定制模式扩展构建模式? http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_specify_my_own_configurations_.28for_generators_that_allow_it.29_.3F我设置构建类型如下:

# Set Project Name and supported Languages(optional)
project (s4 Fortran C)
# Set Version Number
set (S4_VERSION_MAJOR 1)
set (s4_VERSION_MINOR 0)

# Set Source Language
enable_language (Fortran)

...

if(WIN32)
  # Release flags
  set(CMAKE_Fortran_FLAGS_RELEASE " ${CMAKE_Fortran_FLAGS_RELEASE} /D__WIN_intel__ /assume:byterecl")
  # Debug Flags
  set(CMAKE_Fortran_FLAGS_DEBUG " ${CMAKE_Fortran_FLAGS_DEBUG} /D__WIN_intel__ /assume:byterecl /Od /warn:all /check:all
                                                              /warn:notruncated_source /warn:nodeclarations /warn:nounused") 
  # verbose Debug flags (user-defined build type)
  set(CMAKE_Fortran_FLAGS_DEBUGVERBOSE  " /debug:full /dbglibs /D__WIN_intel__ /assume:byterecl /Od /warn:all /check:all"
                                      CACHE STRING  "Extended Debug Flags used by the Fortran compiler during verbose Debug builds.") 
  set(CMAKE_CXX_FLAGS_DEBUGVERBOSE      " ${CMAKE_CXX_FLAGS_DEBUG}"
                                      CACHE STRING "Flags used by the C++ compiler during verbose Debug builds."  FORCE )
  set(CMAKE_C_FLAGS_DEBUGVERBOSE        " ${CMAKE_C_FLAGS_DEBUG}"
                                      CACHE STRING "Flags used by the C compiler during verbose Debug builds."    FORCE )
  set(CMAKE_EXE_LINKER_FLAGS_DEBUGVERBOSE "${CMAKE_EXE_LINKER_FLAGS_DEBUG}"
                                      CACHE STRING "Flags used for linking binaries during verbose Debug builds." FORCE )
  set(CMAKE_SHARED_LINKER_FLAGS_DEBUGVERBOSE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}"
                                      CACHE STRING "Flags used by the shared libraries linker during verbose Debug builds." FORCE )
elseif(UNIX)
   ...<definition of Release, Debug, DebugVerbose Compiler Options>
endif()

# Edit available Configrations to make them available in IDE that support multiple-configuration (for example Visual Studio)
if(CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_CONFIGURATION_TYPES Release, Debug, Debugverbose)
  set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
      "Reset the configurations to what we need" FORCE)
endif()

...<definition of lots of source files and build targets>...

# Visual Studio Userfile (set the debugging environment):
CreateUserfile()

这会在第一次 cmake-configure +generate 运行时设置(根据 cmake-gui 和 CMakeCache.txt)相应的变量。但直到第二次 cmake-configure + 生成之后,它们才会显示在 Visual Studio 解决方案中。我还在命令行中对此进行了测试,并且还需要运行两次才能将设置输入 Visual Studio。

这种行为似乎也存在于较旧的 cmake 和 Visual Studio 版本中,如中所示这个答案 https://stackoverflow.com/a/6562390/2969529 to “如何使用 CMake 创建新配置” https://stackoverflow.com/questions/4212945/how-to-create-a-new-configuration-with-cmake。这也会导致 cmake 错误报告0005811:为 MSVC 创建新配置 http://www.cmake.org/Bug/view.php?id=5811这可能是造成这种行为的原因。

我们使用的所有其他生成器(代码:Blocks + MinGW;UNIX Makefiles)都没有这种行为,并且可以在第一次运行时完成工作。我知道 Visual Studio 很特别,因为它是我们设置中唯一的多配置 IDE,但我通常不赞成不一致的行为,因为它会让用户感到困惑。


问题:

我的方法有什么问题吗,或者这个 cmake 行为(->需要多次运行)是有意的/目前不可更改吗?



目前的解决方法:

我找到了一个解决方法 -here http://www.cmake.org/pipermail/cmake/2012-January/048856.html- 我只将用户定义的构建类型附加到已有的配置中。请注意设置“​​项目”和“语言”之间“CMAKE_CONFIGURATION_TYPES”if 语句的位置!

# Set Project Name and supported Languages(optional)
project (s4 Fortran C)
# Set Version Number
set (S4_VERSION_MAJOR 1)
set (s4_VERSION_MINOR 0)

# Edit available Configrations to make them available in IDE that support multiple-configuration (for example Visual Studio)
if(CMAKE_CONFIGURATION_TYPES)
 set(CMAKE_CONFIGURATION_TYPES Debugverbose)
 set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
     "Append user-defined configuration to list of configurations to make it usable in Visual Studio" FORCE)
endif()

# Set Source Language
enable_language (Fortran)

...

if(WIN32)
  ...<definition of Release, Debug, DebugVerbose Compiler Options>
elseif(UNIX)
  ...<definition of Release, Debug, DebugVerbose Compiler Options>
endif

...<definition of lots of source files and build targets>...

# Visual Studio Userfile (set the debugging environment):
CreateUserfile()

使用此解决方案,“DEBUGVERBOSE”配置会在第一次 cmake-configure +generate 运行后添加到现有配置中,并且还会显示在 Visual Studio 中。但似乎不可能更改配置列表以忽略 cmake 生成的构建类型“MinSizeRel”和“RelWithDebInfo”(即使在多次 cmake 运行之后)。

随着上述帖子 http://www.cmake.org/pipermail/cmake/2012-January/048856.html来自 cmake 讨论组,是否可以改进我的解决方法,以便 Visual Studio 中仅存在配置“Release、Debug、DebugVerbose”?



EDIT :


正如彼得在this https://stackoverflow.com/a/21285845/2969529回答我的实现中有一个错误。遗憾的是,修复此问题并没有改变 Visual Studio 2012 的行为。

# Set Project Name and supported Languages(optional)
project (s4)

...

# Set Source Language
enable_language (Fortran C)

...

我在此修改中遇到的唯一区别是在将新的 CMakeCache.txt 与前一个进行比较时:CMake 添加了“CXX”的编译器标志。我认为这意味着 C++、C# 等编译器标志?

从此构建并重读之后相应的帖子 http://www.cmake.org/pipermail/cmake/2012-January/048856.html我从 cmake 讨论组开始进行实验。使用 PROJECT、enable_language 和 CMAKE_CONFIGURATION_TYPES 位置的几种组合进行测试,我想分享我的发现。

  1. CMAKE_CONFIGURATION_TYPESafter项目(s4 Fortran C),例如省略启用语言:
    如果没有启用语言,代码需要 2 次 CMake 传递才能使 Visual Studio 识别新设置,同时使用第一次传递更新缓存。因此,enable_language 似乎将设置传播到 Visual Studio *.sln 文件。

  2. CMAKE_CONFIGURATION_TYPESbefore项目(s4)声明:
    需要第二次 cmake 传递才能将设置传播到 CMakeCache.txt。但 Visual Studio 无法识别这些设置。通过此设置,似乎可以更改可用的构建类型,但由于 Visual Studio 无法识别它们,并且需要第二次 cmake 传递来传播它们,因此此选项对于我的情况不可行。

  3. CMAKE_CONFIGURATION_TYPESbetween项目(s4)和enable_language(Fortran C):
    CMakeCache.txt 和 Visual Studio 中的第一遍都会识别这些设置。后续的 cmake 传递不会更改缓存。因此我认为这个方法足够了。

但删除某些构建类型或重写 CMAKE_CONFIGURATION_TYPES 似乎是不可能的。我测试了上述讨论组的建议,例如使用 LIST(APPEND ...) 显式附加新的构建类型并检查/删除重复项。看来这些措施是在配置例程中隐式实现的,因为添加(或省略)这些措施并没有改变行为或缓存文件(无论是使用语句 LIST(APPEND ...) 还是 SET(...) )。

我注意到的另一个行为是用户定义的字符串

   set(CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES}
                                 CACHE STRING "Append user-defined configuration to list of configurations to make it usable in Visual Studio" FORCE)

仅在第 2 种情况下被认可。使用 3. Case 它似乎被忽略,并且标准 CMake 字符串似乎在缓存中设置。


RESULT :

根据这些发现,可以得出当前已实施的代码。

# Set Project Name
project (s4)
# Set Version Number
set (S4_VERSION_MAJOR 1)
set (s4_VERSION_MINOR 0)

# Edit available Configrations to make them available in IDE that support multiple-configuration (for example Visual Studio)
# has to be between "project" and "enable_language" to work as intended!
if(CMAKE_CONFIGURATION_TYPES)
   list(APPEND CMAKE_CONFIGURATION_TYPES Debugverbose)
   set(CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES}
                                 CACHE STRING"Append user-defined configuration to list of configurations to make it usable in Visual Studio" FORCE)
endif()

# Set Source Language
enable_language (Fortran C)

...

我采用了 LIST(APPEND ...) 语句,因为它提高了可读性并明确说明了代码正在做什么。如上所述,它不会改变 CMake 的行为,例如自动检查重复项。


开放性问题:

我的实验结论有错误吗?也许有人足够了解内部 CMake 程序来详细说明上述行为?例如,为什么 set(CMAKE_CONFIGURATION_TYPES ...) 语句中的字符串无法识别?

原来的问题仍然存在:

有没有办法将 CMAKE_CONFIGURATION_TYPES 重置为用户定义的列表,并将这些设置传递到缓存和 Visual Studio,只需 1 个 CMake 传递?


在你提到的帖子中cmake-讨论 http://www.cmake.org/pipermail/cmake/2012-January/048856.html,据说你应该

  • 在 PROJECT() 之前设置 CMAKE_CONFIGURATION_TYPES
  • 在 PROJECT() 之后附加到 CMAKE_CONFIGURATION_TYPES -无需语言调用- 但在 ENABLE_LANGUAGE() 之前

在您的解决方法中,您可以在 CMAKE_CONFIGURATION_TYPES 之前设置语言:

project (s4 Fortran C)

最好的方法是将 CMAKE_CONFIGURATION_TYPES 设置为 cmake 命令的参数

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

CMake 行为:使用 Visual Studio 的自定义配置类型需要多次运行 cmake 才能正确显示。这是故意的吗? 的相关文章

随机推荐

  • 从另一个浏览器打开一个浏览器[重复]

    这个问题在这里已经有答案了 我正在 Firefox 上运行我的 Web 应用程序 我在其中一个页面上有超链接 当我单击它时 它会打开另一个应用程序作为新的弹出窗口 但 Firefox 不支持该应用程序 所以我想在 Internet Expl
  • 将 Android CheckBox 设置为不同的图像...然后返回原始图像

    我正在使用以下 非常常见 代码来更改 Android 应用程序中的复选框图像 mCheck CheckBox findViewById R id chkMine mCheck setButtonDrawable R drawable my
  • 如何通过属性名称和/或值查找锚标记? [复制]

    这个问题在这里已经有答案了 这是我正在尝试自动化的网络 https www supremenewyork com shop sweatshirts xi9sboa21 u2te1fdw8 https www supremenewyork c
  • 为 Databricks 生成数据库架构图

    我正在创建一个 Databricks 应用程序 并且数据库架构变得非常重要 有没有办法为 Databricks 数据库生成架构图 类似于可以从 mysql 生成的架构图 有两种可能的变体 使用 Spark SQL 与show databas
  • 将 C/C++ 回调传递到 matlab 引擎

    我有一个 C 文件 启动 matlab 引擎 calls matlab optimize 一个编译后的 m 文件 在内部运行 matlab 优化器之一 打印结果 停止发动机并退出 这很好用 我现在想将第二行更改为 calls matlab
  • Xcode 文档图标未更新

    我创建了一个 icns并在我的项目的 文档类型 部分中进行设置 但 Finder 中的文档图标仍然是通用的 我注意到 如果更改文档类型的文件扩展名 则会显示该图标 是否有我需要清除的缓存或其他方式来更新图标而不更改文件扩展名 要强制刷新图标
  • Sequelize 同步与迁移

    我正在学习 Sequelize 我想了解一些有关同步与迁移的说明 我知道同步将根据我的模型架构创建丢失的表 但我还读到同步用于初始化数据库 而迁移用于生产 如果是这种情况 express example 显示调用同步来自bin www ht
  • 在哪里可以获得 MediaWiki 的模板?

    我注意到很多基于 mediawiki 的网站都使用 Robelbox Ambox 等模板 我在哪里可以获得它们以及如何安装它们 It s a PITA http www urbandictionary com define php term
  • 为什么 Python 的 lambda 表达式中不允许赋值?

    这不是重复的Python 中 lambda 表达式内的赋值 https stackoverflow com questions 6282042 assignment inside lambda expression in python 即我
  • 如何在 JavaFX2 中的任务之间重置进度指示器?

    我的主屏幕 UI 上有一个进度指示器 由各种选项卡和服务共享 每个 TabController 都有自己的 Service 实例 在我的 MainController 类中 对于每个选项卡 我已将每个服务的进度属性绑定到 ProgressI
  • 通过 Kivy 在 Android 上运行 Tensorflow

    I found 这个答案 https stackoverflow com a 34495029 828184这让我想到了一个想法 你可以在 Android 手机上使用 kivy 而不是使用编译后的张量流图 这样你就可以使用直接与张量流图对话
  • 将数组中的相同值分组

    我有一个数组 里面有一些值 我希望返回另一个数组 该数组的值分组到自己的数组中 所以我想要达到的结果是这样的 var arr 1 1 2 2 2 3 3 4 4 4 4 5 6 var groupedArr 1 1 2 2 2 3 3 4
  • Xamarin.Android 中的测试活动

    我想对活动生命周期的一些交互进行单元测试 我正在开发一个数据绑定库 没有它就无法进行单元测试 安卓也有一些不错的文档 http developer android com tools testing activity testing htm
  • “代码生成器已取消优化 [某些文件] 的样式,因为它超过了最大值“100KB””是什么意思?

    我向我的项目添加了一个新的 npm 包 并在我的一个模块中需要它 现在我从 webpack 收到这条消息 build modulesNote The code generator has deoptimised the styling of
  • SSRS 选择性分页符

    我正在处理的有关财产记录的当前报告在 SSRS 中遇到一些格式问题 我的报告由 6 个在横向视图中对齐的 tablixes 构建而成 旨在保留特定的布局以供潜在的报告打印 第一个 Tablix 包含有关相关财产和所有者的一般信息 该信息将是
  • 如何以编程方式选择 MKUserLocation?

    标题和副标题可以添加到 iOS 显示的用户位置MK用户位置 https stackoverflow com questions 6400880 on mkuserlocation how do i show my own custom me
  • 如何重置向南迁移以捕获 django 模型的当前状态

    我有一个应用程序 目前有 35 次向南迁移 在设置新部署时 我们经常创建新部署 这些需要一段时间才能完成 并且应用程序正在不断发展 添加更多迁移 此外 迁移还包括一些潜在的复杂数据迁移和一些破坏 SQLite3 的自定义迁移 目前这不是一个
  • 像 Instagram 一样带有圆角的文本背景

    我想像 Instagram 一样创建具有背景颜色和圆角的文本 我能够实现背景颜色 但无法创建圆角 到目前为止我所拥有的 下面是上面截图的源代码 void createBackgroundColor self txtView layoutMa
  • CoffeeScript - 编译当前目录和所有子目录中的所有 .coffee 文件

    编译当前目录和所有子目录中的所有 coffee 文件的最简单方法是什么 您可以使用集成的coffee外壳工具 coffee output lib compile src 编译 coffee 文件的目录树src到 js 文件的并行树中lib
  • CMake 行为:使用 Visual Studio 的自定义配置类型需要多次运行 cmake 才能正确显示。这是故意的吗?

    Context 我正在将一个项目从普通 Makefile 迁移到 CMake 以添加对多个编译器 gfortran ifort 和操作系统 Windows Linux 的支持 当我完成整个事情时 我正在尝试简化 CMake 行为并为用户提供