什么是CMAKE_BUILD_类型:调试、发布、RelWithDebInfo和MinSizeRel?

什么是CMAKE_BUILD_类型:调试、发布、RelWithDebInfo和MinSizeRel?,cmake,Cmake,从: CMAKE\u BUILD\u类型 指定单个配置生成器上的生成类型 这静态地指定将在此生成树中生成的生成类型(配置)。可能的值为空、Debug、Release、RelWithDebInfo和MinSizeRel。此变量仅对单个配置生成器有意义(例如Makefile生成器和Ninja)即,当CMake运行以生成生成生成树时选择单个配置的生成器,而不是在生成的生成环境中提供生成配置选择的多配置生成器。有许多每配置属性和变量(通常遵循干净的一些_VAR顺序约定),例如CMAKE_C_FLAGS,

从:

CMAKE\u BUILD\u类型

指定单个配置生成器上的生成类型

这静态地指定将在此生成树中生成的生成类型(配置)。可能的值为空、
Debug
Release
RelWithDebInfo
MinSizeRel
。此变量仅对单个配置生成器有意义(例如
Makefile生成器
Ninja
)即,当CMake运行以生成生成生成树时选择单个配置的生成器,而不是在生成的生成环境中提供生成配置选择的多配置生成器。有许多每配置属性和变量(通常遵循干净的
一些_VAR
顺序约定),例如
CMAKE_C_FLAGS
,指定为大写:
CMAKE_C_FLAGS.[DEBUG | RELEASE | RELWITHDEBINFO | MINSIZEREL]
。例如,在配置为build type
Debug
的生成树中,CMake将确保将
CMake\u C\u FLAGS\u Debug
设置添加到
CMake\u C\u FLAGS
设置中。另请参见
CMAKE\u配置类型

我知道
Debug
构建和
Release
构建之间的区别,但是
Release
RelWithDebInfo
MinSizeRel
之间的区别是什么?我猜
RelWithDebInfo
意味着创建可调试的二进制文件,
MinSizeRel
意味着创建尽可能小的二进制文件

从:

CMAKE\u BUILD\u类型:字符串

如果您使用的是诸如VisualStudio之类的IDE,则应使用IDE设置来设置生成类型。请注意,Release和RelWithDebInfo在大多数平台上使用不同的优化级别


如果我想生成生产版本,我是否应该选择
Release

RelWithDebInfoRelease相同,允许您进行调试

例如,在VisualStudio中,您将拥有
.pdb
文件,如果没有这些文件,将很难调试,因为二进制文件中的所有签名都不是人类可读的,并且无法将它们映射到源代码

MinSizeRelRelease相同,例如,它的优化配置仅在Visual Studio中设置为

如果我想生成生产构建,我应该选择发布吗

是的,那对你来说应该很合适。调试/发布是最常用的选项

阅读实际上对你有很大帮助。

是的,你是对的:

我猜
RelWithDebInfo
意味着创建可调试的二进制文件,
MinSizeRel
意味着创建尽可能小的二进制文件

RelWithDebInfo
将添加用于生成调试信息的编译器标志(GCC/clang的
-g
标志),并将生成可调试但更大的二进制文件

MinSizeRel
将添加编译器标志以生成更紧凑的二进制文件(GCC/clang的
-Os
标志),这可能是以牺牲程序速度为代价的

如果我想生成生产构建,我应该选择
Release


是的,
Release
将是一个不错的选择。它应该生成更快的二进制文件,方法是指定编译器优化级别以提高速度(
-O3
用于GCC/clang),并且不包括调试符号。

重要的是:
CMAKE_BUILD_TYPE
仅适用于单个目标生成器,如makefile。它不用于多目标生成器,因为这些生成器只生成能够构建所有构建类型(调试、发布等)的构建系统

CMAKE\u BUILD\u TYPE
是关于

  • 优化(水平)[code>-O0、-O1、-O2、-O3、-Oast、-Os、-Oz、-Og、-O、-O4]
  • 包括可执行文件中的“调试信息”[
    -g,-gline表,-gmodules,-g
    level
    ,-gcoff,-gdwarf,-gdwarf-
    version
    ,-ggdb,-grecord gcc开关,-gno record gcc开关,-gstabs+,-gstrict dwarf,-gno strict dwarf,-gcolumn info,-gno column info,-gvms,-gxcoff,-gz[=/code>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.
    
    就编译器标志而言,这通常意味着(因为在大多数情况下,所有平台都支持这些标志):

    其中,在支持此功能的平台上添加了定义
    NDEBUG
    (它禁用
    assert()
    )。这就是为什么你应该确保你的主张没有副作用,当然

    扩展构建类型

    虽然一般来说,为不同的工具链添加需要不同选项的内容并不是您真正想要做的事情(尽管编译器选项基本上是特定于编译器/语言的,因此您可以很容易地检查是否需要,然后根据需要选择标记)

    当您将自己限制为[
    -g,-O0,-O2,-O3
    -Os
    ]时,以更改优化标志或调试标志的形式添加支持非常容易,可以删除可能的
    -DNDEBUG
    标志和/或添加自定义宏

    假设我们有一个宏
    DEBUG
    ,我们想定义它来包含特定的调试代码(例如,可以包括编写调试输出)

    然后我们一共有四个优化级别,调试信息与否,断言代码与否,调试代码与否
    1. Release: `-O3 -DNDEBUG`
    2. Debug: `-O0 -g`
    3. RelWithDebInfo: `-O2 -g -DNDEBUG`
    4. MinSizeRel: `-Os -DNDEBUG`
    
    1. Release
    2. MinSizeRel
    
    3. RelWithDebInfo
    
    4. Debug
    
    5. BetaTest [`-O3 -g`] - aka Release minus the `-DNDEBUG` but with `-g`.
    
    6. RelWithDebug [`-O2 -g -DDEBUG`] - aka RelWithDebInfo but `-DNDEBUG` removed and `-DDEBUG` added.
    
    string(REGEX REPLACE "( -DNDEBUG$|-DNDEBUG )" "" CMAKE_CXX_FLAGS_BETATEST "${CMAKE_CXX_FLAGS_RELEASE}" ) 
    string(REGEX REPLACE "( -DNDEBUG$|-DNDEBUG )" "" CMAKE_C_FLAGS_BETATEST "${CMAKE_C_FLAGS_RELEASE}" )    
    string(REGEX REPLACE "-DNDEBUG " "" CMAKE_CXX_FLAGS_RELWITHDEBUG "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG" )
    string(REGEX REPLACE "-DNDEBUG " "" CMAKE_C_FLAGS_RELWITHDEBUG "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DDEBUG" )