来自docs page:
CMAKE_BUILD_TYPE
指定单配置生成器上的构建类型。
这静态地指定将在此构建树中构建的构建类型(配置)。可能的值为空,
Debug
,Release
,RelWithDebInfo
和MinSizeRel
。此变量仅对单配置生成器(例如Makefile Generators
和Ninja
)有意义,即在CMake运行生成构建树时选择单个配置的那些,而不是提供选择的多配置生成器生成的构建环境中的构建配置。有许多per-config属性和变量(通常遵循干净的SOME_VAR_<CONFIG>
顺序约定),例如CMAKE_C_FLAGS_<CONFIG>
,指定为大写:CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]
。例如,在配置为构建类型Debug
的构建树中,CMake会将CMAKE_C_FLAGS_DEBUG
设置添加到CMAKE_C_FLAGS
设置中。另请参阅CMAKE_CONFIGURATION_TYPES
。
我知道Debug
版本和Release
版本之间存在差异,但Release
,RelWithDebInfo
和MinSizeRel
之间有何区别?我猜RelWithDebInfo
意味着创建可调试的二进制文件,MinSizeRel
意味着创建尽可能小的二进制文件。
CMAKE_BUILD_TYPE:STRING
如果您使用的是Visual Studio等IDE,则应使用IDE设置来设置构建类型。请注意,Release和RelWithDebInfo在大多数平台上使用不同的优化级别。
如果我想生成生成版本,我应该选择Release
吗?
答案 0 :(得分:4)
RelWithDebInfo 与发布相同,允许您symbol files进行调试。
例如,在Visual Studio中,您将拥有.pdb
个文件,如果没有它们,它将很难调试,因为二进制文件中的所有签名都不会是人类可读,无法将它们映射到源代码。
MinSizeRel 与发布相同,例如,其优化配置在Visual Studio中设置为Minimize size, Maximize speed。
如果我想生成生产版本,我应该选择发布吗?
是的,那应该为你做正确的工作。调试/发布是最常用的选项。
阅读this CMAKE FAQ实际上对你有很大的帮助。
答案 1 :(得分:1)
是的,你是对的:
我猜测
RelWithDebInfo
意味着创建可调试的二进制文件,MinSizeRel
意味着创建尽可能小的二进制文件。
RelWithDebInfo
将添加编译器标志以生成调试信息(GCC / clang的-g
标志),并将导致可调试但更大的二进制文件。
MinSizeRel
将添加编译器标志以生成更紧凑的二进制文件(GCC / clang的-Os
标志),可能以程序速度为代价。
如果我想生成生成版本,我应该选择
Release
吗?
是的,Release
将是一个不错的选择。它应该生成更快的二进制文件,方法是指定编译器优化级别以支持速度(GCC / clang为-O3
),不包括调试符号。
答案 2 :(得分:0)
CMAKE_BUILD_TYPE
即将结束,
-O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
] -g, -gline-tables-only, -gmodules, -g
, -gcoff, -gdwarf, -gdwarf-
版本 , -ggdb, -grecord-gcc-switches, -gno-record-gcc-switches, -gstabs, -gstabs+, -gstrict-dwarf, -gno-strict-dwarf, -gcolumn-info, -gno-column-info, -gvms, -gxcoff, -gxcoff+, -gz[=
type ]
] assert()
生成代码[-DNDEBUG
] 大多数此类编译器选项是特定于编译器和/或平台的。因此,对构建类型的扩展支持需要更新您要支持的每个现有工具链。
cmake附带的默认构建类型或多或少表示以下内容,
1. Release: high optimization level, no debug info, code or asserts.
2. Debug: No optimization, asserts enabled, [custom debug (output) code enabled],
debug info included in executable (so you can step through the code with a
debugger and have address to source-file:line-number translation).
3. RelWithDebInfo: optimized, *with* debug info, but no debug (output) code or asserts.
4. MinSizeRel: same as Release but optimizing for size rather than speed.
就通常意味着的编译器标志而言(由于在大多数情况下所有平台上都支持这些标志):
1. Release: `-O3 -DNDEBUG`
2. Debug: `-O0 -g`
3. RelWithDebInfo: `-O2 -g -DNDEBUG`
4. MinSizeRel: `-Os -DNDEBUG`
在支持此功能的平台上添加了定义NDEBUG
的位置(它禁用了assert()
)。这就是为什么您应该确保所有断言都没有副作用的原因。
扩展构建类型
尽管添加不同工具链需要不同选项的内容通常并不是您真正想做的(尽管,编译器选项基本上是特定于编译器/语言的,所以如果您愿意,可以轻松检查compiler ID想要,然后根据需要选择您的标志。)
当您将自己限制为[-g, -O0, -O2, -O3
和-Os
]时,以更改优化标志或调试标志的形式添加支持非常容易,从而消除了可能的{ {1}}标志和/或添加自定义宏。
假设我们要定义一个宏-DNDEBUG
,以包括特定的调试代码(例如,可能包括编写调试输出)。
然后,我们共有四个优化级别,即是否调试信息,是否声明代码以及是否调试代码,总共有4 * 2 * 2 * 2 = 32个配置(构建类型)。但显然并非所有配置都非常实用。最好看看配置的用例是什么。
很显然,我们拥有DEBUG
构建,它是无漏洞的代码,已广泛发布;这是生产代码。您不会经常编译它,并且在执行时,比起编译它要花多长时间,结果代码要快(或小?)更为重要。这样就产生了两种现有的生产代码构建类型:
Release
但是,事实证明,在生产代码中毕竟存在一个错误,导致应用程序崩溃。您无法复制它,它只会在某些时候发生。您为用户实现了向您发送核心转储的反馈机制,但信息还不够。您希望获得堆栈跟踪信息,希望它能告诉您更多信息。您要求某些用户(或者可能是您自己,每天以“用户”身份使用它)下载可以正常使用的特殊版本(速度足够快,经过优化),但其中包含调试信息,因此需要更长的时间去下载。那些用户并不介意:他们希望此崩溃得到解决。
支持1. Release
2. MinSizeRel
当然,作为开发人员,您需要一个可以与调试器一起使用的版本。它并不需要很快-您已经知道如何重现不依赖优化的错误(这是逻辑错误,代码中的问题-不是Heisenbug)。为此,您使用
3. RelWithDebInfo
但是-您也有beta测试人员(也许您自己是每天使用该程序作为“用户”使用的)。在这种情况下,您希望对代码进行优化,以使其速度足够快-但您也希望所有断言都处于打开状态。断言可能会告诉您问题出在哪里比以后发生的核心转储好得多。或更糟糕的是,它的行为可能很奇怪并且根本不会崩溃。您需要确保即使在生产代码中也不会断言。那就是beta测试人员的目的。让我们将此构建类型称为
4. Debug
最后,有些调试版本不是 ,无法通过调试器逐步进行,堆栈跟踪也没有帮助(因为它不是核心转储,或者问题不是导致立即崩溃)。有很多(即使不是大多数)此类错误。查找这些错误(一旦发生)的唯一方法是使用 extra 调试代码和/或将大量调试输出写入日志文件。您希望至少使用5. BetaTest [`-O3 -g`] - aka Release minus the `-DNDEBUG` but with `-g`.
编译此代码,但也要声明断言(为什么不这样),并且需要定义宏-O2
。当然,我们也可能包含调试信息,因为在这里,可执行文件的大小不太重要。让我们称之为这样的构建
DEBUG
我在这里建议6. RelWithDebug [`-O2 -g -DDEBUG`] - aka RelWithDebInfo but `-DNDEBUG` removed and `-DDEBUG` added.
,因为这是您作为开发人员最常编译的内容,因为您自己永远都是这样的用户,因为如果发生意外情况,您想知道是什么原因造成的(拥有这些日志) !),并且您不想一直使用慢得多的-O2
进行编译...
要支持这两种额外的构建类型,我们需要能够做两种 因此,事情是:获取现有构建类型的标志(更改它们)并将这些标志用于新的(自定义)构建类型。
这是执行此操作的方法
如果将以下四行添加到项目根-O3
文件的顶部,然后使用CMakeLists.txt
(或-DCMAKE_BUILD_TYPE=BetaTest
),将使用上面概述的标志。当然,如果RelWithDebug
文件中的其他内容取决于构建类型,则可能必须进行更多更改。这是我个人使用的示例:CW_OPTIONS.cmake(看一下,.cmake
和betatest
的大小写不敏感,加上这两个变量具有的值所设置的变量)。
relwithdebug