mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-04 05:10:10 -05:00
bf52fbfbc4
Add a feature to parse snippets into a trace file compatible with the Google Trace Event Format. Fixes: #26674
226 lines
6.9 KiB
CMake
226 lines
6.9 KiB
CMake
cmake_minimum_required(VERSION 3.30)
|
|
include(RunCMake)
|
|
|
|
function(instrument test)
|
|
# Set Paths Variables
|
|
set(config "${CMAKE_CURRENT_LIST_DIR}/config")
|
|
set(ENV{CMAKE_CONFIG_DIR} ${config})
|
|
set(OPTIONS
|
|
"BUILD"
|
|
"BUILD_MAKE_PROGRAM"
|
|
"INSTALL"
|
|
"INSTALL_PARALLEL"
|
|
"TEST"
|
|
"NO_WARN"
|
|
"COPY_QUERIES"
|
|
"COPY_QUERIES_GENERATED"
|
|
"STATIC_QUERY"
|
|
"DYNAMIC_QUERY"
|
|
"TRACE_QUERY"
|
|
"MANUAL_HOOK"
|
|
"PRESERVE_DATA"
|
|
"NO_CONFIGURE"
|
|
)
|
|
cmake_parse_arguments(ARGS "${OPTIONS}" "CHECK_SCRIPT;CONFIGURE_ARG" "" ${ARGN})
|
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test})
|
|
set(uuid "d16a3082-c4e1-489b-b90c-55750a334f27")
|
|
set(v1 ${RunCMake_TEST_BINARY_DIR}/.cmake/instrumentation-${uuid}/v1)
|
|
set(query_dir ${CMAKE_CURRENT_LIST_DIR}/query)
|
|
|
|
# Clear previous instrumentation data
|
|
# We can't use RunCMake_TEST_NO_CLEAN 0 because we preserve queries placed in the build tree after
|
|
if (ARGS_PRESERVE_DATA)
|
|
file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/CMakeFiles)
|
|
else()
|
|
file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR})
|
|
endif()
|
|
|
|
# Set hook command
|
|
set(static_query_hook_arg 0)
|
|
if (ARGS_STATIC_QUERY)
|
|
set(static_query_hook_arg 1)
|
|
endif()
|
|
set(trace_query_hook_arg 0)
|
|
if (ARGS_TRACE_QUERY)
|
|
set(trace_query_hook_arg 1)
|
|
endif()
|
|
set(GET_HOOK "\\\"${CMAKE_COMMAND}\\\" -P \\\"${RunCMake_SOURCE_DIR}/hook.cmake\\\" ${static_query_hook_arg} ${trace_query_hook_arg}")
|
|
|
|
# Load query JSON and cmake (with cmake_instrumentation(...)) files
|
|
set(query ${query_dir}/${test}.json.in)
|
|
set(cmake_file ${query_dir}/${test}.cmake)
|
|
if (EXISTS ${query})
|
|
file(MAKE_DIRECTORY ${v1}/query)
|
|
configure_file(${query} ${v1}/query/${test}.json)
|
|
elseif (EXISTS ${cmake_file})
|
|
list(APPEND ARGS_CONFIGURE_ARG "-DINSTRUMENT_COMMAND_FILE=${cmake_file}")
|
|
endif()
|
|
|
|
set(copy_loc ${RunCMake_TEST_BINARY_DIR}/query)
|
|
if (ARGS_COPY_QUERIES_GENERATED)
|
|
set(ARGS_COPY_QUERIES TRUE)
|
|
set(copy_loc ${v1}/query/generated) # Copied files here should be cleared on configure
|
|
endif()
|
|
if (ARGS_COPY_QUERIES)
|
|
file(MAKE_DIRECTORY ${copy_loc})
|
|
set(generated_queries "0;1;2")
|
|
foreach(n IN LISTS generated_queries)
|
|
configure_file(
|
|
"${query_dir}/generated/query-${n}.json.in"
|
|
"${copy_loc}/query-${n}.json"
|
|
)
|
|
endforeach()
|
|
endif()
|
|
|
|
# Configure Test Case
|
|
set(RunCMake_TEST_NO_CLEAN 1)
|
|
if (ARGS_NO_WARN)
|
|
list(APPEND ARGS_CONFIGURE_ARG "-Wno-dev")
|
|
endif()
|
|
set(RunCMake_TEST_SOURCE_DIR ${RunCMake_SOURCE_DIR}/project)
|
|
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
|
set(maybe_CMAKE_BUILD_TYPE -DCMAKE_BUILD_TYPE=Debug)
|
|
endif()
|
|
if (NOT ARGS_NO_CONFIGURE)
|
|
run_cmake_with_options(${test} ${ARGS_CONFIGURE_ARG} ${maybe_CMAKE_BUILD_TYPE})
|
|
endif()
|
|
|
|
# Follow-up Commands
|
|
if (ARGS_BUILD)
|
|
run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Debug)
|
|
endif()
|
|
if (ARGS_BUILD_MAKE_PROGRAM)
|
|
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
|
# Force reconfigure to test for double preBuild & postBuild hooks
|
|
file(TOUCH ${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt)
|
|
run_cmake_command(${test}-make-program ${RunCMake_MAKE_PROGRAM})
|
|
unset(RunCMake_TEST_OUTPUT_MERGE)
|
|
endif()
|
|
if (ARGS_INSTALL)
|
|
run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . --prefix install --config Debug)
|
|
endif()
|
|
if (ARGS_TEST)
|
|
run_cmake_command(${test}-test ${CMAKE_CTEST_COMMAND} . -C Debug)
|
|
endif()
|
|
if (ARGS_MANUAL_HOOK)
|
|
run_cmake_command(${test}-index ${CMAKE_CTEST_COMMAND} --collect-instrumentation .)
|
|
endif()
|
|
|
|
# Run Post-Test Checks
|
|
# Check scripts need to run after ALL run_cmake_command have finished
|
|
if (ARGS_CHECK_SCRIPT)
|
|
set(RunCMake-check-file ${ARGS_CHECK_SCRIPT})
|
|
set(RunCMake_CHECK_ONLY 1)
|
|
run_cmake(${test}-verify)
|
|
unset(RunCMake-check-file)
|
|
unset(RunCMake_CHECK_ONLY)
|
|
endif()
|
|
endfunction()
|
|
|
|
# Bad Queries
|
|
instrument(bad-option)
|
|
instrument(bad-hook)
|
|
instrument(empty)
|
|
instrument(bad-version)
|
|
|
|
# Verify Hooks Run and Index File
|
|
instrument(hooks-1 BUILD INSTALL TEST STATIC_QUERY)
|
|
instrument(hooks-2 BUILD INSTALL TEST)
|
|
instrument(hooks-no-callbacks MANUAL_HOOK)
|
|
|
|
# Check data file contents for optional query data
|
|
instrument(no-query
|
|
BUILD INSTALL TEST
|
|
CHECK_SCRIPT check-data-dir.cmake
|
|
)
|
|
instrument(dynamic-query
|
|
BUILD INSTALL TEST DYNAMIC_QUERY
|
|
CHECK_SCRIPT check-data-dir.cmake
|
|
)
|
|
instrument(both-query
|
|
BUILD INSTALL TEST DYNAMIC_QUERY
|
|
CHECK_SCRIPT check-data-dir.cmake
|
|
)
|
|
|
|
# Test cmake_instrumentation command
|
|
instrument(cmake-command
|
|
COPY_QUERIES NO_WARN STATIC_QUERY DYNAMIC_QUERY
|
|
CHECK_SCRIPT check-generated-queries.cmake
|
|
)
|
|
instrument(cmake-command-data
|
|
COPY_QUERIES NO_WARN BUILD INSTALL TEST DYNAMIC_QUERY
|
|
CHECK_SCRIPT check-data-dir.cmake
|
|
)
|
|
instrument(cmake-command-bad-api-version NO_WARN)
|
|
instrument(cmake-command-bad-data-version NO_WARN)
|
|
instrument(cmake-command-missing-version NO_WARN)
|
|
instrument(cmake-command-bad-arg NO_WARN)
|
|
instrument(cmake-command-parallel-install
|
|
BUILD INSTALL TEST NO_WARN INSTALL_PARALLEL DYNAMIC_QUERY
|
|
CHECK_SCRIPT check-data-dir.cmake)
|
|
instrument(cmake-command-resets-generated
|
|
NO_WARN COPY_QUERIES_GENERATED
|
|
CHECK_SCRIPT check-data-dir.cmake
|
|
)
|
|
instrument(cmake-command-cmake-build
|
|
NO_WARN BUILD
|
|
CHECK_SCRIPT check-no-make-program-hooks.cmake
|
|
)
|
|
|
|
# Test CUSTOM_CONTENT
|
|
instrument(cmake-command-custom-content
|
|
NO_WARN BUILD
|
|
CONFIGURE_ARG "-DN=1"
|
|
)
|
|
instrument(cmake-command-custom-content
|
|
NO_WARN BUILD PRESERVE_DATA
|
|
CONFIGURE_ARG "-DN=2"
|
|
CHECK_SCRIPT check-custom-content.cmake
|
|
)
|
|
instrument(cmake-command-custom-content
|
|
NO_WARN NO_CONFIGURE MANUAL_HOOK PRESERVE_DATA
|
|
CHECK_SCRIPT check-custom-content-removed.cmake
|
|
)
|
|
instrument(cmake-command-custom-content-bad-type NO_WARN)
|
|
instrument(cmake-command-custom-content-bad-content NO_WARN)
|
|
|
|
# Test Google trace
|
|
instrument(trace-query
|
|
BUILD INSTALL TEST TRACE_QUERY
|
|
CHECK_SCRIPT check-generated-queries.cmake
|
|
)
|
|
instrument(cmake-command-trace
|
|
NO_WARN BUILD INSTALL TEST TRACE_QUERY
|
|
)
|
|
instrument(cmake-command-trace
|
|
NO_WARN BUILD PRESERVE_DATA
|
|
CHECK_SCRIPT check-trace-removed.cmake
|
|
)
|
|
|
|
# Test make/ninja hooks
|
|
if(RunCMake_GENERATOR STREQUAL "MSYS Makefiles")
|
|
# FIXME(#27079): This does not work for MSYS Makefiles.
|
|
set(Skip_BUILD_MAKE_PROGRAM_Case 1)
|
|
elseif(RunCMake_GENERATOR STREQUAL "NMake Makefiles")
|
|
execute_process(
|
|
COMMAND "${RunCMake_MAKE_PROGRAM}" -?
|
|
OUTPUT_VARIABLE nmake_out
|
|
ERROR_VARIABLE nmake_out
|
|
RESULT_VARIABLE nmake_res
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
if(nmake_res EQUAL 0 AND nmake_out MATCHES "Program Maintenance Utility[^\n]+Version ([1-9][0-9.]+)")
|
|
set(nmake_version "${CMAKE_MATCH_1}")
|
|
else()
|
|
message(FATAL_ERROR "'nmake -?' reported:\n${nmake_out}")
|
|
endif()
|
|
if(nmake_version VERSION_LESS 9)
|
|
set(Skip_BUILD_MAKE_PROGRAM_Case 1)
|
|
endif()
|
|
endif()
|
|
if(NOT Skip_BUILD_MAKE_PROGRAM_Case)
|
|
instrument(cmake-command-make-program
|
|
NO_WARN BUILD_MAKE_PROGRAM
|
|
CHECK_SCRIPT check-make-program-hooks.cmake)
|
|
endif()
|