How to deal with Ninja setting CMAKE_BUILD_TYPE to Debug?

I am running CMake 3.14.5 on Windows with Ninja and MSVC compiler. I am also building the same project on Linux using Ninja.

As suggested by CMake and the Default Build Type I set the build type to Release if it has not been set:

set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
  set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
      STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
    "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

However, I am finding that Ninja on WIndows sets CMAKE_BUILD_TYPE to Debug, even if not set by the user. So the above code does not work. I could force the build type to Release but that would not respect an intentional setting of Debug by the user.

Why is Ninja doing this and how can I get around it?

1 Like

You can just set the cached variable CMAKE_BUILD_TYPE without the keyword FORCE. So, it will set only if not already defined (through command line -DCMAKE_BUILD_TYPE=... for example).

Moreover, to check if the configuration is multi-config, the preferred way is to pick-up global property GENERATOR_IS_MULTI_CONFIG value rather than using variable CMAKE_CONFIGURATION_TYPES:

get_property (is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)

@marc.chevrier Thanks for your reply and suggestions.

You can just set the cached variable CMAKE_BUILD_TYPE without the keyword FORCE . So, it will set only if not already defined …

My point is that I think Ninja is setting CMAKE_BUILD_TYPE to Debug, i.e. CMAKE_BUILD_TYPE is set before my CMake code is reached so my default of Release is not being used. I don’t know why Ninja is doing this as I believe it is not a multi-configuration generator. It seems to only happen on Windows.

The definition of CMAKE_BUILD_TYPE must occurred before the project command:

set (CMAKE_BUILD_TYPE "Release" CACHE
      STRING "Choose the type of build.")

project (MyProject ...)

Using this snippet, you manage a default value and take care of user’s choice done through command line.

1 Like

@marc.chevrier Thank you. That the definition of CMAKE_BUILD_TYPE must occur before the project command, fixed the problem for me.