forked from qt/qtbase
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathQtPublicTestHelpers.cmake
155 lines (135 loc) · 5.59 KB
/
QtPublicTestHelpers.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# This function wraps COMMAND with cmake script, that makes possible standalone run with external
# arguments.
#
# Generated wrapper will be written to OUTPUT_FILE.
# If WORKING_DIRECTORY is not set COMMAND will be executed in CMAKE_CURRENT_BINARY_DIR.
# Variables from ENVIRONMENT will be set before COMMAND execution.
# PRE_RUN and POST_RUN arguments may contain extra cmake code that supposed to be executed before
# and after COMMAND, respectively. Both arguments accept a list of cmake script language
# constructions. Each item of the list will be concantinated into single string with '\n' separator.
# COMMAND_ECHO option takes a value like it does for execute_process, and passes that value to
# execute_process.
function(_qt_internal_create_command_script)
#This style of parsing keeps ';' in ENVIRONMENT variables
cmake_parse_arguments(PARSE_ARGV 0 arg
""
"OUTPUT_FILE;WORKING_DIRECTORY;COMMAND_ECHO"
"COMMAND;ENVIRONMENT;PRE_RUN;POST_RUN"
)
if(NOT arg_COMMAND)
message(FATAL_ERROR "qt_internal_create_command_script: COMMAND is not specified")
endif()
if(NOT arg_OUTPUT_FILE)
message(FATAL_ERROR "qt_internal_create_command_script: Wrapper OUTPUT_FILE\
is not specified")
endif()
if(NOT arg_WORKING_DIRECTORY AND NOT QNX)
set(arg_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
set(environment_extras)
set(skipNext false)
if(arg_ENVIRONMENT)
list(LENGTH arg_ENVIRONMENT length)
math(EXPR length "${length} - 1")
foreach(envIdx RANGE ${length})
if(skipNext)
set(skipNext FALSE)
continue()
endif()
set(envVariable "")
set(envValue "")
list(GET arg_ENVIRONMENT ${envIdx} envVariable)
math(EXPR envIdx "${envIdx} + 1")
if (envIdx LESS_EQUAL ${length})
list(GET arg_ENVIRONMENT ${envIdx} envValue)
endif()
if(NOT "${envVariable}" STREQUAL "")
set(environment_extras "${environment_extras}\nset(ENV{${envVariable}} \
\"${envValue}\")")
endif()
set(skipNext TRUE)
endforeach()
endif()
#Escaping environment variables before expand them by file GENERATE
string(REPLACE "\\" "\\\\" environment_extras "${environment_extras}")
if(CMAKE_HOST_WIN32)
# It's necessary to call actual test inside 'cmd.exe', because 'execute_process' uses
# SW_HIDE to avoid showing a console window, it affects other GUI as well.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/17690 for details.
#
# Run the command using the proxy 'call' command to avoid issues related to invalid
# processing of quotes and spaces in cmd.exe arguments.
set(extra_runner "cmd /c call")
endif()
if(arg_PRE_RUN)
string(JOIN "\n" pre_run ${arg_PRE_RUN})
endif()
if(arg_POST_RUN)
string(JOIN "\n" post_run ${arg_POST_RUN})
endif()
set(command_echo "")
if(arg_COMMAND_ECHO)
set(command_echo "COMMAND_ECHO ${arg_COMMAND_ECHO}")
endif()
set(command_escaped "")
foreach(command_arg IN LISTS arg_COMMAND)
if(NOT command_arg MATCHES "^\\\${[^}]+}$" AND NOT command_arg MATCHES "^\".+\"$")
string(REPLACE "\"" "\\\"" command_arg "${command_arg}")
string(APPEND command_escaped " \"${command_arg}\"")
else()
# Assume that all arguments that passed as escaped variables can be empty when
# unwrapped during the script execution.
string(APPEND command_escaped " ${command_arg}")
endif()
endforeach()
file(GENERATE OUTPUT "${arg_OUTPUT_FILE}" CONTENT
"#!${CMAKE_COMMAND} -P
# Qt generated command wrapper
${environment_extras}
${pre_run}
execute_process(COMMAND ${extra_runner} ${command_escaped}
WORKING_DIRECTORY \"${arg_WORKING_DIRECTORY}\"
${command_echo}
RESULT_VARIABLE result
)
${post_run}
if(NOT result EQUAL 0)
string(JOIN \" \" full_command ${extra_runner} ${command_escaped})
message(FATAL_ERROR \"\${full_command} execution failed with exit code \${result}.\")
endif()"
)
endfunction()
function(_qt_internal_test_batch_target_name out)
set(${out} "test_batch" PARENT_SCOPE)
endfunction()
# Create a *_check target of the ctest execution for alternative execution
# Arguments:
# : CTEST_TEST_NAME: (default: ${testname})
# name of the ctest test used
function(_qt_internal_make_check_target testname)
set(options "")
set(singleOpts CTEST_TEST_NAME)
set(multiOpts "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${options}" "${singleOpts}" "${multiOpts}"
)
if(NOT arg_CTEST_TEST_NAME)
set(arg_CTEST_TEST_NAME ${testname})
endif()
set(test_config_options "")
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
set(test_config_options -C $<CONFIG>)
endif()
# Note: By default the working directory here is CMAKE_CURRENT_BINARY_DIR, which will
# work as long as this is called anywhere up or down the path where the equivalent
# `add_test` is called (not down a different branch path).
add_custom_target(${testname}_check
VERBATIM
COMMENT "Running ctest -V -R \"^${arg_CTEST_TEST_NAME}$\" ${test_config_options}"
COMMAND
"${CMAKE_CTEST_COMMAND}" -V -R "^${arg_CTEST_TEST_NAME}$" ${test_config_options}
)
endfunction()