Detect a variable changed between configure runs

Hello,

I am trying to detect if a variable in the CMakeLists.txt was changed compared to the previous configure run.

At first I tried using the cache variables, but it didn’t work, then I tried writing it to a file like this:

cmake_minimum_required(VERSION 3.25)
project(test_cache NONE)

set(NEW "Hello")

set(cache_file "${CMAKE_CURRENT_BINARY_DIR}/cache.txt")
if(NOT EXISTS "${cache_file}")
    file(WRITE "${cache_file}" "${NEW}")
else()
    file(READ "${cache_file}" OLD)
    message("OLD: ${OLD}")
    message("NEW: ${NEW}")
    if("${OLD}" STREQUAL "${NEW}")
        message("They are equal, nothing to do")
    else()
        message("They are NOT equal, overwritting")
        file(WRITE "${cache_file}" "${NEW}")
    endif()
endif()

The idea is that I can edit manually the NEW variable in the CMakeLists.txt, and in case the variable changed since the last configure I would execute a process at configure time.
The goal is to not execute this process unless necessary, as it slows down the configure phase.

There might be other ways of doing this, but I am really confused why this doesn’t work?

When I run this code first time, nothing gets printed as expected.
On the second run I get the following

OLD: Hello
NEW: Hello
They are equal, nothing to do

Now, I modify variable set(NEW “World”)

If I rerun the configure again I get:

OLD: WORLD
NEW: WORLD
They are equal, nothing to do

How is this even possible? I could be completely misunderstanding something.
I would appreciate some help to clarify this.

Best regards,
Risto.

The weirdness goes further with this one.

I noticed on my qemu virtual machine, I get the behavior I would expect.
I started playing with the original script, and if I generate a random string for NEW like this:

# set(NEW "Hello")
string(RANDOM LENGTH 5 NEW)

This works perfectly.

Also if I have a sleep between the READ and WRITE, it also fixes the issue.

    file(READ "${cache_file}" OLD)

    execute_process(COMMAND sleep 1) # This helps
    message("OLD: ${OLD}")
    message("NEW: ${NEW}")
    if("${OLD}" STREQUAL "${NEW}")
        message("They are equal, nothing to do")
    else()
        message("They are NOT equal, overwritting")
        file(WRITE "${cache_file}" "${NEW}")
    endif()
endif()

So it seems like the write comes before the read, how should I prevent that.
I was getting the same behaviour with the CACHE variables.

I found the issue, it’s a bit embarrassing.
There is no issue with CMake here or any kind of file buffering.

The problem was a LSP server running in my text editor.
I had cmake-language-server running in the background, and it seems like it triggered reconfigure on every file save.

I might as well switch to neocmakeat this point.