How to change toolchain without breaking developer workflows?

Here is the short of it.

I have a toolchain. The toochain specifies these variables:

CMAKE_RC_COMPILER=.../rc.exe
CMAKE_CXX_COMPILER= .../cl.exe
CMAKE_C_COMPILER= .../cl.exe
etc...

I update the toolchain to use a newer compiler/sdk etc.
This didn’t seem to be a problem with Visual Studio as it succeeded just fine. (Which is a problem in itself in my opinion)
However, this fails on Ninja with the following error message.

-- Configuring done
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:

Granted I don’t have to delete the build. I just need to rerun cmake. But is there anything I can do to avoid this problem? Because it’s pretty jaring to developers on our current team to have this error.

If you change the toolchain, you should start with a fresh build. There are too many things that assume the toolchain doesn’t change and while you may be able to find workarounds which appear to work, I recommend you always use a fresh build tree for a different toolchain. This same logic also applies if you update the existing toolchain in-place (e.g. you update to a newer version of GCC on Linux, a newer version of Xcode on macOS, etc.). CMake queries compiler capabilities and caches the results. If you change the toolchain in a way that CMake can’t catch, then you end up with stale cached capabilities being used for the new/updated toolchain. Please don’t do that. :wink:

If you want to switch back and forth between toolchains, set up two different build trees and then you can jump between them as needed. You can have both associated with the same source tree. I do this frequently myself.

Is there a way to create a fresh build for the user? So that the onus is on the cmake writer/maintainer.

Because ideally I don’t want people to have to manually delete their build directories themselves.

It would be really nice if this was possible for example

if (${BREAKING_TOOLCHAIN_ISSUE)
   // Delete cmake cache/build
   // Call configure/generate for the user with the command line arguments the user passed in
   restart_cmake()
endif()

The user should be in control of wiping their own build directory or CMake cache. CMake can do its part by halting if it detects a change. The user action at that point is trivial for the user to do. Perhaps we can improve the warning/error message to make that action clearer, but I would not be in favour of CMake discarding a user’s CMake cache on change of toolchain. Accidentally using a different toolchain is relatively easy to do, especially with the way some IDEs work and you are jumping between command line and IDE for the same build. It happens to me quite regularly. Having to re-create all my cache settings in such accidental cases would be a big inconvenience.