如何在使用Visual Studio编译的Cmake项目中正确设置调试标志



我有一个C++CMake项目,它是在Linux和Windows上编译的。在Windows上,这是通过Visual Studio/MSVCC完成的。

在CMAKE和VS中,构建被设置为Debug,但在VS构建中似乎从未生成任何调试符号,因此调试是不可能的。

当查看VS的详细输出时,我看到了以下内容:

cl : command line warning D9002: ignoring unknown option '-g'

这向我表明,它不像GCC/Clang-do那样识别-g标志。

以下是CMake参数:

SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(BUILD_MODE Debug)
SET(CMAKE_CXX_FLAGS "-Wall")
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3")

如何使其与Visual Studio兼容?我试着到处找,但大多数相关的帖子似乎都是关于C#/.net或VS.的旧版本

如果这很重要的话,该项目确实使用了QT库。

更新:

事实证明,BUILD_MODE是由其他人添加的,这样每个子项目就不需要单独设置为发布或调试,我们只需在根级别的Cmakelist中设置一次即可。他们确实都按预期使用了CMAKE_BUILD_TYPE

此外,这里的答案是正确的。直接设置CMAKE_CXX_FLAGS会清除默认值,导致调试构建在MSVCC中没有/Zi等选项,从而阻止调试符号和所有调试。它还引入了一个未被识别的标志"-g";MSVCC无法理解。

我从项目中的每个Cmakelists.txt中完全删除了SET_CXX_FLAGS,一切都很顺利。

如果需要添加,我将按照建议使用_INIT选项。

您必须使用与中不同的CMAKE_BUILD_TYPE模式集进行编译

cmake -DCMAKE_BUILD_TYPE=DEBUG <sourcedir>

你从来没有直接设置这些标志。如果你想在调试模式中添加一个新的标志,比如堆栈保护器,你应该使用*_INIT变量。

您可以进一步区分使用UNIXWIN32MSVCcmake布尔预定义常量运行的操作系统:

if ( UNIX )
set( CMAKE_CXX_FLAGS_DEBUG_INIT "-fstack-protector" )
elseif( WIN32 )
set( CMAKE_CXX_FLAGS_DEBUG_INIT "/GS" )
endif()

不需要在cmake中显式定义-O3-g。正如您所看到的,设置这些可能会阻止代码与其他编译器一起工作。无论如何,这两个选项都是默认选项。

要使用unix makefile构建其中一个配置,只需在配置期间设置CMAKE_BUILD_TYPE缓存变量:

(我假设上面提到的生成器是下面的默认生成器。(

cmake -D CMAKE_BUILD_TYPE=Debug -S ... -B buildDir

cmake -D CMAKE_BUILD_TYPE=Debug -S ... -B buildDir

并使用构建项目

cmake --build buildDir

visual studio的不同之处在于,生成的项目同时涵盖了所有配置。您可以指定在构建(或安装(项目时使用的配置:

cmake -A x64 -S ... -B buildDir
cmake --build buildDir --config Release
cmake --build buildDir --config Debug

或者,您可以简单地在IDE中打开生成的解决方案。

cmake --open buildDir

对于编译器特定的标志,您可能需要区分大小写:

if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/Wall)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wall)
endif()

最新更新