From b8dae2c617af4cceb886b5ae87ab3dbe79a4ecd0 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 12 Aug 2019 15:51:17 +0200 Subject: [PATCH] Handle test helpers better Teach pro2cmake to use add_qt_test_helper instead of add_qt_executable when the qmake 'qt_test_helper' feature is used. Don't use macOS bundles when building tests on macOS, because that breaks path assumptions for certain tests. Introduce a new OVERRIDE_OUTPUT_DIRECTORY option for add_qt_test_helper that allows placing the binary into a folder other than the test parent folder. I considered changing the default behavior not to place into the parent folder, but that would break all existing tests, so I opted for override approach instead. Ultimately we might want to revisit this later. Change-Id: I68fd1dea608333c2af0d3896050b40a6964dd87f Reviewed-by: Leander Beernaert Reviewed-by: Qt CMake Build Bot Reviewed-by: Simon Hausmann --- cmake/QtBuild.cmake | 60 ++++++++++++++++++++++++++++++++++++++--- util/cmake/pro2cmake.py | 11 ++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index d08c93771f2..cf9a9a90cca 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -2031,11 +2031,27 @@ function(add_qml_module target) endfunction() +# Collection of add_qt_executable arguments so they can be shared across add_qt_executable +# and add_qt_test_helper. +set(__add_qt_executable_optional_args + "GUI;BOOTSTRAP;NO_QT;NO_INSTALL;EXCEPTIONS" +) +set(__add_qt_executable_single_args + "OUTPUT_DIRECTORY;INSTALL_DIRECTORY" +) +set(__add_qt_executable_multi_args + "EXE_FLAGS;${__default_private_args};${__default_public_args}" +) + # This function creates a CMake target for a generic console or GUI binary. # Please consider to use a more specific version target like the one created # by add_qt_test or add_qt_tool below. function(add_qt_executable name) - qt_parse_all_arguments(arg "add_qt_executable" "GUI;BOOTSTRAP;NO_QT;NO_INSTALL;EXCEPTIONS" "OUTPUT_DIRECTORY;INSTALL_DIRECTORY" "EXE_FLAGS;${__default_private_args};${__default_public_args}" ${ARGN}) + qt_parse_all_arguments(arg "add_qt_executable" + "${__add_qt_executable_optional_args}" + "${__add_qt_executable_single_args}" + "${__add_qt_executable_multi_args}" + ${ARGN}) if ("x${arg_OUTPUT_DIRECTORY}" STREQUAL "x") set(arg_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${INSTALL_BINDIR}") @@ -2142,6 +2158,11 @@ function(add_qt_test name) DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS} ) + # Tests should not be bundles on macOS even if arg_GUI is true, because some tests make + # assumptions about the location of helper processes, and those paths would be different + # if a test is built as a bundle. + set_property(TARGET "${name}" PROPERTY MACOSX_BUNDLE FALSE) + # QMLTest specifics extend_target("${name}" CONDITION arg_QMLTEST @@ -2236,10 +2257,41 @@ function(add_qt_test name) endfunction() -# This function creates an executable for use as helper program with tests. Some -# tests launch separate programs to test certainly input/output behavior. +# This function creates an executable for use as a helper program with tests. Some +# tests launch separate programs to test certain input/output behavior. +# Specify OVERRIDE_OUTPUT_DIRECTORY if you dont' want to place the helper in the parent directory, +# in which case you should specify OUTPUT_DIRECTORY "/foo/bar" manually. function(add_qt_test_helper name) - add_qt_executable("${name}" NO_INSTALL OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." ${ARGN}) + + set(add_qt_test_helper_optional_args + "OVERRIDE_OUTPUT_DIRECTORY" + ) + + qt_parse_all_arguments(arg "add_qt_test_helper" + "${add_qt_test_helper_optional_args};${__add_qt_executable_optional_args}" + "${__add_qt_executable_single_args}" + "${__add_qt_executable_multi_args}" + ${ARGN}) + + qt_remove_args(forward_args + ARGS_TO_REMOVE + "${name}" + ${add_qt_test_helper_optional_args} + ALL_ARGS + ${add_qt_test_helper_optional_args} + ${__add_qt_executable_optional_args} + ${__add_qt_executable_single_args} + ${__add_qt_executable_multi_args} + ARGS + ${ARGV} + ) + + set(extra_args_to_pass) + if(NOT arg_OVERRIDE_OUTPUT_DIRECTORY) + set(extra_args_to_pass OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/..") + endif() + + add_qt_executable("${name}" NO_INSTALL ${extra_args_to_pass} ${forward_args}) endfunction() # Sets QT_WILL_BUILD_TOOLS if tools will be built. diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index 29fd8853709..f6d354f19c1 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -2008,7 +2008,14 @@ def write_binary(cm_fh: typing.IO[str], scope: Scope, binary_name = scope.TARGET assert binary_name - extra = ['GUI',] if gui else [] + is_qt_test_helper = 'qt_test_helper' in scope.get('_LOADED') + + extra = ['GUI'] if gui and not is_qt_test_helper else [] + cmake_function_call = 'add_qt_executable' + + if is_qt_test_helper: + binary_name += '_helper' + cmake_function_call = 'add_qt_test_helper' target_path = scope.get_string('target.path') if target_path: @@ -2017,7 +2024,7 @@ def write_binary(cm_fh: typing.IO[str], scope: Scope, if 'target' in scope.get('INSTALLS'): extra.append('INSTALL_DIRECTORY "{}"'.format(target_path)) - write_main_part(cm_fh, binary_name, 'Binary', 'add_qt_executable', scope, + write_main_part(cm_fh, binary_name, 'Binary', cmake_function_call, scope, extra_lines=extra, indent=indent, known_libraries={'Qt::Core', }, extra_keys=['target.path', 'INSTALLS'])