Change Default Value of Cmake_Cxx_Flags_Debug and Friends in Cmake

Change default value of CMAKE_CXX_FLAGS_DEBUG and friends in CMake

I just wanted to add the four possibilities I see:

  1. Having your own toolchain files containing the presets for each compiler you support like:

    GNUToolchain.cmake

     set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "")

    And then use it with

     cmake -DCMAKE_TOOLCHAIN_FILE:string=GNUToolchain.cmake ...
  2. You can try to determine the compiler by checking CMAKE_GENERATOR (which is valid before the project() command):

    CMakeLists.txt

     if("${CMAKE_GENERATOR}" MATCHES "Makefiles" OR 
    ("${CMAKE_GENERATOR}" MATCHES "Ninja" AND NOT WIN32))
    set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "")
    endif()

    project(your_project C CXX)
  3. You can use CMAKE_USER_MAKE_RULES_OVERRIDE to give a script with your own ..._INIT values:

    It is loaded after CMake’s builtin compiler and platform information modules have been loaded but before the information is used. The file may set platform information variables to override CMake’s defaults.

    MyInitFlags.cmake

     # Overwrite the init values choosen by CMake
    if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    set(CMAKE_CXX_FLAGS_DEBUG_INIT "-ggdb3 -O0")
    endif()

    CMakeLists.txt

     set(CMAKE_USER_MAKE_RULES_OVERRIDE "MyInitFlags.cmake")

    project(your_project C CXX)
  4. You can simplify your solution from March 1st by checking against the ..._INIT variants of the compiler flag variables:

    CMakeLists.txt

     project(your_project C CXX)

    if (DEFINED CMAKE_CXX_FLAGS_DEBUG_INIT AND
    "${CMAKE_CXX_FLAGS_DEBUG_INIT}" STREQUAL "${CMAKE_CXX_FLAGS_DEBUG}")
    # Overwrite the init values choosen by CMake
    if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "" FORCE)
    endif()
    endif()

Comments:

I prefer and use the toolchain variant. But I admit it has the disadvantage of having to give the toolchain file manually (if you are not calling cmake via a script/batch file).

References:

  • CMake: In which order are files parsed (cache, toolchain, etc.)?
  • cmake - Global linker flag setting (for all targets in directory)
  • Switching between GCC and Clang/LLVM using CMake

In CMake, how do you change default compiler flags for a build type on a per-user basis?

I normally set compiler flags in cmakelists.txt by adding an environment variable into my build script, then referencing that in cmakelists.txt.

#build.sh
export MY_CXXFLAGS="-std=gnu++11 -Ofast -NDEBUG -Wall -Wno-unused-function -Wno-unknown-pragmas"
cmake `pwd` -Dtest=ON
make -j9

Then in my CMakeLists.txt, I'll have the following line:

SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{MY_CXXFLAGS}")

It's simple then to pass arguments to build.sh, which is just a bash script, to change the content of MY_CXXFLAGS, based on the users needs. (E.g. build.sh -b DEVELOP|DEBUG|RELEASE etc).

CMake CMAKE_CXX_FLAGS enabled optimization unexpectly

With the code in your question you are hiding the default parameters - including the optimization level - that CMake does apply.

Please try appending your options with

SET ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd" )

or with the use of generator expressions and add_compile_options():

add_compile_options("$<$<CONFIG:Debug>:/MDd>")

But you may not need this particular option, because /MDd is already part of CMake's default MSVC debug flag's setting.

Background

If you look at CMake's Windows-MSVC.cmake you'll see the following initialization settings:

set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}")

Without changing any flags in your CMakeLists.txt you will see in your CMakeCache.txt:

//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1

With your code you are hiding this cached variable and you will end up with just /MDd.

References

  • What's the CMake syntax to set and use variables?
  • cmake - Global linker flag setting (for all targets in directory)
  • CMAKE - setting compile flags for libraries
  • Change default value of CMAKE_CXX_FLAGS_DEBUG and friends in CMake

cmake - Global linker flag setting (for all targets in directory)

Your problems are/were not related to a specific CMake version.

It's the same for all linker/compiler flag variables in CMake. Because those variables are cached variables and set with the project()/enable_language() command (details see here), you either have to

  1. prefill the cache with set(... CACHE ...) before the project() command
  2. generally use the set(... CACHE ... FORCE) to force/overwrite
  3. move the set() after the project() command to hide or append to the cached variables

Here is an example for CMAKE_EXE_LINKER_FLAGS showing all three variants:

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

# 1. prefill
#set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "")

project(Test_Project CXX)

# 2. force
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE)

# 3. hide
#set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map")
# 3. or append
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=output.map")

# TODO: Remove, this is just for testing
file(WRITE "foo.cpp" "int main() {}")

add_executable(${PROJECT_NAME} foo.cpp)

Whatever the values of those variables are at the end of your any given CMakeLists.txt file will be applied to all corresponding targets in the same CMakeLists.txt file as defaults (see CMAKE - setting compile flags for libraries and What's the CMake syntax to set and use variables?).

The first variant has the disadvantage that it's really only the initial value. The second and third variant would most likely need an if (CMAKE_COMPILER_IS_GNUCXX) around it, so I prefer the second variant with moving those settings to its own initial-cache file:

MyGNUSettings.cmake

set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -Wfatal-errors" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE INTERNAL "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE)

Using e.g.

cmake -G "Unix Makefiles" -C MyGNUSettings.cmake -DCMAKE_BUILD_TYPE=Release  .

And yes - for the global and per compiler settings - I prefer the global cached variables over the add_compile_options() command. I think add_compile_options() haven't replaced the global variables, it was mainly introduced to prevent people putting compiler options in add_definitions() commands.

How to enabled gdb -g3 debug level with CMake?

set the CMAKE_C_FLAGS "-Og -g3 ...

CMake AMRCC + custom linker

Apparently this is a bug in the cmake's armcc support, so I will keep my change in the ARMCC.cmake file.



Related Topics



Leave a reply



Submit