I'm experiencing a strange behaviour where changing cmake_minimum_required
affects files generated by CMake
targetting Visual Studio 2019. According to the doc of cmake_minimum_required
:
If the running version of CMake is lower than the required version it will stop processing the project and report an error
So it's just supposed to interrupt project generation.
But, if I create:
main.cpp:
int main()
{
#ifndef _DEBUG
#error "DEBUG flag not set"
#endif
return 0;
}
and CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12)
project(hello_world)
set( CMAKE_CONFIGURATION_TYPES "Debug;Release;MyDebug" CACHE INTERNAL "" FORCE )
set( CMAKE_CXX_FLAGS_MYDEBUG "${CMAKE_CXX_FLAGS_DEBUG}" )
set( CMAKE_C_FLAGS_MYDEBUG "${CMAKE_C_FLAGS_DEBUG}" )
set( CMAKE_EXE_LINKER_FLAGS_MYDEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" )
set( CMAKE_SHARED_LINKER_FLAGS_MYDEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" )
set_property( GLOBAL PROPERTY DEBUG_CONFIGURATIONS "Debug;MyDebug" )
add_executable(app main.cpp)
If I generate this project with CMake 3.24.1 for Visual Studio 2019, then it builds correctly using MyDebug
config as _DEBUG
compilation flag is correctly set.
However, if I change cmake_minimum_required(VERSION 2.8.12)
to cmake_minimum_required(VERSION 3.24.1)
, then it fails to build, reporting DEBUG flag not set
, meaning _DEBUG
compilation flag is not set anymore.
When I check vcproj
file, I see that for MyDebug
, <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
is changed to <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
.
Is this a CMake
bug or am I doing something wrong?
CodePudding user response:
Of course cmake
can change behaviour with its evolution.
As CMake evolves it is sometimes necessary to change existing behavior in order to fix bugs or improve implementations of existing features.
*
If it just changes some behaviour in a new version, it introduces a policy, that can explicitly switch cmake to use an old behaviour. The OLD behavior of a policy becomes deprecated by definition and may be removed in a future version of CMake.
See what is changed in the list cmake-policies(7).
Also you can set cmake_minimum_required
incrementing the major version number by one at a time, run cmake and see what policies were introduced in cmake dump. One of them is changing the behaviour of RuntimeLibrary
and _DEBUG
.
CodePudding user response:
So it's just supposed to interrupt project generation.
That's not the case at all!
cmake_minimum_required
puts your project into a backwards compatibility mode consistent with the version specified. The "Policy Settings" section of that doc talks about this. There are a set of now over one hundred CMake policies that enable breaking improvements to the system. You can see the full list here: https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html
The relevant policy here is CMP0091 which was introduced in CMake 3.15.
CMake 3.15 and above prefer to leave the MSVC runtime library selection flags out of the default
CMAKE_<LANG>_FLAGS_<CONFIG>
values and instead offer a first-class abstraction. TheCMAKE_MSVC_RUNTIME_LIBRARY
variable andMSVC_RUNTIME_LIBRARY
target property may be set to select the MSVC runtime library. If they are not set then CMake uses the default valueMultiThreaded$<$<CONFIG:Debug>:Debug>DLL
which is equivalent to the original flags.
So to upgrade your project to a version of CMake newer than 3.15, you'll just need to override the default CMAKE_MSVC_RUNTIME_LIBRARY
close to the top of your CMakeLists.txt file:
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug,MyDebug>:Debug>DLL"
CACHE STRING "Rule for selecting MSVC runtime")
This uses the $<CONFIG>
generator expression to enable the debug runtime for your custom MyDebug
config.