mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-09 17:18:18 +00:00
CMAKE_TOOLCHAIN_FILE: Avoid excess reconfigures from relative paths
Save original input value of CMAKE_TOOLCHAIN_FILE also before normalization or relative searching to avoid reconfiguring because the full path doesn't match the input. Tests correct behavior avoiding reconfigures and ensuring reconfigure on toolchain change from preset. Fixes: #24942
This commit is contained in:
@@ -145,6 +145,8 @@ endif()
|
||||
# variables around so they can be used in CMakeLists.txt.
|
||||
# In all other cases, the host and target platform are the same.
|
||||
if(CMAKE_TOOLCHAIN_FILE)
|
||||
# Retain input value to detect changes requiring re-configuration.
|
||||
set(_CMAKE_INPUT_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}")
|
||||
if(IS_ABSOLUTE "${CMAKE_TOOLCHAIN_FILE}" AND EXISTS "${CMAKE_TOOLCHAIN_FILE}")
|
||||
# Normalize the absolute path.
|
||||
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" CACHE FILEPATH "The CMake toolchain file" FORCE)
|
||||
@@ -225,6 +227,7 @@ if(CMAKE_BINARY_DIR)
|
||||
set(INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED)
|
||||
if(CMAKE_TOOLCHAIN_FILE)
|
||||
string(CONCAT INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED
|
||||
"set(_CMAKE_INPUT_TOOLCHAIN_FILE \"${_CMAKE_INPUT_TOOLCHAIN_FILE}\")\n"
|
||||
"set(_CMAKE_SYSTEM_TOOLCHAIN_FILE \"${CMAKE_TOOLCHAIN_FILE}\")\n"
|
||||
"include(\"\${_CMAKE_SYSTEM_TOOLCHAIN_FILE}\")"
|
||||
)
|
||||
|
||||
@@ -701,13 +701,18 @@ 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
|
||||
// If the toolchain file changes, the introspection results may become
|
||||
// invalid, and so the cache must be deleted. The CMAKE_TOOLCHAIN_FILE
|
||||
// value could be input the same way but be different in the cache due to
|
||||
// normalization and relative path searching, so the value is checked
|
||||
// against the original input to decide if the file path has changed.
|
||||
cmValue toolchainFile = mf->GetDefinition("CMAKE_TOOLCHAIN_FILE");
|
||||
cmValue inputToolchainFile =
|
||||
mf->GetDefinition("_CMAKE_INPUT_TOOLCHAIN_FILE");
|
||||
cmValue storedToolchainFile =
|
||||
mf->GetDefinition("_CMAKE_SYSTEM_TOOLCHAIN_FILE");
|
||||
if (toolchainFile && toolchainFile != storedToolchainFile) {
|
||||
if (toolchainFile && toolchainFile != inputToolchainFile &&
|
||||
toolchainFile != storedToolchainFile) {
|
||||
mf->GetState()->AddDeleteCacheChangeVar("CMAKE_TOOLCHAIN_FILE",
|
||||
*toolchainFile);
|
||||
for (std::string const& lang : cur_languages) {
|
||||
|
||||
11
Tests/RunCMake/CompilerChange/CMakePresets.json.in
Normal file
11
Tests/RunCMake/CompilerChange/CMakePresets.json.in
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"generator": "@RunCMake_GENERATOR@",
|
||||
"binaryDir": "${sourceDir}-build",
|
||||
"toolchainFile": "@CompilerChange_Toolchain@"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
file(COPY
|
||||
"${RunCMake_BINARY_DIR}/foo.cmake"
|
||||
DESTINATION "${RunCMake_TEST_BINARY_DIR}"
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message(STATUS "Using toolchain: ${toolchain_var}")
|
||||
@@ -0,0 +1,2 @@
|
||||
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message(STATUS "Using toolchain: ${toolchain_var}")
|
||||
@@ -0,0 +1,9 @@
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(COPY
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_SOURCE_DIR}/RelativeToolchainSource-step1.cmake"
|
||||
"${RunCMake_SOURCE_DIR}/RelativeToolchainSource-step2.cmake"
|
||||
"${RunCMake_BINARY_DIR}/foo.cmake"
|
||||
DESTINATION "${RunCMake_TEST_SOURCE_DIR}"
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message(STATUS "Using toolchain: ${toolchain_var}")
|
||||
@@ -0,0 +1,2 @@
|
||||
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message(STATUS "Using toolchain: ${toolchain_var}")
|
||||
@@ -75,3 +75,52 @@ block()
|
||||
"-DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/bar.cmake"
|
||||
)
|
||||
endblock()
|
||||
|
||||
# Running without toolchain argument does not trigger reconfigure
|
||||
block()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ToolchainFromCmdlineOnce-build)
|
||||
set(RunCMake-stdout-file
|
||||
${RunCMake_SOURCE_DIR}/ToolchainFromCmdlineOnce-stdout.txt
|
||||
)
|
||||
run_cmake_with_options(ToolchainFromCmdlineOnce-step1
|
||||
"-DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/foo.cmake"
|
||||
)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake(ToolchainFromCmdlineOnce-step2)
|
||||
endblock()
|
||||
|
||||
# New toolchain path comes from a preset file
|
||||
block()
|
||||
set(RunCMake_TEST_SOURCE_DIR ${RunCMake_BINARY_DIR}/ToolchainFromPreset)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ToolchainFromPreset-build)
|
||||
run_cmake_with_options(ToolchainFromPreset-step1 --preset default)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_with_options(ToolchainFromPreset-step2 --preset default)
|
||||
endblock()
|
||||
|
||||
# Unchanged relative toolchain file in binary dir does not trigger reconfigure
|
||||
block()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RelativeToolchainBinary)
|
||||
run_cmake_with_options(RelativeToolchainBinary-step1
|
||||
"-DCMAKE_TOOLCHAIN_FILE=foo.cmake"
|
||||
)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_with_options(RelativeToolchainBinary-step2
|
||||
"-DCMAKE_TOOLCHAIN_FILE=foo.cmake"
|
||||
)
|
||||
endblock()
|
||||
|
||||
# Unchanged relative toolchain file in source dir does not trigger reconfigure
|
||||
block()
|
||||
set(RunCMake_TEST_SOURCE_DIR ${RunCMake_BINARY_DIR}/RelativeToolchainSource)
|
||||
set(RunCMake_TEST_BINARY_DIR
|
||||
${RunCMake_BINARY_DIR}/RelativeToolchainSource-build
|
||||
)
|
||||
run_cmake_with_options(RelativeToolchainSource-step1
|
||||
"-DCMAKE_TOOLCHAIN_FILE=foo.cmake"
|
||||
)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_with_options(RelativeToolchainSource-step2
|
||||
"-DCMAKE_TOOLCHAIN_FILE=foo.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,2 @@
|
||||
message(STATUS "Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message(STATUS "Using toolchain: ${toolchain_var}")
|
||||
@@ -0,0 +1,13 @@
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(COPY
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_SOURCE_DIR}/ToolchainFromPreset-step1.cmake"
|
||||
DESTINATION "${RunCMake_TEST_SOURCE_DIR}"
|
||||
)
|
||||
set(CompilerChange_Toolchain "${RunCMake_BINARY_DIR}/foo.cmake")
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakePresets.json.in"
|
||||
"${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json"
|
||||
@ONLY
|
||||
)
|
||||
@@ -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,11 @@
|
||||
file(COPY
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_SOURCE_DIR}/ToolchainFromPreset-step2.cmake"
|
||||
DESTINATION "${RunCMake_TEST_SOURCE_DIR}"
|
||||
)
|
||||
set(CompilerChange_Toolchain "${RunCMake_BINARY_DIR}/bar.cmake")
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakePresets.json.in"
|
||||
"${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json"
|
||||
@ONLY
|
||||
)
|
||||
@@ -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}")
|
||||
Reference in New Issue
Block a user