CMake中的调试与发布

Car*_*s00 390 c c++ gcc cmake

在GCC编译的项目中,

  • 如何为每种目标类型(调试/发布)运行CMake?
  • 如何使用CMake指定调试和释放C/C++标志?
  • 我如何表示主要可执行文件将g++与一个嵌套库一起编译gcc

kb1*_*ooo 614

使用CMake,通常建议执行"out of source"构建.CMakeLists.txt在项目的根目录中创建您的.然后从项目的根目录:

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make
Run Code Online (Sandbox Code Playgroud)

对于Debug(再次来自项目的根):

mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
Run Code Online (Sandbox Code Playgroud)

Release/ Debug将为您的编译器添加适当的标志.也有RelWithDebInfoMinSizeRel构建配置.


您可以修改/添加CMAKE_C_FLAGS_DEBUGvia CMAKE_C_FLAGS_RELEASECMakeLists.txt变量中的标志,例如:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅CMAKE_BUILD_TYPE.


至于你的第三个问题,我不确定你究竟在问什么.CMake应该自动检测并使用适合您不同源文件的编译器.

  • 如果要创建子目录,这不是源代码构建!建议在源目录之外/之上创建构建目录. (6认同)
  • 我必须运行 `cmake --build 。--config Release` 获取发布版本。如果省略“--config Release”,则无论上一个命令中的“cmake -DCMAKE_BUILD_TYPE=Release ..”如何,您始终会获得调试版本。(cmake 3.21) (5认同)
  • @thiagowfx` -i`选项导致此错误消息:`不再支持"cmake -i"向导模式.我正在使用cmake 3.7.1 (4认同)
  • 您也可以改为执行`cmake -i ..`,因此cmake将以交互方式运行,询问您需要哪种类型的构建(None,Release,Debug,MinSizeRel,RelWithDebInfo). (3认同)
  • 很好的观察.它看起来自版本3.0.0以后就被弃用了.[参考文献](https://cmake.org/cmake/help/v3.0/release/3.0.0.html#deprecated-and-removed-features). (3认同)

dun*_*can 21

对于调试/释放标志,请参阅CMAKE_BUILD_TYPE变量(将其传递为cmake -DCMAKE_BUILD_TYPE=value).这需要像值Release,Debug等等.

http://cmake.org/Wiki/CMake_Useful_Variables#Compilers_and_Tools

cmake使用扩展名来选择编译器,所以只需命名你的文件.c.

您可以使用各种设置覆盖它:

例如:

set_source_files_properties(yourfile.c LANGUAGE CXX) 
Run Code Online (Sandbox Code Playgroud)

用g ++编译.c文件.上面的链接还说明了如何为C/C++选择特定的编译器.


小智 18

这里的很多答案已经过时/不好。所以我将尝试更好地回答它。当然,我会在 2020 年回答这个问题,所以预计事情会发生变化。


如何为每个目标类型(调试/发布)运行 CMake?

首先,调试/发布在 cmake (nitpick) 中被称为配置。

如果您使用单个配置生成器(Ninja/Unix-Makefiles)

然后,您需要为每个配置创建一个构建文件夹。

像这样:

# Configure the build
cmake -S . -B build/Debug -D CMAKE_BUILD_TYPE=Release

# Actually build the binaries
cmake --build build/Debug
Run Code Online (Sandbox Code Playgroud)

对于多配置生成器,它略有不同(Ninja Multi-Config,Visual Studio)

# Configure the build
cmake -S . -B build

# Actually build the binaries
cmake --build build --config Debug
Run Code Online (Sandbox Code Playgroud)

如果您想知道为什么这是必要的,那是因为 cmake 不是构建系统。这是一个元构建系统(即构建构建系统的构建系统)。这基本上是处理支持 1 个构建中的多个配置的构建系统的结果。如果您想更深入地了解,我建议您阅读 Craig Scott 的书“Professional CMake: A Practical Guide”中有关 cmake 的一些内容


如何使用 CMake 指定调试和发布 C/C++ 标志?

现代做法是使用目标和属性。

下面是一个例子:

add_library(foobar)

# Add this compile definition for debug builds, this same logic works for
# target_compile_options, target_link_options, etc.
target_compile_definitions(foobar PRIVATE
    $<$<CONFIG:Debug>:
        FOOBAR_DEBUG=1
    >
)
Run Code Online (Sandbox Code Playgroud)

注意:我如何使用生成器表达式来指定配置!使用 CMAKE_BUILD_TYPE 将导致任何多配置生成器的构建错误!

此外,有时您需要全局设置,而不仅仅是针对一个目标。使用 add_compile_definitions、add_compile_options 等。这些函数支持生成器表达式。除非必须,否则不要使用旧式 cmake(这条路是噩梦之地)


我如何表示主可执行文件将使用 g++ 和一个带有 gcc 的嵌套库进行编译?

你最后一个问题真的没有意义。


seb*_*ian 14

您可以使用:而不是CMAKE_CXX_FLAGS直接操作字符串(使用string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g3")btw 可以更好地完成)add_compiler_options

add_compile_options(
  "-Wall" "-Wpedantic" "-Wextra" "-fexceptions"
  "$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
)
Run Code Online (Sandbox Code Playgroud)

这会将指定的警告添加到所有构建类型,但只会给DEBUG构建的给定调试标志.请注意,编译选项存储为CMake列表,它只是一个用分号分隔其元素的字符串;.

  • 这在 2020/cmake 3.17 中仍然是合适的方式吗?最后一行看起来很恶心 (6认同)
  • 不会列出(APPEND CMAKE_CXX_FLAGS_DEBUG"-g3")`在-g3终止命令之前添加一个分号并启动一个肯定会失败的新命令-g3? (2认同)

小智 10

如果你想构建一个不同的配置而不重新生成如果使用你也可以运行cmake --build {$PWD} --config <cfg>对于多配置工具,选择<cfg>ex。调试、发布、MinSizeRel、RelWithDebInfo

https://cmake.org/cmake/help/v2.8.11/cmake.html#opt%3a--builddir


sai*_*009 6

// CMakeLists.txt:发布

set(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)
Run Code Online (Sandbox Code Playgroud)

// CMakeLists.txt:调试

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)
Run Code Online (Sandbox Code Playgroud)

  • 我不明白为什么这被否决了,这是在生产中使用的真实代码,顺便说一句,我不在乎。 (8认同)
  • 可能是因为根据CMake文档,“ CMAKE_CONFIGURATION_TYPES”包含“ CMAKE_BUILD_TYPE”的可能值。因此,您应将后者设置为其他答案所建议的。也许您的解决方案有效,因为它将可能的选择限制在您想要的选择范围之内。 (5认同)
  • 投票,因为这将起作用。我爱我一些CMake,但有一些怪癖,有时您需要使用大铁锤才能使事情正常进行。我有一些项目出于某种原因会拒绝命令行标志。 (2认同)