set: CACHE INTERNAL type initialization drops value
Calling set(<var> <val> CACHE INTERNAL "text")
might fail if user applies -D<var>=<val>
when invoking CMake.
For example, the following code:
cmake_minimum_required(VERSION 3.20.0)
function(append_cache_var var val)
if(NOT ${val} IN_LIST ${var}_fail)
set(${var}_fail "${${var}_fail};${val}" CACHE INTERNAL "expected to fail")
endif()
if(NOT ${val} IN_LIST ${var}_pass)
set(${var}_pass "${${var}_pass};${val}" CACHE STRING "expected to pass" FORCE)
endif()
endfunction()
project(CMake-cache-bug)
enable_language(C)
append_cache_var(test_var test-add-1)
append_cache_var(test_var test-add-2)
appends test-add-1
and test-add-2
to the cache lists test_var_pass
and test_var_fail
.
Running CMake on this sample and reading the cache settings works as expected when user don't initializes the cache variables, for example:
$ cmake -Bbuild .
...
-- Build files have been written to: /tmp/cmake-bug/build
$ grep test_var build/CMakeCache.txt
test_var_pass:STRING=;test-add-1;test-add-2
test_var_fail:INTERNAL=;test-add-1;test-add-2
as expected, both test-add-1
and test-add-2
are present in both cache lists.
But if user initializes the lists, for example:
$ rm -rf build; cmake -Bbuild . -Dtest_var_fail=failing -Dtest_var_pass=working
...
-- Build files have been written to: /tmp/cmake-bug/build
$ grep test_var build/CMakeCache.txt
test_var_pass:STRING=working;test-add-1;test-add-2
test_var_fail:INTERNAL=failing;test-add-2
it can now be seen that the test_var_fail
cache variable that was updated using the INTERNAL
flag is now missing the test-add-1
value.
Of course a CMake re-run in the build folder will update the cache correct second time, but it still means the CMake cache variable is wrong on the first invocation. (and the order after second run is different)
Re-running CMake
$ cmake -Bbuild
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake-bug/build
$ grep test_var build/CMakeCache.txt
test_var_pass:STRING=working;test-add-1;test-add-2
test_var_fail:INTERNAL=failing;test-add-2;test-add-1