mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
The overall `cmakeBuild` snippet is written only after the native build tool returns, so interrupting `cmake --build` with Ctrl+C terminated CMake before it was recorded and lost the build's delineation. When instrumentation is active, install a scoped, async-signal-safe handler (POSIX SIGINT; Windows CTRL_C/CTRL_BREAK) that just flags the interrupt. The existing write then runs during unwind, records the interrupting signal in a new `interruptSignal` field, skips the post-build index hook, and re-raises so the exit status still reflects the signal. The handler lives in its own translation unit, keeping the platform-divergent signal code out of the main instrumentation implementation. Issue: #27859
126 lines
5.4 KiB
CMake
126 lines
5.4 KiB
CMake
# Performs generic (non-project specific) validation of v1 Snippet File Contents
|
|
include_guard()
|
|
|
|
include(${CMAKE_CURRENT_LIST_DIR}/json.cmake)
|
|
include(${CMAKE_CURRENT_LIST_DIR}/validate_schema.cmake)
|
|
|
|
function(snippet_has_fields snippet contents)
|
|
get_filename_component(filename "${snippet}" NAME)
|
|
json_has_key("${snippet}" "${contents}" role)
|
|
json_has_key("${snippet}" "${contents}" workingDir)
|
|
json_has_key("${snippet}" "${contents}" result)
|
|
# Only an interrupted build records this; completed commands must omit it.
|
|
json_missing_key("${snippet}" "${contents}" interruptSignal)
|
|
if (NOT filename MATCHES "^build-*")
|
|
json_has_key("${snippet}" "${contents}" command)
|
|
else()
|
|
json_missing_key("${snippet}" "${contents}" command)
|
|
endif()
|
|
if (filename MATCHES "^link-*")
|
|
json_has_key("${snippet}" "${contents}" target)
|
|
json_has_key("${snippet}" "${contents}" outputs)
|
|
json_has_key("${snippet}" "${contents}" outputSizes)
|
|
json_has_key("${snippet}" "${contents}" config)
|
|
json_has_key("${snippet}" "${contents}" language)
|
|
elseif (filename MATCHES "^compile-*")
|
|
json_has_key("${snippet}" "${contents}" target)
|
|
json_has_key("${snippet}" "${contents}" outputs)
|
|
json_has_key("${snippet}" "${contents}" outputSizes)
|
|
json_has_key("${snippet}" "${contents}" source)
|
|
json_has_key("${snippet}" "${contents}" language)
|
|
json_has_key("${snippet}" "${contents}" config)
|
|
elseif (filename MATCHES "^custom-*")
|
|
json_has_key("${snippet}" "${contents}" outputs)
|
|
json_has_key("${snippet}" "${contents}" outputSizes)
|
|
json_has_key("${snippet}" "${contents}" config)
|
|
elseif (filename MATCHES "^ctest-*")
|
|
json_has_key("${snippet}" "${contents}" showOnly)
|
|
elseif (filename MATCHES "^test-*")
|
|
json_has_key("${snippet}" "${contents}" testName)
|
|
json_has_key("${snippet}" "${contents}" config)
|
|
elseif (filename MATCHES "^install-*")
|
|
json_has_key("${snippet}" "${contents}" config)
|
|
endif()
|
|
if(ARGS_DYNAMIC_QUERY)
|
|
json_has_key("${snippet}" "${contents}" dynamicSystemInformation)
|
|
string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET "${contents}" dynamicSystemInformation)
|
|
if (NOT noInfo)
|
|
json_has_key("${snippet}" ${dynamicSystemInfo} beforeCPULoadAverage)
|
|
json_has_key("${snippet}" ${dynamicSystemInfo} beforeHostMemoryUsed)
|
|
json_has_key("${snippet}" ${dynamicSystemInfo} afterCPULoadAverage)
|
|
json_has_key("${snippet}" ${dynamicSystemInfo} afterHostMemoryUsed)
|
|
endif()
|
|
else()
|
|
json_missing_key("${snippet}" "${contents}" dynamicSystemInformation)
|
|
string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET "${contents}" dynamicSystemInformation)
|
|
if (NOT noInfo)
|
|
json_missing_key("${snippet}" ${dynamicSystemInfo} beforeCPULoadAverage)
|
|
json_missing_key("${snippet}" ${dynamicSystemInfo} beforeHostMemoryUsed)
|
|
json_missing_key("${snippet}" ${dynamicSystemInfo} afterCPULoadAverage)
|
|
json_missing_key("${snippet}" ${dynamicSystemInfo} afterHostMemoryUsed)
|
|
endif()
|
|
endif()
|
|
return(PROPAGATE RunCMake_TEST_FAILED ERROR_MESSAGE)
|
|
endfunction()
|
|
|
|
function(snippet_valid_timing contents)
|
|
string(JSON start GET "${contents}" timeStart)
|
|
string(JSON duration GET "${contents}" duration)
|
|
if (start LESS 0)
|
|
snippet_error("${snippet}" "Negative time start: ${start}")
|
|
endif()
|
|
if (duration LESS 0)
|
|
json_error("${snippet}" "Negative duration: ${end}")
|
|
endif()
|
|
return(PROPAGATE RunCMake_TEST_FAILED ERROR_MESSAGE)
|
|
endfunction()
|
|
|
|
function(verify_snippet_data snippet contents)
|
|
snippet_has_fields("${snippet}" "${contents}")
|
|
snippet_valid_timing("${contents}")
|
|
string(JSON version_major GET "${contents}" version major)
|
|
string(JSON version_minor GET "${contents}" version minor)
|
|
if (NOT version_major EQUAL 1 OR NOT version_minor LESS_EQUAL 2)
|
|
json_error("${snippet}" "Version must be <= 1.2, got: ${version_major}.${version_minor}")
|
|
endif()
|
|
get_filename_component(filename "${snippet}" NAME)
|
|
string(JSON result GET "${contents}" result)
|
|
if ("${filename}" MATCHES "^build-*" AND result)
|
|
json_error("${snippet}" "Result must be null for build snippets, got: ${result}")
|
|
elseif (NOT "${filename}" MATCHES "^build-*" AND NOT result MATCHES "^-?[0-9]+$")
|
|
json_error("${snippet}" "Result must be integer, got: ${result}")
|
|
endif()
|
|
string(JSON outputs ERROR_VARIABLE noOutputs GET "${contents}" outputs)
|
|
if (outputs)
|
|
string(JSON outputSizes ERROR_VARIABLE noOutputSizes GET "${contents}" outputSizes)
|
|
list(LENGTH outputs outputsLen)
|
|
list(LENGTH outputSizes outputSizesLen)
|
|
if (NOT outputSizes OR NOT outputsLen EQUAL outputSizesLen)
|
|
json_error("${snippet}" "outputs and outputSizes do not match")
|
|
endif()
|
|
endif()
|
|
return(PROPAGATE ERROR_MESSAGE RunCMake_TEST_FAILED role)
|
|
endfunction()
|
|
|
|
function(verify_snippet_file snippet contents)
|
|
verify_snippet_data("${snippet}" "${contents}")
|
|
|
|
string(JSON role GET "${contents}" role)
|
|
get_filename_component(filename "${snippet}" NAME)
|
|
if (NOT filename MATCHES "^${role}-")
|
|
json_error("${snippet}" "Role \"${role}\" doesn't match snippet filename")
|
|
endif()
|
|
|
|
validate_schema(
|
|
"${snippet}"
|
|
"${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/snippet-v1-schema.json"
|
|
# We expect to always generate valid snippet files.
|
|
0
|
|
)
|
|
if (RunCMake_TEST_FAILED)
|
|
add_error("${RunCMake_TEST_FAILED}")
|
|
endif()
|
|
|
|
return(PROPAGATE ERROR_MESSAGE RunCMake_TEST_FAILED role)
|
|
endfunction()
|