Build/Configuration Types

Hello,

I’ve been using CMake for quite a while and it’s quite common that I enforce the possible different build/configuration type on my project using similar code to this:

set(CMAKE_CONFIGURATION_TYPES "Debug" "Release")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES})
if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type of the project" FORCE)
elseif(NOT CMAKE_BUILD_TYPE IN_LIST CMAKE_CONFIGURATION_TYPES)
    message(FATAL_ERROR "Invalid build type \'${CMAKE_BUILD_TYPE}\'. Possible values: ${CMAKE_CONFIGURATION_TYPES}")
endif()

I wonder if that’s the correct way to handle strict enforcement/management of possible build types and it’s correct, why isn’t there standard command or procedure to do such? I don’t want people to build my project with incorrect build type, it makes no sense. And I do want to be able to support generation on both single and multiple configuration generators.
Is there something I’m missing?

Here is a refinement of your pattern:

cmake_minimum_required(VERSION 3.15)

set(MyProject_BUILD_TYPES Debug Release)
get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(multi_config)
  set(CMAKE_CONFIGURATION_TYPES "${MyProject_BUILD_TYPES}" CACHE STRING "list of supported configuration types" FORCE)
else()
  set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type of the project.")
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${MyProject_BUILD_TYPES}")
  if(NOT CMAKE_BUILD_TYPE IN_LIST MyProject_BUILD_TYPES)
    message(FATAL_ERROR "Invalid build type '${CMAKE_BUILD_TYPE}'. Possible values:\n ${MyProject_BUILD_TYPES}")
  endif()
endif()

project(MyProject)

It’s important to do it before the project() command so that the default CMAKE_BUILD_TYPE initialization does not happen first.

Thank you for your help.
Is there any reason there isn’t something built-in to do this?
Something like:

project(TestProject BUILD_TYPES Release Debug)

I have not seen this use case come up often. Most projects I’ve seen just use the default behavior and don’t try to restrict the set of configurations like this. Doing so can make it harder to embed projects as subdirectories in other projects.