CMAKE_TOOLCHAIN_FILE: Detect path changes and reset cache

If the path to the toolchain file changes then anything in the cache
that's derived from the toolchain may need to be recomputed.  Detect
this case and start a fresh build.

Issue: #27867
Signed-off-by: Aiden Woodruff <aiden.woodruff@kitware.com>
This commit is contained in:
Aiden Woodruff
2026-06-29 12:09:16 -04:00
committed by Brad King
parent 066b9cf7a1
commit 7a989ed58a
17 changed files with 92 additions and 2 deletions
+4 -1
View File
@@ -224,7 +224,10 @@ if(CMAKE_BINARY_DIR)
# so settings done there are also available if they don't go in the cache and in try_compile()
set(INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED)
if(CMAKE_TOOLCHAIN_FILE)
set(INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED "include(\"${CMAKE_TOOLCHAIN_FILE}\")")
string(CONCAT INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED
"set(_CMAKE_SYSTEM_TOOLCHAIN_FILE \"${CMAKE_TOOLCHAIN_FILE}\")\n"
"include(\"\${_CMAKE_SYSTEM_TOOLCHAIN_FILE}\")"
)
endif()
# configure variables set in this file for fast reload, the template file is defined at the top of this file
+15
View File
@@ -709,6 +709,21 @@ void cmGlobalGenerator::EnableLanguage(
fpath += "/CMakeSystem.cmake";
if (cmSystemTools::FileExists(fpath)) {
mf->ReadListFile(fpath);
// Fail early if CMAKE_TOOLCHAIN_FILE is different than what is stored in
// CMakeSystem.cmake to erase the cache because introspection results may
// become invalid
cmValue toolchainFile = mf->GetDefinition("CMAKE_TOOLCHAIN_FILE");
cmValue storedToolchainFile =
mf->GetDefinition("_CMAKE_SYSTEM_TOOLCHAIN_FILE");
if (toolchainFile && toolchainFile != storedToolchainFile) {
mf->GetState()->AppendGlobalProperty(
"__CMAKE_DELETE_CACHE_CHANGE_VARS_",
"CMAKE_TOOLCHAIN_FILE;" + *toolchainFile);
for (std::string const& lang : cur_languages) {
this->LanguagesInProgress.erase(lang);
}
return;
}
}
}
@@ -2,5 +2,13 @@ cmake_minimum_required(VERSION 3.10)
if(NOT RunCMake_TEST)
set(RunCMake_TEST "$ENV{RunCMake_TEST}") # needed when cache is deleted
endif()
if(RunCMake_TEST MATCHES "^ToolchainFromFile")
# CMAKE_TOOLCHAIN_FILE should be set before project. The ToolchainFromFile
# cases test detecting toolchain path changes between CMake invocations and
# not mid-configure.
file(READ "${CMAKE_BINARY_DIR}/toolchain.txt" toolchain_file)
string(STRIP ${toolchain_file} toolchain_file)
set(CMAKE_TOOLCHAIN_FILE "${toolchain_file}")
endif()
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
@@ -10,4 +10,4 @@ CMake Error at EmptyCompiler\.cmake:2 \(enable_language\):
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
the compiler, or to the compiler name if it is in the PATH\.
Call Stack \(most recent call first\):
CMakeLists\.txt:6 \(include\)$
CMakeLists\.txt:14 \(include\)$
@@ -45,3 +45,29 @@ block()
set(RunCMake_TEST_VARIANT_DESCRIPTION "-step2")
run_cmake_with_options(CompilerPath "-DCMAKE_C_COMPILER=${cc1_dot}")
endblock()
# Set up "toolchain" files
file(WRITE "${RunCMake_BINARY_DIR}/foo.cmake" "set(toolchain_var foo)\n")
file(WRITE "${RunCMake_BINARY_DIR}/bar.cmake" "set(toolchain_var bar)\n")
# New toolchain path comes from file
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ToolchainFromFile-build)
run_cmake(ToolchainFromFile-step1)
set(RunCMake_TEST_NO_CLEAN 1)
set(ENV{RunCMake_TEST} "ToolchainFromFile-step2")
run_cmake(ToolchainFromFile-step2)
endblock()
# New toolchain path comes from command line
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ToolchainFromCmdline-build)
run_cmake_with_options(ToolchainFromCmdline-step1
"-DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/foo.cmake"
)
set(RunCMake_TEST_NO_CLEAN 1)
set(ENV{RunCMake_TEST} "ToolchainFromCmdline-step2")
run_cmake_with_options(ToolchainFromCmdline-step2
"-DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/bar.cmake"
)
endblock()
@@ -0,0 +1,3 @@
-- Toolchain file: [^
]*/Tests/RunCMake/CompilerChange/foo\.cmake
-- Using toolchain: foo
@@ -0,0 +1,2 @@
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "Using toolchain: ${toolchain_var}")
@@ -0,0 +1,5 @@
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:
CMAKE_TOOLCHAIN_FILE= [^
]*/Tests/RunCMake/CompilerChange/bar\.cmake
@@ -0,0 +1,3 @@
-- Toolchain file: [^
]*/Tests/RunCMake/CompilerChange/bar\.cmake
-- Using toolchain: bar
@@ -0,0 +1,2 @@
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "Using toolchain: ${toolchain_var}")
@@ -0,0 +1,4 @@
file(WRITE
"${RunCMake_TEST_BINARY_DIR}/toolchain.txt"
"${RunCMake_BINARY_DIR}/foo.cmake\n"
)
@@ -0,0 +1,3 @@
-- Toolchain file: [^
]*/Tests/RunCMake/CompilerChange/foo\.cmake
-- Using toolchain: foo
@@ -0,0 +1,2 @@
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "Using toolchain: ${toolchain_var}")
@@ -0,0 +1,4 @@
file(WRITE
"${RunCMake_TEST_BINARY_DIR}/toolchain.txt"
"${RunCMake_BINARY_DIR}/bar.cmake\n"
)
@@ -0,0 +1,5 @@
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:
CMAKE_TOOLCHAIN_FILE= [^
]*/Tests/RunCMake/CompilerChange/bar\.cmake
@@ -0,0 +1,3 @@
-- Toolchain file: [^
]*/Tests/RunCMake/CompilerChange/bar\.cmake
-- Using toolchain: bar
@@ -0,0 +1,2 @@
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "Using toolchain: ${toolchain_var}")