C++ – How to create a CMake variable that takes a default value unless explicitly overriden

buildccmakedefault

I have a C++ project that is built using CMake. I would like the build configuration in CMakeLists.txt to be such that it builds in Release mode by default, and builds in Debug mode only when explicitly specified.

Referring to this and this, to allow the build type to be specified from the command line, I have set the variable as follows:

set(CMAKE_BUILD_TYPE Release CACHE STRING "")

However, this caches the build type from the last build, so if the last build was Debug, I need to explicitly specify Release in the next build.

I tried using FORCE and also tried adding

unset(CMAKE_BUILD_TYPE CACHE)

before the set(), but both these methods fix the value to Release and override the value specified by the user.

Is there a way to achieve this? Thank you.


The following is an MCVE:

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
project(Test LANGUAGES CXX)

set(CMAKE_BUILD_TYPE Release CACHE STRING "")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")

file(GLOB SOURCES *.cpp)

add_executable(test ${SOURCES})

test.cpp

#include <iostream>

int main() {
#ifdef DEBUG
    std::cout << "Debug defined" << std::endl;
#else
    std::cout << "Debug not defined" << std::endl;
#endif
    return 0;
}

To build, I use

cmake .
make

The first step could have -DCMAKE_BUILD_TYPE=Debug for Debug mode.

Best Answer

You can use something like this:

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

That way, if nothing is specified to CMake, it will use whatever value you set here, and the provided value otherwise.

To prevent this from being used for all the subsequent builds, add

unset(CMAKE_BUILD_TYPE CACHE)

towards the end of your script, so that it removes any cached value and rely on either the default or the provided one.

Related Topic