mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-09 01:01:12 +00:00
Reply file names embed the configuration name verbatim. Reconfiguring a build tree with a build type that differs from the previous one only in case (e.g. Debug -> debug) makes CMake write a reply whose name also differs only in case from the existing file. On a case-insensitive filesystem the write is skipped because the name already exists, but RemoveOldReplyFiles compared on-disk names to the just-written names textually and deleted the surviving file, leaving the reply index citing a target or directory reply that no longer exists on disk. Prune reply files by file identity via cmSystemTools::GetFileId instead of by name, so an on-disk entry that aliases a reply we just wrote is kept. An entry whose identity cannot be obtained is retained rather than deleted. Fixes: #28022
234 lines
7.4 KiB
CMake
234 lines
7.4 KiB
CMake
include(RunCMake)
|
|
|
|
cmake_policy(SET CMP0140 NEW)
|
|
|
|
include("${RunCMake_SOURCE_DIR}/../validate_json_schema.cmake")
|
|
|
|
# Function called in *-check.cmake scripts to check api files.
|
|
function(check_api expect)
|
|
file(GLOB_RECURSE actual
|
|
LIST_DIRECTORIES TRUE
|
|
RELATIVE ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1
|
|
${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/*
|
|
)
|
|
if(NOT "${actual}" MATCHES "${expect}")
|
|
set(RunCMake_TEST_FAILED "API files:
|
|
${actual}
|
|
do not match what we expected:
|
|
${expect}
|
|
in directory:
|
|
${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1")
|
|
endif()
|
|
if(NOT RunCMake_TEST_FAILED AND Python_EXECUTABLE AND CMake_TEST_JSON_SCHEMA)
|
|
cmake_path(SET schema_dir NORMALIZE ${RunCMake_SOURCE_DIR}/../../../Help/manual/file_api)
|
|
set(prefix ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1)
|
|
set(replies ${actual})
|
|
list(FILTER replies INCLUDE REGEX "^reply/")
|
|
set(schema_types
|
|
index # Special case, error replies also use this schema
|
|
codemodel
|
|
directory
|
|
target
|
|
configureLog
|
|
cache
|
|
cmakeFiles
|
|
toolchains
|
|
)
|
|
foreach(schema_type IN LISTS schema_types)
|
|
set(schema_type_${schema_type} "")
|
|
endforeach()
|
|
foreach(file IN LISTS replies)
|
|
if(file MATCHES "^reply/(index|error)-")
|
|
list(APPEND schema_type_index ${prefix}/${file})
|
|
else()
|
|
foreach(schema_type IN LISTS schema_types)
|
|
if(file MATCHES "^reply/${schema_type}-")
|
|
list(APPEND schema_type_${schema_type} ${prefix}/${file})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endforeach()
|
|
foreach(schema_type IN LISTS schema_types)
|
|
if("${schema_type_${schema_type}}" STREQUAL "")
|
|
# No files to validate against the schema
|
|
continue()
|
|
endif()
|
|
validate_json_schema(
|
|
"${schema_dir}/schema_${schema_type}.json"
|
|
"${schema_type_${schema_type}}"
|
|
)
|
|
endforeach()
|
|
endif()
|
|
return(PROPAGATE RunCMake_TEST_FAILED)
|
|
endfunction()
|
|
|
|
function(check_stateful_queries)
|
|
if(RunCMake_TEST_FAILED OR NOT Python_EXECUTABLE OR NOT CMake_TEST_JSON_SCHEMA)
|
|
return()
|
|
endif()
|
|
|
|
cmake_path(SET schema_dir NORMALIZE
|
|
${RunCMake_SOURCE_DIR}/../../../Help/manual/file_api
|
|
)
|
|
set(prefix ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query/client)
|
|
list(TRANSFORM ARGN
|
|
REPLACE "^(.+)$" "${prefix}-\\1/query.json"
|
|
OUTPUT_VARIABLE query_json_files
|
|
)
|
|
validate_json_schema(
|
|
"${schema_dir}/schema_stateful_query.json"
|
|
"${query_json_files}"
|
|
)
|
|
return(PROPAGATE RunCMake_TEST_FAILED)
|
|
endfunction()
|
|
|
|
function(check_python case prefix)
|
|
if(RunCMake_TEST_FAILED OR NOT Python_EXECUTABLE)
|
|
return()
|
|
endif()
|
|
file(GLOB index ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply/${prefix}-*.json)
|
|
execute_process(
|
|
COMMAND ${Python_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py"
|
|
--build-dir "${RunCMake_TEST_BINARY_DIR}"
|
|
--reply-index "${index}"
|
|
--cxx-compiler-id "${CMAKE_CXX_COMPILER_ID}"
|
|
--cxx-simulate-id "${CMAKE_CXX_SIMULATE_ID}"
|
|
RESULT_VARIABLE result
|
|
OUTPUT_VARIABLE output
|
|
ERROR_VARIABLE output
|
|
)
|
|
if(NOT result EQUAL 0)
|
|
string(REPLACE "\n" "\n " output " ${output}")
|
|
set(RunCMake_TEST_FAILED "Unexpected index:\n${output}" PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
|
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo")
|
|
endif()
|
|
|
|
if(JsonCpp_VERSION AND JsonCpp_VERSION VERSION_LESS 1.7.5)
|
|
set(ENV{CMake_JSONCPP_PRE_1_7_5} 1)
|
|
endif()
|
|
|
|
run_cmake(Nothing)
|
|
run_cmake(Empty)
|
|
run_cmake(EmptyClient)
|
|
run_cmake(Stale)
|
|
run_cmake(SharedStateless)
|
|
run_cmake(ClientStateless)
|
|
run_cmake(MixedStateless)
|
|
run_cmake(DuplicateStateless)
|
|
run_cmake(ClientStateful)
|
|
run_cmake_with_options(InitialCache -C ${RunCMake_SOURCE_DIR}/InitialCache-script.cmake)
|
|
run_cmake(ProjectQueryGood)
|
|
run_cmake(ProjectQueryBad)
|
|
run_cmake(FailConfigure)
|
|
|
|
# Reconfiguring with a case-only build-type change (Debug -> debug) must not
|
|
# leave the reply index citing a target file that cleanup deleted on a
|
|
# case-insensitive filesystem (Windows, default macOS).
|
|
function(run_config_case)
|
|
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ConfigCaseReconfigure-build)
|
|
run_cmake_with_options(ConfigCaseReconfigure -DCMAKE_BUILD_TYPE=Debug)
|
|
set(RunCMake_TEST_NO_CLEAN 1)
|
|
run_cmake_command(ConfigCaseReconfigure-recon ${CMAKE_COMMAND} . -DCMAKE_BUILD_TYPE=debug)
|
|
endif()
|
|
endfunction()
|
|
run_config_case()
|
|
|
|
function(run_object object)
|
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${object}-build)
|
|
list(APPEND RunCMake_TEST_OPTIONS ${ARGN} -DCMAKE_POLICY_DEFAULT_CMP0118=NEW)
|
|
run_cmake(${object})
|
|
list(POP_BACK RunCMake_TEST_OPTIONS)
|
|
set(RunCMake_TEST_NO_CLEAN 1)
|
|
run_cmake_command(${object}-SharedStateless ${CMAKE_COMMAND} .)
|
|
run_cmake_command(${object}-ClientStateless ${CMAKE_COMMAND} .)
|
|
run_cmake_command(${object}-ClientStateful ${CMAKE_COMMAND} .)
|
|
run_cmake_command(${object}-FailConfigure ${CMAKE_COMMAND} . -DFAIL=1)
|
|
endfunction()
|
|
|
|
run_object(codemodel-v2)
|
|
run_object(configureLog-v1)
|
|
run_object(cache-v2)
|
|
run_object(cmakeFiles-v1)
|
|
run_object(toolchains-v1)
|
|
run_object(toolchains-v1 -DTOOLCHAINSV1_COMPILERARGS=1)
|
|
run_object(toolchains-v1 -DTOOLCHAINSV1_COMPILERARGS=2)
|
|
|
|
function(run_import_std_codemodel_test)
|
|
if(NOT CMake_TEST_MODULE_COMPILATION)
|
|
return()
|
|
endif()
|
|
|
|
set(stdlib_custom_json)
|
|
if(CMake_TEST_CXX_STDLIB_MODULES_JSON)
|
|
list(APPEND stdlib_custom_json
|
|
-DCMAKE_CXX_STDLIB_MODULES_JSON=${CMake_TEST_CXX_STDLIB_MODULES_JSON})
|
|
endif()
|
|
|
|
run_cmake(codemodel-v2-import-std-Inspect ${stdlib_custom_json})
|
|
include("${RunCMake_BINARY_DIR}/codemodel-v2-import-std-Inspect-build/info.cmake")
|
|
|
|
if(RunCMake_GENERATOR MATCHES "Ninja")
|
|
execute_process(
|
|
COMMAND "${CMAKE_MAKE_PROGRAM}" --version
|
|
RESULT_VARIABLE res
|
|
OUTPUT_VARIABLE ninja_version
|
|
ERROR_VARIABLE err
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
ERROR_STRIP_TRAILING_WHITESPACE)
|
|
|
|
if(res)
|
|
message(WARNING
|
|
"Failed to determine `ninja` version: ${err}")
|
|
set(ninja_version "0")
|
|
endif()
|
|
endif()
|
|
|
|
set(generator_supports_cxx_modules 0)
|
|
if(RunCMake_GENERATOR MATCHES "Ninja" AND
|
|
ninja_version VERSION_GREATER_EQUAL "1.11" AND
|
|
"cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
|
set(generator_supports_cxx_modules 1)
|
|
endif()
|
|
|
|
if(RunCMake_GENERATOR MATCHES "Visual Studio" AND
|
|
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34")
|
|
set(generator_supports_cxx_modules 1)
|
|
endif()
|
|
|
|
if(NOT generator_supports_cxx_modules)
|
|
return()
|
|
endif()
|
|
|
|
string(REPLACE "," ";" cxx_module_features "${CMake_TEST_MODULE_COMPILATION}")
|
|
if(RunCMake_GENERATOR MATCHES "Ninja")
|
|
list(APPEND cxx_module_features
|
|
"ninja")
|
|
endif()
|
|
|
|
if(NOT "import_std23" IN_LIST cxx_module_features OR
|
|
NOT "cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
|
return()
|
|
endif()
|
|
|
|
set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/codemodel-v2-import-std")
|
|
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/codemodel-v2-import-std-build")
|
|
|
|
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
|
set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
|
|
else()
|
|
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
|
|
endif()
|
|
|
|
list(APPEND RunCMake_TEST_OPTIONS
|
|
${stdlib_custom_json}
|
|
"-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}")
|
|
run_cmake(codemodel-v2-import-std)
|
|
endfunction()
|
|
|
|
run_import_std_codemodel_test()
|