CMake中的调试与发布


435

在GCC编译的项目中,

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

Answers:


657

对于CMake,通常建议执行“源外”构建CMakeLists.txt在您的项目的根目录中创建您的。然后从您的项目的根目录:

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make

并且Debug(再次从项目的根源开始):

mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

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


您可以通过指定可以在其中添加和变量的工具链文件来修改/添加到标志,例如:CMAKE_C_FLAGS_DEBUGCMAKE_C_FLAGS_RELEASE

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")

有关更多详细信息,请参见CMAKE_BUILD_TYPE


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


3
您也可以cmake -i ..代替它,以便cmake可以交互运行,询问您想要哪种类型的构建(无,发布,调试,MinSizeRel,RelWithDebInfo)。
thiagowfx

5
@thiagowfx -i选项导致此错误消息:The "cmake -i" wizard mode is no longer supported.。我正在使用cmake 3.7.1
PhilippClaßen17年

3
不错的观察。自版本以来,它似乎已被弃用3.0.0参考
thiagowfx

7
如果要创建子目录,这不是源代码之外的构建!建议在源目录之外/之上创建构建目录。
Victor Lamoine '17

请注意,如果CMAKE_BUILD_TYPE未设置,则cmake不会选择任何默认的构建类型,因此生成的编译器命令行将不匹配任何构建配置。
大卫

23

有关调试/释放标志,请参见CMAKE_BUILD_TYPE变量(将其传递为cmake -DCMAKE_BUILD_TYPE=value)。这需要像值ReleaseDebug等等。

https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/Useful-Variables#compilers-and-tools

cmake使用扩展名选择编译器,因此只需将文件命名为.c。

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

例如:

set_source_files_properties(yourfile.c LANGUAGE CXX) 

将使用g ++编译.c文件。上面的链接还显示了如何为C / C ++选择特定的编译器。


16

除了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>"
)

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


2
list(APPEND CMAKE_CXX_FLAGS_DEBUG "-g3")在-g3终止命令并启动新命令-g3肯定会失败之前,是否不会添加分号?
cburn11年

您说的对,CMAKE_CXX_FLAGS不是 cmake列表,而是一串用空格分隔的命令行标志。我发现行为不一致...
sebastian

add_compile_options()整洁。当您还需要向链接器添加选项(例如-fsanitize = address)时,可以通过add_link_options()对其进行补充。
Bowie Owens

1
在2020年/ cmake 3.17中这仍然是合适的方法吗?最后一行看起来令人讨厌
Jay


5

// CMakeLists.txt:发布

set(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)

// CMakeLists.txt:调试

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)

10
我不明白为什么这被否决了,这是在生产中使用的真实代码,顺便说一句,我不在乎。
sailfish009

5
可能是因为根据CMake docs CMAKE_CONFIGURATION_TYPES可能包含的值CMAKE_BUILD_TYPE。因此,您应该将后者设置为其他答案所建议的。也许您的解决方案行之有效,因为它将可能的选择限制在您想要的范围之内。
bjhend

2
投票,因为这将起作用。我爱我一些CMake,但有一些怪癖,有时您需要使用大锤子才能使事情正常。我有一些项目出于某种原因会拒绝命令行标志。
cory.todd

以下是有关为何设置可能无法使用的一些其他信息:stackoverflow.com/a/24470998/3196753
tresf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.