【问题标题】:Cmake generators for Visual Studio do not set CMAKE_CONFIGURATION_TYPESVisual Studio 的 Cmake 生成器不设置 CMAKE_CONFIGURATION_TYPES
【发布时间】:2015-07-27 19:05:43
【问题描述】:

Cmake FAQother places 建议检查CMAKE_CONFIGURATION_TYPES 以识别多配置生成器。我发现了几个不起作用的问题(例如this one)。问题似乎是第一次调用 cmake 时没有设置变量。

我用下面的文件测试过

cmake_minimum_required(VERSION 2.6)

if(CMAKE_CONFIGURATION_TYPES)
    message("Multi-configuration generator")
else()
    message("Single-configuration generator")
endif()

project(foo)

这样称呼它

mkdir build
cd build
cmake -G "Visual Studio 12 2013" ..

得到Single-configuration generator

如何区分当前的生成器是否支持多种配置?

【问题讨论】:

  • 有什么理由在project() 命令之前检查CMAKE_CONFIGURATION_TYPES?因为大多数变量都是通过project() 调用设置的(参见here)。请在project() 前后添加message("CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES}") 以查看区别。

标签: visual-studio cmake


【解决方案1】:

已编辑:添加了有关检查和更改的信息CMAKE_CONFIGURATION_TYPES

检查和更改CMAKE_CONFIGURATION_TYPES

接受this question 的建议,您可以检查并更改CMAKE_CONFIGURATION_TYPES,但请注意 CMake 3.2.2 中有一个错误0015577: The 'project' command overwrites CMAKE_CONFIGURATION_TYPES 确实打破了最初的这种行为VS 解决方案生成(使用 CMake 3.3.0 修复):

cmake_minimum_required(VERSION 3.3)

project(foo NONE)

if(CMAKE_CONFIGURATION_TYPES)
    message("Multi-configuration generator")
    set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "My multi config types" FORCE)
else()
    message("Single-configuration generator")
endif()

enable_language(C CXX)

预设CMAKE_CONFIGURATION_TYPES

如果您只需要针对多配置环境的一组配置,您可以这样做(感谢@Tsyvarev 的建议):

cmake_minimum_required(VERSION 2.8)

# NOTE: Only used in multi-configuration environments
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "My multi config types" FORCE)

project(foo)

没有多配置环境会忽略它。但请注意其他 CMake 模块,如 findBoost.cmakefindCUDA.cmake 可能依赖于 CMAKE_CONFIGURATION_TYPES 为空的单一配置环境(再次感谢 @Tsyvarev 的提示)。

因此,更好的解决方案是为所有受支持的生成器添加工具链文件。它们通常很有用,因为您可以在那里处理所有工具链/生成器特定的部分。

这是我的VSToolchain.txt的摘录:

# Reduce the config types to only Debug and Release
SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)

# Standard is a console app. If you need a windows app, use WIN32 define in add_executable
set(CMAKE_WIN32_EXECUTABLE 0 CACHE INTERNAL "")

CMAKE_WIN32_EXECUTABLE 只是用来显示我在 Visual Studio 工具链文件中放入的设置类型。

这里建议另一种 CMake 命令行解决方案:How to create cmake build configuration without debug symbols and without optimizations?

只检查CMAKE_CONFIGURATION_TYPES

如果您只想检查 CMake 在 CMAKE_CONFIGURATION_TYPES 中设置的内容:

我刚刚使用 Visual Studio 2013 和 MinGW/GCC 测试了您的上述代码(两者都有空的 build 目录)。您只需稍作改动,然后将检查移到project() 命令之后:

project(foo)

message("CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES}")

if(CMAKE_CONFIGURATION_TYPES)
    message("Multi-configuration generator")
else()
    message("Single-configuration generator")
endif()

我得到了 VS2013:

CMAKE_CONFIGURATION_TYPES Debug;Release;MinSizeRel;RelWithDebInfo
Multi-configuration generator

对于 GCC:

CMAKE_CONFIGURATION_TYPES
Single-configuration generator

有关 CMake 所见内容的更多详细信息:

【讨论】:

  • 我在project()之前进行测试的原因是在项目之后设置变量意味着更改没有在第一次cmake运行时传播到VS项目文件。我现在无法对此进行测试(办公室里只有 Windows PC),但我链接的问题(stackoverflow.com/questions/20638963)提到了同样的问题,答案是在 ENABLE_LANGUAGE() 之前设置 CMAKE_CONFIGURATION_TYPES。
  • @Flogo:回答你提到的状态,你可以在选择语言之前设置CMAKE_CONFIGURATION_TYPES。只需无条件地将其设置为缓存值。顺便说一句,配置特定标志(CMAKE_<LANG>_FLAGS_<CONFIG>)的最佳位置也是在语言设置之前。
  • @Tsyvarev:我不明白。是否无条件地将其设置为缓存值会绕过整个 if 语句?也就是说,如果我在缓存中设置了值,单个配置生成器的语言设置会再次删除它吗?然后我是否需要在语言设置之后使用 if 语句,或者我可以在语言设置之前无条件地设置我想要的类型。如果是这样,为什么所有示例都使用 if 语句?特别是常见问题解答中的示例似乎有些不完整。
  • @Florian,感谢您的测试。实际上,无条件设置CMAKE_CONFIGURATION_TYPES 的问题是某些模块(例如findBoost.cmakefindCUDA.cmake)使用它来识别多配置生成器。我不确定在单个配置的情况下找到非空变量是否对他们至关重要。
  • @Tsyvarev 我通过添加variable_watch(CMAKE_CONFIGURATION_TYPES) 对此进行了测试,但我没有找到与project(foo NONE)/enable_language() 的任何组合确实有效。这里有什么奇怪的:对于 VS,两个命令都调用 cmGlobalVisualStudio7Generator::EnableLanguage() 并再次覆盖 CMAKE_CONFIGURATION_TYPES (不应该因为代码检查变量是否已设置)。并且行为在 CMake 2.8.12 和 3.3 之间发生了多次更改(参见例如here。我再次检查 3.3。
猜你喜欢
  • 2019-09-06
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多