CMake: Move _qt_internal_create_command_script to a public file
It's needed for creating qmake build tests. CMake / CTest has a limitation of not allowing to create single-config tests when using a multi-config generator using the add_test(NAME) signature. Using add_test(NAME) forcefully creates per-config tests, which means that it's not possible to just run ctest to execute tests, without specifying a -C parameter, which we do in the CI. qmake tests need to use the add_test(NAME) signature to specify the WORKING_DIRECTORY option. Because of the above limitation, a work around is to not use the add_test(NAME) signature, but instead delegate the working directory assignment to a generated cmake script, which _qt_internal_create_command_script can already do. Pick-to: 6.4 Task-number: QTBUG-96058 Change-Id: I6f439165994671724157f0edb7a71e351271e329 Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
parent
5145d3899d
commit
edb88a3b29
@ -332,6 +332,7 @@ set(__public_cmake_helpers
|
|||||||
cmake/QtPublicFinalizerHelpers.cmake
|
cmake/QtPublicFinalizerHelpers.cmake
|
||||||
cmake/QtPublicPluginHelpers.cmake
|
cmake/QtPublicPluginHelpers.cmake
|
||||||
cmake/QtPublicTargetHelpers.cmake
|
cmake/QtPublicTargetHelpers.cmake
|
||||||
|
cmake/QtPublicTestHelpers.cmake
|
||||||
cmake/QtPublicToolHelpers.cmake
|
cmake/QtPublicToolHelpers.cmake
|
||||||
cmake/QtPublicWalkLibsHelpers.cmake
|
cmake/QtPublicWalkLibsHelpers.cmake
|
||||||
cmake/QtPublicFindPackageHelpers.cmake
|
cmake/QtPublicFindPackageHelpers.cmake
|
||||||
|
@ -557,6 +557,7 @@ include(QtPublicTargetHelpers)
|
|||||||
include(QtPublicWalkLibsHelpers)
|
include(QtPublicWalkLibsHelpers)
|
||||||
include(QtPublicFindPackageHelpers)
|
include(QtPublicFindPackageHelpers)
|
||||||
include(QtPublicDependencyHelpers)
|
include(QtPublicDependencyHelpers)
|
||||||
|
include(QtPublicTestHelpers)
|
||||||
include(QtPublicToolHelpers)
|
include(QtPublicToolHelpers)
|
||||||
|
|
||||||
if(CMAKE_CROSSCOMPILING)
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
@ -115,6 +115,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/QtPublicTargetHelpers.cmake")
|
|||||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicWalkLibsHelpers.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicWalkLibsHelpers.cmake")
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicFindPackageHelpers.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicFindPackageHelpers.cmake")
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicDependencyHelpers.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicDependencyHelpers.cmake")
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicTestHelpers.cmake")
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicToolHelpers.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicToolHelpers.cmake")
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicCMakeHelpers.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicCMakeHelpers.cmake")
|
||||||
|
|
||||||
|
96
cmake/QtPublicTestHelpers.cmake
Normal file
96
cmake/QtPublicTestHelpers.cmake
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
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;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(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.
|
||||||
|
set(extra_runner "cmd /c")
|
||||||
|
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()
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${arg_OUTPUT_FILE}" CONTENT
|
||||||
|
"#!${CMAKE_COMMAND} -P
|
||||||
|
# Qt generated command wrapper
|
||||||
|
|
||||||
|
${environment_extras}
|
||||||
|
${pre_run}
|
||||||
|
execute_process(COMMAND ${extra_runner} ${arg_COMMAND}
|
||||||
|
WORKING_DIRECTORY \"${arg_WORKING_DIRECTORY}\"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
${post_run}
|
||||||
|
if(NOT result EQUAL 0)
|
||||||
|
string(JOIN \" \" full_command ${arg_COMMAND})
|
||||||
|
message(FATAL_ERROR \"\${full_command} execution failed with exit code \${result}.\")
|
||||||
|
endif()"
|
||||||
|
)
|
||||||
|
endfunction()
|
@ -50,7 +50,7 @@ function(qt_internal_add_benchmark target)
|
|||||||
|
|
||||||
# Add a ${target}_benchmark generator target, to run single benchmark more easily.
|
# Add a ${target}_benchmark generator target, to run single benchmark more easily.
|
||||||
set(benchmark_wrapper_file "${arg_OUTPUT_DIRECTORY}/${target}Wrapper$<CONFIG>.cmake")
|
set(benchmark_wrapper_file "${arg_OUTPUT_DIRECTORY}/${target}Wrapper$<CONFIG>.cmake")
|
||||||
qt_internal_create_command_script(COMMAND "$<TARGET_FILE:${target}>"
|
_qt_internal_create_command_script(COMMAND "$<TARGET_FILE:${target}>"
|
||||||
OUTPUT_FILE "${benchmark_wrapper_file}"
|
OUTPUT_FILE "${benchmark_wrapper_file}"
|
||||||
ENVIRONMENT "PATH" "${benchmark_env_path}"
|
ENVIRONMENT "PATH" "${benchmark_env_path}"
|
||||||
"QT_PLUGIN_PATH" "${benchmark_env_plugin_path}"
|
"QT_PLUGIN_PATH" "${benchmark_env_plugin_path}"
|
||||||
@ -507,7 +507,7 @@ endfunction()
|
|||||||
# directly by 'cmake -P path/to/scriptWrapper.cmake', COMMAND will be executed in specified
|
# directly by 'cmake -P path/to/scriptWrapper.cmake', COMMAND will be executed in specified
|
||||||
# WORKING_DIRECTORY with arguments specified in ARGS.
|
# WORKING_DIRECTORY with arguments specified in ARGS.
|
||||||
#
|
#
|
||||||
# See also qt_internal_create_command_script for details.
|
# See also _qt_internal_create_command_script for details.
|
||||||
function(qt_internal_create_test_script)
|
function(qt_internal_create_test_script)
|
||||||
#This style of parsing keeps ';' in ENVIRONMENT variables
|
#This style of parsing keeps ';' in ENVIRONMENT variables
|
||||||
cmake_parse_arguments(PARSE_ARGV 0 arg
|
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||||
@ -568,7 +568,7 @@ for this function. Will be ignored")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
qt_internal_create_command_script(COMMAND "${crosscompiling_emulator} \${env_test_runner} \
|
_qt_internal_create_command_script(COMMAND "${crosscompiling_emulator} \${env_test_runner} \
|
||||||
\"${executable_file}\" \${env_test_args} ${command_args}"
|
\"${executable_file}\" \${env_test_args} ${command_args}"
|
||||||
OUTPUT_FILE "${arg_OUTPUT_FILE}"
|
OUTPUT_FILE "${arg_OUTPUT_FILE}"
|
||||||
WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}"
|
WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}"
|
||||||
@ -580,99 +580,7 @@ for this function. Will be ignored")
|
|||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# 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' sepatator.
|
|
||||||
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;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(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.
|
|
||||||
set(extra_runner "cmd /c")
|
|
||||||
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()
|
|
||||||
|
|
||||||
file(GENERATE OUTPUT "${arg_OUTPUT_FILE}" CONTENT
|
|
||||||
"#!${CMAKE_COMMAND} -P
|
|
||||||
# Qt generated command wrapper
|
|
||||||
|
|
||||||
${environment_extras}
|
|
||||||
${pre_run}
|
|
||||||
execute_process(COMMAND ${extra_runner} ${arg_COMMAND}
|
|
||||||
WORKING_DIRECTORY \"${arg_WORKING_DIRECTORY}\"
|
|
||||||
RESULT_VARIABLE result
|
|
||||||
)
|
|
||||||
${post_run}
|
|
||||||
if(NOT result EQUAL 0)
|
|
||||||
string(JOIN \" \" full_command ${arg_COMMAND})
|
|
||||||
message(FATAL_ERROR \"\${full_command} execution failed with exit code \${result}.\")
|
|
||||||
endif()"
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# This function creates an executable for use as a helper program with tests. Some
|
# This function creates an executable for use as a helper program with tests. Some
|
||||||
# tests launch separate programs to test certain input/output behavior.
|
# tests launch separate programs to test certain input/output behavior.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user