有两种类型的生成器:单配置和多配置。
单配置
类似于 Make 的生成器:Unix Makefiles, NMake Makefiles, MinGW Makefiles,...
您可以在生成步骤中设置配置类型:
cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"
在这种情况下,构建步骤始终为
调试:
> 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 ...
多配置
IDE生成器:Visual Studio, Xcode
在生成步骤中忽略CMAKE_BUILD_TYPE
,两者均适用:
> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"
并且
> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"
将会产生相同的效果:
![Enter image description here](https://istack.dev59.com/C0vNC.webp)
这是因为所有的配置都是内部的(即,
_builds/msvc-opaque/Release
和
_builds/msvc-opaque/Debug
或其他,无所谓)。您可以使用
--config
选项进行切换:
> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...
控制(?)
是的,你可以。只需定义CMAKE_CONFIGURATION_TYPES:
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")
默认输出:
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done
重写它:
> 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
![Enter image description here](https://istack.dev59.com/a3yIB.webp)
你甚至可以定义自己的配置类型:
> 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"
![Enter image description here](https://istack.dev59.com/y3V0k.webp)
并构建:
cmake --build _builds --config MyRelease
混乱?
如果你知道诀窍,一点也不混乱 :) 以下是如何在脚本/CI服务器/文档的构建说明中构建/测试配置:
> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}"
> cmake --build _builds --config "${CONFIG}"
> (cd _builds && ctest -VV -C "${CONFIG}")
不良模式
if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...
不错
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")
运行良好。
target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")
谢谢!:) 你为一个程序员节省了一天的时间。
使用Makefile对我很有效,我很高兴...
来自一本不错的人的好书的一些引用,你可能知道(重点是我的):
为什么要费心呢?那些在各种系统上编程或使用各种编译器的人关心这个问题,因为如果他们不这样做,就会被迫花费时间查找和修复晦涩难懂的错误。那些声称他们不关心可移植性的人通常是因为他们只使用单一的系统,觉得可以采取“语言就是我的编译器实现”的态度。这是一个狭隘和短视的观点。如果你的程序成功了,很可能会被移植,所以别人就必须找到并修复与实现相关的问题。此外,程序经常需要使用其他编译器进行编译,即使是你最喜欢的编译器的未来版本也可能会与当前版本有所不同。在编写程序时了解和限制实现依赖性的影响要容易得多,而在事后试图解决混乱则要困难得多。
CMAKE_BUILD_TYPE
的工作... - Syntactic Fructoseset(CMAKE_BUILD_TYPE "Release" CACHE STRING "Configuration type" FORCE)
,但是没有起作用。 - Syntactic Fructoseset(CMAKE_BUILD_TYPE Release)
这并不是它的正确使用方式。这个命令虽然会在Makefile
生成器中工作,但对于像 Xcode 和 Visual Studio 这样的 IDE,这行代码将被忽略,因为 Release/Debug 在内部切换。文档 已经很清楚地说明了这一点。如果你想限制你的编译变体,你需要设置 CMAKE_CONFIGURATION_TYPES。 - user2288008CMAKE_BUILD_TYPE
默认值的方法。一旦设置,使用make VERBOSE=1
命令可以显示发送给编译器的完整命令,可用于验证是否有效。 - legends2k