CakeKE_BUILD_TYPE未在CMakeLists.txt中使用

Syn*_*ose 57 build cmake build-system

我在将我的默认构建配置设置为Release时遇到问题,在我的CMakeLists.txt文件中,我在文件顶部设置了CMAKE_BUILD_TYPE

#enable Release ALWAYS, configure vars
set(CMAKE_BUILD_TYPE Release)
set(EXECUTABLE_NAME "ParticleSimulator")
set(VERSION_MAJOR 0)
set(VERSION_MINOR 2)
Run Code Online (Sandbox Code Playgroud)

但是在构建我的项目并打开解决方案时,我总是会看到调试模式,这与我在CMakeLists文件中指定的相反.我究竟做错了什么?我在那里看了一些其他的问题,但没有看到任何特定于这个问题的东西.

CMakeLists.txt的要点

小智 163

有两种类型的发生器:单配置和多配置.

单一配置

类似Make的生成器:Unix Makefiles,NMake Makefiles,MinGW Makefiles,......

您在生成步骤上设置配置类型:

cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"
Run Code Online (Sandbox Code Playgroud)

在这种情况下,构建步骤始终是Debug:

> cmake --build _builds/Debug
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Debug # `--config` ignored
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Release # yep, ignored
/usr/bin/c++ -g ...
Run Code Online (Sandbox Code Playgroud)

多配置

IDE生成器:Visual Studio,Xcode

CMAKE_BUILD_TYPE on generate步骤被忽略,两者:

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"
Run Code Online (Sandbox Code Playgroud)

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"
Run Code Online (Sandbox Code Playgroud)

会产生同样的效果:

在此输入图像描述

这是因为所有配置都是内部的(即_builds/msvc-opaque/Release和/ _builds/msvc-opaque/Debug或其他,无关紧要).您可以使用--config选项切换:

> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...
Run Code Online (Sandbox Code Playgroud)

控制 (?)

是的你可以.只需定义CMAKE_CONFIGURATION_TYPES:

# Somewhere in CMakeLists.txt
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")
Run Code Online (Sandbox Code Playgroud)

默认输出:

-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done
Run Code Online (Sandbox Code Playgroud)

重写它:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;Release" "-GVisual Studio 12 2013 Win64"
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release
-- Configuring done
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

您甚至可以定义自己的配置类型:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;MyRelease" -DCMAKE_CXX_FLAGS_MYRELEASE="/My-Rel-flag" -DCMAKE_EXE_LINKER_FLAGS_MYRELEASE="/My-Linker-flags" "-GVisual Studio 12 2013 Win64"
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

并建立:

cmake --build _builds --config MyRelease

乱 (?)

如果你知道诀窍就一点都不:)这是如何在脚本/ CI服务器/文档的构建指令等中构建/测试配置:

> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}" # Set Debug to Makefile, ignored by IDE
> cmake --build _builds --config "${CONFIG}" # Build Debug in IDE, ignored by Makefile
> (cd _builds && ctest -VV -C "${CONFIG}") # Test Debug in IDE, ignored by Makefile
Run Code Online (Sandbox Code Playgroud)

糟糕的模式

if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...
Run Code Online (Sandbox Code Playgroud)

好的

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")
Run Code Online (Sandbox Code Playgroud)

工作得很好.

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")
Run Code Online (Sandbox Code Playgroud)

谢谢!:)你为一个程序员节省了一天.

使用Makefile为我工作,我很高兴...

从一个漂亮的书中的一些报价好人,你可能知道(重点煤矿):

你为什么要打扰?在各种系统上编程或使用各种编译器的人非常关心,因为如果他们不这样做,他们就不得不浪费时间寻找和修复模糊的错误.声称他们不关心可移植性的人通常会这样做,因为他们只使用一个系统,并且觉得他们能够承担"我的编译器实现的语言"的态度.这是一个狭隘短视的观点.如果您的程序成功,则可能会被移植,因此有人必须找到并修复与实现相关的功能相关的问题.此外,程序通常需要与同一系统的其他编译器一起编译,甚至您喜欢的编译器的未来版本可能会做一些与当前版本不同的东西.在编写程序时,了解并限制实现依赖性的影响要比在之后尝试解决混乱更容易.

  • 哇,一旦它在4小时内可用,这值得一个赏金的答案.谢谢你这么深入的回答. (6认同)
  • 我找到了答案; `-H`是[未记录的特征](http://stackoverflow.com/questions/31090821/what-does-the-h-option-means-for-cmake). (3认同)
  • @Muscampester只是为了您的信息最有趣的链接和解释可以在[本页]上找到(http://cgold.readthedocs.io/en/latest/glossary/-H.html) (2认同)

小智 8

您还可以使用以下代码段:

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
            "Default build type: RelWithDebInfo" FORCE)
endif()
Run Code Online (Sandbox Code Playgroud)

  • 大家,如果您对提交的答案投了反对票,请找一些词来说明您这样做的原因。因为在所有建议的答案中,这个简单的答案是唯一对我有用的。在此之前,我在这里找到了类似的“接受”解决方案:https://blog.kitware.com/cmake-and-the-default-build-type/ (2认同)
  • 不适用于 Visual Studio 生成器 (2认同)

Dan*_*per 6

发生的一种可能性是子模块CMAKE_BUILD_TYPE之一在缓存中设置了值,即:

SET(CMAKE_BUILD_TYPE Debug CACHE) 
Run Code Online (Sandbox Code Playgroud)

这意味着该值将从该点到配置运行结束永久更新。

跟踪此值更改的违规位置的一种好方法是使用CMake 的 variable_watch。在您的主CMakelists.txt文件中,添加以下行

variable_watch(CMAKE_BUILD_TYPE)
Run Code Online (Sandbox Code Playgroud)

这将在每次访问此变量时打印标准错误。并将其记录到日志文件中,请执行以下操作:

cmake <your options> 2>variable_watch.log
Run Code Online (Sandbox Code Playgroud)

您可能会看到类似以下内容:

<...>/CMakeLists.txt:184 (add_library) 处的 CMake 调试日志:使用值为“Debug”的 READ_ACCESS 访问了变量“CMAKE_BUILD_TYPE”。

然后您可能会看到第一次更改 CMAKE_BUILD_TYPE 的点。从这里开始,您将更接近于追踪违规的 CMake 生产线。