Home > Software engineering >  How to set debug flags correctly in a Cmake project compiled with Visual Studio
How to set debug flags correctly in a Cmake project compiled with Visual Studio

Time:09-02

I have a C CMake project that is compiled both on Linux and Windows. On Windows, this is done via Visual Studio/MSVCC.

In CMAKE and in VS, the build is set up as Debug, but it seems that no debug symbols are ever being made in the VS build - so debugging is impossible.

When looking over the Detailed output for VS, I saw this:

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

That suggests to me that it doesn't recognize the -g flag like GCC/Clang do.

Here is the CMake arguments:

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

How do I make this compatible with Visual Studio? I've tried looking all over, but most related posts seem to be about C#/.net, or much older versions of VS.

The project does use the QT library if that matters.

UPDATE:

It turns out BUILD_MODE was something added by someone else so that each sub-project would not individually need to be set to release or debug, we could just set it once in the root level Cmakelists.

Also, the answers here were correct. Setting the CMAKE_CXX_FLAGS directly was wiping away the defaults, causing the Debug build to not have options like /Zi in MSVCC, preventing debug symbols and all debugging. It also introduced an unrecognized flag "-g" which MSVCC couldn't understand.

I completely remove the SET_CXX_FLAGS from every Cmakelists.txt in the project, and everything is working perfectly.

Should I need to add to them, I will use the _INIT option as suggested.

CodePudding user response:

You have to compile with a different mode set with CMAKE_BUILD_TYPE as in

cmake -DCMAKE_BUILD_TYPE=DEBUG <sourcedir>

You never set those flags directly. If you want to add a new flag to a debug mode like for example a stack protector, you should use the *_INIT variables.

You can further distinguish which OS you are running with the UNIX, WIN32 and MSVC cmake boolean predefined constants:

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

CodePudding user response:

There should be no need to define -O3 and -g explicitly in cmake. Setting those may prevent the code from working with other compilers, as you've seen. Those 2 options are the default anyways.

To build one of the configurations using unix makefiles you simply set the CMAKE_BUILD_TYPE cache variable during configuration:

(I'm assuming the generators mentioned are the default generators below.)

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

or

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

and to build the project you use

cmake --build buildDir

The visual studio is differnet insofar that the generated project covers all configurations at once. You specify the configuration to work with when building (or installing) the project instead:

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

Alternatively you can simply open the generated solution in the IDE.

cmake --open buildDir

For compiler specific flags you may need to make a case distinction:

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