summaryrefslogtreecommitdiffstats
path: root/src/corelib/Qt6CTestMacros.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/Qt6CTestMacros.cmake')
-rw-r--r--src/corelib/Qt6CTestMacros.cmake671
1 files changed, 581 insertions, 90 deletions
diff --git a/src/corelib/Qt6CTestMacros.cmake b/src/corelib/Qt6CTestMacros.cmake
index 50cc40939a..8722553cd0 100644
--- a/src/corelib/Qt6CTestMacros.cmake
+++ b/src/corelib/Qt6CTestMacros.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
#
# W A R N I N G
# -------------
@@ -8,57 +11,161 @@
#
# We mean it.
-message("CMAKE_VERSION: ${CMAKE_VERSION}")
-message("CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
-message("CMAKE_MODULES_UNDER_TEST: ${CMAKE_MODULES_UNDER_TEST}")
-foreach(_mod ${CMAKE_MODULES_UNDER_TEST})
- message("CMAKE_${_mod}_MODULE_MAJOR_VERSION: ${CMAKE_${_mod}_MODULE_MAJOR_VERSION}")
- message("CMAKE_${_mod}_MODULE_MINOR_VERSION: ${CMAKE_${_mod}_MODULE_MINOR_VERSION}")
- message("CMAKE_${_mod}_MODULE_PATCH_VERSION: ${CMAKE_${_mod}_MODULE_PATCH_VERSION}")
-endforeach()
-
-set(BUILD_OPTIONS_LIST)
-
-if (CMAKE_C_COMPILER AND NOT CMAKE_CROSSCOMPILING)
- list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
-endif()
-
-if (CMAKE_CXX_COMPILER AND NOT CMAKE_CROSSCOMPILING)
- list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
-endif()
-
-if (CMAKE_BUILD_TYPE)
- list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
-endif()
-
-if (CMAKE_TOOLCHAIN_FILE)
- file(TO_CMAKE_PATH "${CMAKE_TOOLCHAIN_FILE}" _CMAKE_TOOLCHAIN_FILE)
- list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_TOOLCHAIN_FILE=${_CMAKE_TOOLCHAIN_FILE}")
-endif()
-
-if (CMAKE_VERBOSE_MAKEFILE)
- list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_VERBOSE_MAKEFILE=1")
-endif()
-
-if (NO_GUI)
- list(APPEND BUILD_OPTIONS_LIST "-DNO_GUI=True")
-endif()
-if (NO_WIDGETS)
- list(APPEND BUILD_OPTIONS_LIST "-DNO_WIDGETS=True")
-endif()
-if (NO_DBUS)
- list(APPEND BUILD_OPTIONS_LIST "-DNO_DBUS=True")
-endif()
-
-foreach(module ${CMAKE_MODULES_UNDER_TEST})
- list(APPEND BUILD_OPTIONS_LIST
- "-DCMAKE_${module}_MODULE_MAJOR_VERSION=${CMAKE_${module}_MODULE_MAJOR_VERSION}"
- "-DCMAKE_${module}_MODULE_MINOR_VERSION=${CMAKE_${module}_MODULE_MINOR_VERSION}"
- "-DCMAKE_${module}_MODULE_PATCH_VERSION=${CMAKE_${module}_MODULE_PATCH_VERSION}"
+message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}")
+message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
+message(STATUS "CMAKE_MODULES_UNDER_TEST: ${CMAKE_MODULES_UNDER_TEST}")
+
+# Generate a shell script wrapper that calls ninja with -v parameter.
+# Upstream issue to allow specifying custom build tool options when using ctest's --build-and-test
+# https://gitlab.kitware.com/cmake/cmake/-/issues/22443.
+# Only one file is created that is used by all tests.
+function(_qt_internal_get_ninja_wrapper ninja_path out_wrapper_path)
+ if(QT_INTERNAL_CTEST_NINJA_WRAPPER AND EXISTS "${QT_INTERNAL_CTEST_NINJA_WRAPPER}")
+ set(${out_wrapper_path} "${QT_INTERNAL_CTEST_NINJA_WRAPPER}" PARENT_SCOPE)
+ return()
+ endif()
+
+ if(NOT ninja_path)
+ message(FATAL_ERROR "Invalid ninja path specified: '${ninja_path}'.")
+ endif()
+
+ set(wrapper_extension "")
+
+ if(NOT CMAKE_HOST_UNIX)
+ set(wrapper_extension ".bat")
+ endif()
+
+ set(script_name "qt-internal-ninja")
+
+ # the libexec literal is used on purpose for the source, so the file is found
+ # on Windows hosts.
+ set(wrapper_rel_path "libexec/${script_name}${wrapper_extension}.in")
+
+ # Need to find the libexec input file depending whether the qtbase sources are available.
+ # This mirrors the logic in qt_set_up_build_internals_paths.
+ # TODO: Clean this up, together with qt_set_up_build_internals_paths to only use the
+ # the qtbase sources when building qtbase. And perhaps also when doing a non-prefix
+ # developer-build.
+ set(qtbase_wrapper_in_path "${QT_SOURCE_TREE}/${wrapper_rel_path}")
+ set(installed_wrapper_in_path
+ "${_qt_cmake_dir}/${QT_CMAKE_EXPORT_NAMESPACE}/${wrapper_rel_path}")
+
+ # qtbase sources available, always use them, regardless of prefix or non-prefix builds.
+ if(EXISTS "${qtbase_wrapper_in_path}")
+ set(wrapper_in "${qtbase_wrapper_in_path}")
+
+ # qtbase sources unavailable, use installed files.
+ elseif(EXISTS "${installed_wrapper_in_path}")
+ set(wrapper_in "${installed_wrapper_in_path}")
+ else()
+ message(FATAL_ERROR "Can't find ${script_name}${wrapper_extension}.in file.")
+ endif()
+
+ set(wrapper_out "${CMAKE_BINARY_DIR}/.qt/${script_name}${wrapper_extension}")
+
+ set(original_ninja "${ninja_path}")
+ set(ninja_arguments "-v")
+
+ configure_file("${wrapper_in}" "${wrapper_out}" @ONLY)
+
+ set(QT_INTERNAL_CTEST_NINJA_WRAPPER "${wrapper_out}" CACHE STRING
+ "Internal Qt ninja wrapper for ctest tests")
+
+ set(${out_wrapper_path} "${QT_INTERNAL_CTEST_NINJA_WRAPPER}" PARENT_SCOPE)
+endfunction()
+
+# The function collects configuring options for the test projects generated by Qt cmake tests.
+# Arguments:
+# OUT_PREFIX_PATH <variable name>: stores the CMAKE_PREFIX_PATH value in the output variable.
+function(_qt_internal_get_cmake_test_configure_options out_var)
+ cmake_parse_arguments(arg "" "OUT_PREFIX_PATH" "" ${ARGN})
+ set(option_list)
+
+ if (CMAKE_C_COMPILER AND NOT CMAKE_CROSSCOMPILING)
+ list(APPEND option_list "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
+ endif()
+
+ if (CMAKE_CXX_COMPILER AND NOT CMAKE_CROSSCOMPILING)
+ list(APPEND option_list "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
+ endif()
+
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ if(CMAKE_CONFIGURATION_TYPES)
+ string(REPLACE ";" "\;" configuration_types "${CMAKE_CONFIGURATION_TYPES}")
+ list(APPEND option_list "-DCMAKE_CONFIGURATION_TYPES=${configuration_types}")
+ endif()
+ else()
+ if(CMAKE_BUILD_TYPE)
+ list(APPEND option_list "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
+ endif()
+ endif()
+
+ if (CMAKE_TOOLCHAIN_FILE)
+ file(TO_CMAKE_PATH "${CMAKE_TOOLCHAIN_FILE}" _CMAKE_TOOLCHAIN_FILE)
+ list(APPEND option_list "-DCMAKE_TOOLCHAIN_FILE=${_CMAKE_TOOLCHAIN_FILE}")
+ endif()
+
+ if (CMAKE_VERBOSE_MAKEFILE)
+ list(APPEND option_list "-DCMAKE_VERBOSE_MAKEFILE=1")
+ endif()
+
+ if (NO_GUI)
+ list(APPEND option_list "-DNO_GUI=True")
+ endif()
+ if (NO_WIDGETS)
+ list(APPEND option_list "-DNO_WIDGETS=True")
+ endif()
+ if (NO_DBUS)
+ list(APPEND option_list "-DNO_DBUS=True")
+ endif()
+
+ list(APPEND option_list "-DCMAKE_MESSAGE_LOG_LEVEL=DEBUG")
+ list(APPEND option_list "-DCMAKE_AUTOGEN_VERBOSE=TRUE")
+
+ if(APPLE AND CMAKE_OSX_ARCHITECTURES)
+ list(LENGTH CMAKE_OSX_ARCHITECTURES osx_arch_count)
+
+ # When Qt is built as universal config (macOS or iOS), force CMake build tests to build one
+ # architecture instead of all of them, because the build machine that builds the cmake tests
+ # might not have a universal SDK installed.
+ if(osx_arch_count GREATER 1)
+ list(APPEND option_list "-DQT_FORCE_SINGLE_QT_OSX_ARCHITECTURE=ON")
+ endif()
+ endif()
+
+ foreach(module ${CMAKE_MODULES_UNDER_TEST})
+ list(APPEND option_list
+ "-DCMAKE_${module}_MODULE_MAJOR_VERSION=${CMAKE_${module}_MODULE_MAJOR_VERSION}"
+ "-DCMAKE_${module}_MODULE_MINOR_VERSION=${CMAKE_${module}_MODULE_MINOR_VERSION}"
+ "-DCMAKE_${module}_MODULE_PATCH_VERSION=${CMAKE_${module}_MODULE_PATCH_VERSION}"
+ )
+ endforeach()
+
+ _qt_internal_get_build_vars_for_external_projects(
+ PREFIXES_VAR prefixes
+ ADDITIONAL_PACKAGES_PREFIXES_VAR additional_prefixes
)
-endforeach()
+
+ if(arg_OUT_PREFIX_PATH)
+ set(${arg_OUT_PREFIX_PATH} "${prefixes}" PARENT_SCOPE)
+ endif()
+
+ string(REPLACE ";" "\;" prefixes "${prefixes}")
+ list(APPEND option_list "-DCMAKE_PREFIX_PATH=${prefixes}")
+ list(APPEND option_list "-DQT_ADDITIONAL_PACKAGES_PREFIX_PATH=${additional_prefixes}")
+
+ set(${out_var} "${option_list}" PARENT_SCOPE)
+endfunction()
function(_qt_internal_set_up_test_run_environment testname)
+ set(no_value_options NO_PLUGIN_PATH)
+ set(single_value_options "")
+ set(multi_value_options "")
+ cmake_parse_arguments(PARSE_ARGV 1 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
# This is copy-pasted from qt_add_test and adapted to the standalone project case.
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(QT_PATH_SEPARATOR "\\;")
@@ -97,60 +204,423 @@ function(_qt_internal_set_up_test_run_environment testname)
set_property(TEST "${testname}" APPEND PROPERTY ENVIRONMENT "${test_env_path}")
set_property(TEST "${testname}" APPEND PROPERTY ENVIRONMENT "QT_TEST_RUNNING_IN_CTEST=1")
- # Add the install prefix to list of plugin paths when doing a prefix build
- if(NOT QT_INSTALL_DIR)
- foreach(install_prefix ${install_prefixes})
- list(APPEND plugin_paths "${install_prefix}/${INSTALL_PLUGINSDIR}")
- endforeach()
+ if(NOT arg_NO_PLUGIN_PATH)
+ # Add the install prefix to list of plugin paths when doing a prefix build
+ if(NOT QT_INSTALL_DIR)
+ foreach(install_prefix ${install_prefixes})
+ list(APPEND plugin_paths "${install_prefix}/${INSTALL_PLUGINSDIR}")
+ endforeach()
+ endif()
+
+ # TODO: Collect all paths from known repositories when performing a super build.
+ list(APPEND plugin_paths "${PROJECT_BINARY_DIR}/${INSTALL_PLUGINSDIR}")
+ list(JOIN plugin_paths "${QT_PATH_SEPARATOR}" plugin_paths_joined)
+ set_property(TEST "${testname}"
+ APPEND PROPERTY ENVIRONMENT "QT_PLUGIN_PATH=${plugin_paths_joined}")
endif()
-
- #TODO: Collect all paths from known repositories when performing a super
- # build.
- list(APPEND plugin_paths "${PROJECT_BINARY_DIR}/${INSTALL_PLUGINSDIR}")
- list(JOIN plugin_paths "${QT_PATH_SEPARATOR}" plugin_paths_joined)
- set_property(TEST "${testname}"
- APPEND PROPERTY ENVIRONMENT "QT_PLUGIN_PATH=${plugin_paths_joined}")
-
endfunction()
+# Checks if the test project can be built successfully. Arguments:
+#
+# NO_CLEAN_STEP: Skips calling 'clean' target before building.
+#
+# NO_BUILD_PROJECT_ARG: Skips adding --build-project argument. Useful when using Xcode generator.
+#
+# GENERATOR: Use a custom generator. When not specified, uses existing CMAKE_GENERATOR value.
+#
+# NO_IOS_DEFAULT_ARGS: Skips setting default iOS-specific options like the generator to be used.
+#
+# MAKE_PROGRAM: Specify a different make program. Can be useful with a custom make or ninja wrapper.
+#
+# BUILD_TYPE: Specify a different CMake build type. Defaults to CMAKE_BUILD_TYPE if it is not empty.
+# Which means no build type is passed if the top-level project is configured with a
+# multi-config generator.
+#
+# SIMULATE_IN_SOURCE: If the option is specified, the function copies sources of the tests to the
+# CMAKE_CURRENT_BINARY_DIR directory, creates internal build directory in the
+# copied sources and uses this directory to build and test the project.
+# This makes possible to have relative paths to the source files in the
+# generated ninja rules.
+#
+# BUILD_DIR: A custom build dir relative to the calling project CMAKE_CURRENT_BINARY_DIR.
+# Useful when configuring the same test project with different options in separate
+# build dirs.
+#
+# BINARY: Path to the test artifact that will be executed after the build is complete. If a
+# relative path is specified, it will be counted from the build directory.
+# Can also be passed a random executable to be found in PATH, like 'ctest'.
+#
+# BINARY_ARGS: Additional arguments to pass to the BINARY.
+#
+# TESTNAME: a custom test name to use instead of the one derived from the source directory name
+#
+# BUILD_OPTIONS: a list of -D style CMake definitions to pass to ctest's --build-options (which
+# are ultimately passed to the CMake invocation of the test project). You may
+# escape semicolons inside the definitions using:
+# https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#bracket-argument
+# so the argument containing list will look as following:
+# -DLIST_ARGUMENT=item1[[;]]item2[[;]]...itemN.
macro(_qt_internal_test_expect_pass _dir)
- cmake_parse_arguments(_ARGS "" "BINARY" "" ${ARGN})
- string(REPLACE "(" "_" testname "${_dir}")
- string(REPLACE ")" "_" testname "${testname}")
+ if(WASM)
+ return()
+ endif()
+ set(_test_option_args
+ SIMULATE_IN_SOURCE
+ NO_CLEAN_STEP
+ NO_BUILD_PROJECT_ARG
+ NO_IOS_DEFAULT_ARGS
+ NO_RUN_ENVIRONMENT_PLUGIN_PATH
+ )
+ set(_test_single_args
+ BINARY
+ TESTNAME
+ BUILD_DIR
+ GENERATOR
+ MAKE_PROGRAM
+ BUILD_TYPE
+ )
+ set(_test_multi_args
+ BUILD_OPTIONS
+ BINARY_ARGS
+ )
+ cmake_parse_arguments(_ARGS
+ "${_test_option_args}"
+ "${_test_single_args}"
+ "${_test_multi_args}"
+ ${ARGN}
+ )
- set(__expect_pass__prefixes "${CMAKE_PREFIX_PATH}")
- string(REPLACE ";" "\;" __expect_pass__prefixes "${__expect_pass__prefixes}")
-
- set(ctest_command_args
- --build-and-test
- "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}"
- "${CMAKE_CURRENT_BINARY_DIR}/${_dir}"
- --build-config "${CMAKE_BUILD_TYPE}"
- --build-generator "${CMAKE_GENERATOR}"
- --build-makeprogram "${CMAKE_MAKE_PROGRAM}"
- --build-project "${_dir}"
- --build-options "-DCMAKE_PREFIX_PATH=${__expect_pass__prefixes}" ${BUILD_OPTIONS_LIST}
- --test-command ${_ARGS_BINARY})
- add_test(${testname} ${CMAKE_CTEST_COMMAND} ${ctest_command_args})
- if(_ARGS_BINARY)
- _qt_internal_set_up_test_run_environment("${testname}")
- endif()
+ if(NOT _ARGS_NO_IOS_DEFAULT_ARGS AND IOS)
+ set(_ARGS_NO_BUILD_PROJECT_ARG TRUE)
+ set(_ARGS_GENERATOR Xcode)
+ set(_ARGS_MAKE_PROGRAM xcodebuild)
+ endif()
+
+ if(_ARGS_TESTNAME)
+ set(testname "${_ARGS_TESTNAME}")
+ else()
+ string(REPLACE "(" "_" testname "${_dir}")
+ string(REPLACE ")" "_" testname "${testname}")
+ string(REPLACE "/" "_" testname "${testname}")
+ endif()
+
+ # Allow setting a different generator. Needed for iOS.
+ set(generator "${CMAKE_GENERATOR}")
+ if(_ARGS_GENERATOR)
+ set(generator "${_ARGS_GENERATOR}")
+ endif()
+
+ # Allow setting a different make program.
+ if(_ARGS_MAKE_PROGRAM)
+ set(make_program "${_ARGS_MAKE_PROGRAM}")
+ elseif(CMAKE_GENERATOR MATCHES "Ninja")
+ # Use a ninja wrapper when generator is ninja
+ _qt_internal_get_ninja_wrapper("${CMAKE_MAKE_PROGRAM}" ninja_wrapper)
+ set(make_program "${ninja_wrapper}")
+ else()
+ set(make_program "${CMAKE_MAKE_PROGRAM}")
+ endif()
+
+ # Only pass build config if it was specified during the initial tests/auto project
+ # configuration. Important when using Qt multi-config builds which won't have CMAKE_BUILD_TYPE
+ # set.
+ set(build_type "")
+
+ if(_ARGS_BUILD_TYPE)
+ set(build_type "${_ARGS_BUILD_TYPE}")
+ elseif(CMAKE_BUILD_TYPE)
+ set(build_type "${CMAKE_BUILD_TYPE}")
+ endif()
+ if(build_type)
+ set(build_type "--build-config" "${build_type}")
+ endif()
+
+ # Allow skipping clean step.
+ set(build_no_clean "")
+ if(_ARGS_NO_CLEAN_STEP)
+ set(build_no_clean "--build-noclean")
+ endif()
+
+ # Allow omitting the --build-project arg. It's relevant for xcode projects where the project
+ # name on disk is different from the project source dir name.
+ if(NOT _ARGS_NO_BUILD_PROJECT_ARG)
+ set(build_project "--build-project" "${_dir}")
+ else()
+ set(build_project)
+ endif()
+
+ # Allow omitting test command if no binary or binary args are provided.
+ set(test_command "")
+ if(_ARGS_BINARY)
+ list(APPEND test_command ${_ARGS_BINARY} ${_ARGS_BINARY_ARGS})
+ endif()
+ if(test_command)
+ set(test_command "--test-command" ${test_command})
+ endif()
+
+ set(additional_configure_args "")
+
+ # Allow passing additional configure options to all projects via either a cache var or env var.
+ # Can be useful for certain catch-all scenarios.
+ if(QT_CMAKE_TESTS_ADDITIONAL_CONFIGURE_OPTIONS)
+ list(APPEND additional_configure_args ${QT_CMAKE_TESTS_ADDITIONAL_CONFIGURE_OPTIONS})
+ endif()
+ if(DEFINED ENV{QT_CMAKE_TESTS_ADDITIONAL_CONFIGURE_OPTIONS})
+ list(APPEND additional_configure_args $ENV{QT_CMAKE_TESTS_ADDITIONAL_CONFIGURE_OPTIONS})
+ endif()
+
+ # When building an iOS CMake test in the CI using a universal Qt build, target the simulator
+ # sdk, because the CI currently doesn't have a proper setup for signing device binaries
+ # (missing a working signing certificate and provisioning profile). Allow opt-out.
+ if(IOS)
+ set(osx_arch_count 0)
+ if(QT_OSX_ARCHITECTURES)
+ list(LENGTH QT_OSX_ARCHITECTURES osx_arch_count)
+ endif()
+
+ set(build_environment "")
+ if(DEFINED ENV{QT_BUILD_ENVIRONMENT})
+ set(build_environment "$ENV{QT_BUILD_ENVIRONMENT}")
+ endif()
+ if(build_environment STREQUAL "ci"
+ AND osx_arch_count GREATER_EQUAL 2
+ AND NOT QT_APPLE_SDK
+ AND NOT QT_NO_IOS_BUILD_ADJUSTMENT_IN_CI)
+ list(APPEND additional_configure_args
+ -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_SYSROOT=iphonesimulator)
+ endif()
+ endif()
+
+ set(__expect_pass_build_dir "${CMAKE_CURRENT_BINARY_DIR}/${_dir}")
+ if(_ARGS_BUILD_DIR)
+ set(__expect_pass_build_dir "${CMAKE_CURRENT_BINARY_DIR}/${_ARGS_BUILD_DIR}")
+ endif()
+
+ set(__expect_pass_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}")
+ if(_ARGS_SIMULATE_IN_SOURCE)
+ set(__expect_pass_in_source_build_dir "${CMAKE_CURRENT_BINARY_DIR}/in_source")
+ set(__expect_pass_build_dir "${__expect_pass_in_source_build_dir}/${_dir}/build")
+ set(__expect_pass_source_dir "${__expect_pass_in_source_build_dir}/${_dir}")
+
+ unset(__expect_pass_in_source_build_dir)
+ endif()
+
+ if(_ARGS_BINARY AND NOT IS_ABSOLUTE "${_ARGS_BINARY}")
+ set(_ARGS_BINARY "${__expect_pass_build_dir}/${_ARGS_BINARY}")
+ endif()
+
+ if(_ARGS_SIMULATE_IN_SOURCE)
+ add_test(NAME ${testname}_cleanup
+ COMMAND ${CMAKE_COMMAND} -E remove_directory "${__expect_pass_source_dir}"
+ )
+ set_tests_properties(${testname}_cleanup PROPERTIES
+ FIXTURES_SETUP "${testname}SIMULATE_IN_SOURCE_FIXTURE"
+ )
+ add_test(${testname}_copy_sources ${CMAKE_COMMAND} -E copy_directory
+ "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}" "${__expect_pass_source_dir}"
+ )
+ set_tests_properties(${testname}_copy_sources PROPERTIES
+ FIXTURES_SETUP "${testname}SIMULATE_IN_SOURCE_FIXTURE"
+ DEPENDS ${testname}_cleanup
+ )
+ endif()
+
+ string(REPLACE "[[;]]" "\;" _ARGS_BUILD_OPTIONS "${_ARGS_BUILD_OPTIONS}")
+
+ _qt_internal_get_cmake_test_configure_options(option_list)
+ set(ctest_command_args
+ --build-and-test
+ "${__expect_pass_source_dir}"
+ "${__expect_pass_build_dir}"
+ ${build_type}
+ ${build_no_clean}
+ --build-generator "${generator}"
+ --build-makeprogram "${make_program}"
+ ${build_project}
+ --build-options "${option_list}"
+ "${_ARGS_BUILD_OPTIONS}" ${additional_configure_args}
+ ${test_command}
+ )
+ add_test(${testname} ${CMAKE_CTEST_COMMAND} ${ctest_command_args})
+ if(_ARGS_SIMULATE_IN_SOURCE)
+ set_tests_properties(${testname} PROPERTIES
+ FIXTURES_REQUIRED "${testname}SIMULATE_IN_SOURCE_FIXTURE"
+ )
+ endif()
+ set_tests_properties(${testname} PROPERTIES ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0")
+
+ if(_ARGS_BINARY)
+ set(run_env_args "")
+ if(_ARGS_NO_RUN_ENVIRONMENT_PLUGIN_PATH)
+ list(APPEND run_env_args NO_PLUGIN_PATH)
+ endif()
+ _qt_internal_set_up_test_run_environment("${testname}" ${run_env_args})
+ endif()
+
+ unset(__expect_pass_source_dir)
+ unset(__expect_pass_build_dir)
+endmacro()
+
+# Checks if a qmake project can be built successfully. Arguments:
+#
+# TESTNAME: a custom test name to use instead of the one derived from the source directory name.
+# the name also applies to the generated build directory.
+#
+# QMAKE_OPTIONS: a list of variable assignments to pass to the qmake invocation.
+# e.g. CONFIG+=debug
+#
+# BUILD_ENVIRONMENT: a list of environment assignments to use when invoking the build tool
+function(_qt_internal_add_qmake_test dir_name)
+ set(test_option_args
+ )
+ set(test_single_args
+ TESTNAME
+ )
+ set(test_multi_args
+ QMAKE_OPTIONS
+ BUILD_ENVIRONMENT
+ )
+
+ # PARSE_ARGV parsing keeps ';' in ENVIRONMENT variables
+ cmake_parse_arguments(PARSE_ARGV 1 arg
+ "${test_option_args}"
+ "${test_single_args}"
+ "${test_multi_args}"
+ )
+
+ if(arg_TESTNAME)
+ set(testname "${arg_TESTNAME}")
+ else()
+ string(REGEX REPLACE "[/)(]" "_" testname "${dir_name}")
+ endif()
+
+ set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${dir_name}")
+ if(arg_TESTNAME)
+ set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${arg_TESTNAME}")
+ else()
+ set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${dir_name}")
+ endif()
+
+ # Find the qmake binary or the wrapper qmake script when cross-compiling..
+ if(QtBase_BINARY_DIR AND NOT QT_BUILD_STANDALONE_TESTS)
+ set(qmake_dir "${QtBase_BINARY_DIR}/${INSTALL_BINDIR}")
+ else()
+ set(qmake_dir "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_BINS}")
+ endif()
+
+ set(qmake_path "${qmake_dir}/qmake${CMAKE_EXECUTABLE_SUFFIX}")
+
+ set(qmake_args
+ "${source_dir}"
+ ${arg_QMAKE_OPTIONS}
+ )
+
+ # Try to choose an appropriate build tool.
+ if(ENV{QT_QMAKE_TEST_BUILD_TOOL})
+ set(build_tool "$ENV{QT_QMAKE_TEST_BUILD_TOOL}")
+ elseif(MSVC)
+ set(build_tool "nmake")
+ elseif(MINGW)
+ set(build_tool "mingw32-make")
+ else()
+ set(build_tool "make")
+ endif()
+
+ set(build_tool_args "")
+ if(ENV{QT_QMAKE_TEST_BUILD_TOOL_OPTIONS})
+ set(build_tool_args "$ENV{QT_QMAKE_TEST_BUILD_TOOL_OPTIONS}")
+ endif()
+
+ # Remove any stale build dir, and create a new one on each test rerun.
+ add_test(${testname}_remove_build_dir
+ ${CMAKE_COMMAND} -E remove_directory "${build_dir}"
+ )
+ set_tests_properties(${testname}_remove_build_dir PROPERTIES
+ FIXTURES_SETUP "${testname}_ensure_clean_build_dir"
+ )
+
+ add_test(${testname}_create_build_dir
+ ${CMAKE_COMMAND} -E make_directory "${build_dir}"
+ )
+ set_tests_properties(${testname}_create_build_dir PROPERTIES
+ FIXTURES_SETUP "${testname}_ensure_clean_build_dir"
+ )
+
+ set_tests_properties(${testname}_create_build_dir
+ PROPERTIES DEPENDS ${testname}_remove_build_dir)
+
+ # Add test to call qmake.
+ #
+ # We can't use the add_test(NAME) signature to set a working directory, because that breaks
+ # when calling ctest without a -C <config> using multi-config generators, and the CI calls
+ # ctest without -C, and we use Xcode when configuring tests for iOS, which is multi-config.
+ # The plain add_test signature does not have this issue.
+ # Work around this by using a wrapper script that sets a working directory and use the plain
+ # signature.
+ # Somewhat related issue https://gitlab.kitware.com/cmake/cmake/-/issues/20283
+ set(qmake_wrapper_file "${CMAKE_CURRENT_BINARY_DIR}/run_qmake_${testname}.cmake")
+ _qt_internal_create_command_script(
+ COMMAND "${qmake_path}" ${qmake_args}
+ COMMAND_ECHO STDOUT
+ OUTPUT_FILE "${qmake_wrapper_file}"
+ WORKING_DIRECTORY "${build_dir}"
+ )
+
+ add_test(${testname}_qmake "${CMAKE_COMMAND}" "-P" "${qmake_wrapper_file}")
+
+ set_tests_properties(${testname}_qmake PROPERTIES
+ DEPENDS ${testname}_create_build_dir
+ FIXTURES_REQUIRED "${testname}_ensure_clean_build_dir"
+ FIXTURES_SETUP "${testname}_configure_project"
+ )
+
+ # Add test to build the generated qmake project.
+ set(build_tool_wrapper_file "${CMAKE_CURRENT_BINARY_DIR}/run_build_${testname}.cmake")
+ _qt_internal_create_command_script(
+ COMMAND "${build_tool}" ${build_tool_args}
+ COMMAND_ECHO STDOUT
+ OUTPUT_FILE "${build_tool_wrapper_file}"
+ WORKING_DIRECTORY "${build_dir}"
+ ENVIRONMENT ${arg_BUILD_ENVIRONMENT}
+ )
+
+ add_test(${testname} "${CMAKE_COMMAND}" "-P" "${build_tool_wrapper_file}")
+
+ set_tests_properties(${testname} PROPERTIES
+ DEPENDS ${testname}_qmake
+ FIXTURES_REQUIRED "${testname}_ensure_clean_build_dir;${testname}_configure_project"
+ )
+endfunction()
+
+# Checks if the build of the test project fails.
+# This test passes if the test project fails either at the
+# configuring or build steps.
+# Arguments: See _qt_internal_test_expect_pass
+macro(_qt_internal_test_expect_fail)
+ _qt_internal_test_expect_pass(${ARGV})
+ set_tests_properties(${testname} PROPERTIES WILL_FAIL TRUE)
endmacro()
-macro(_qt_internal_test_expect_fail _dir)
+# Checks if the build of the test project fails.
+# This test passes only if the test project fails at the build step,
+# but not at the configuring step.
+macro(_qt_internal_test_expect_build_fail _dir)
string(REPLACE "(" "_" testname "${_dir}")
string(REPLACE ")" "_" testname "${testname}")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}")
+ set(__expect_fail_prefixes "")
+ _qt_internal_get_cmake_test_configure_options(option_list OUT_PREFIX_PATH __expect_fail_prefixes)
+
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}/${_dir}/FindPackageHints.cmake"
- "set(Qt6Tests_PREFIX_PATH \"${CMAKE_PREFIX_PATH}\")
-list(APPEND CMAKE_PREFIX_PATH \"${CMAKE_PREFIX_PATH}\")
+ "set(Qt6Tests_PREFIX_PATH \"${__expect_fail_prefixes}\")
+list(APPEND CMAKE_PREFIX_PATH \"${__expect_fail_prefixes}\")
")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}/CMakeLists.txt"
"
- cmake_minimum_required(VERSION 3.14)
+ cmake_minimum_required(VERSION 3.16)
project(${_dir})
try_compile(Result \${CMAKE_CURRENT_BINARY_DIR}/${_dir}
@@ -164,16 +634,27 @@ list(APPEND CMAKE_PREFIX_PATH \"${CMAKE_PREFIX_PATH}\")
endif()
"
)
+
+
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ # Use a ninja wrapper when generator is ninja
+ _qt_internal_get_ninja_wrapper("${CMAKE_MAKE_PROGRAM}" ninja_wrapper)
+ set(make_program "${ninja_wrapper}")
+ else()
+ set(make_program "${CMAKE_MAKE_PROGRAM}")
+ endif()
+
add_test(${testname} ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}"
"${CMAKE_CURRENT_BINARY_DIR}/failbuild/${_dir}/build"
--build-config "${CMAKE_BUILD_TYPE}"
--build-generator "${CMAKE_GENERATOR}"
- --build-makeprogram "${CMAKE_MAKE_PROGRAM}"
+ --build-makeprogram "${make_program}"
--build-project "${_dir}"
- --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST}
+ --build-options ${option_list}
)
+ unset(__expect_fail_prefixes)
endmacro()
function(_qt_internal_test_module_includes)
@@ -224,7 +705,7 @@ function(_qt_internal_test_module_includes)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/module_includes/CMakeLists.txt"
"
- cmake_minimum_required(VERSION 3.14)
+ cmake_minimum_required(VERSION 3.16)
project(module_includes)
${packages_string}
@@ -266,14 +747,24 @@ function(_qt_internal_test_module_includes)
int main(int, char **) { ${instances_string} return 0; }\n"
)
+ _qt_internal_get_cmake_test_configure_options(option_list)
+
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ # Use a ninja wrapper when generator is ninja
+ _qt_internal_get_ninja_wrapper("${CMAKE_MAKE_PROGRAM}" ninja_wrapper)
+ set(make_program "${ninja_wrapper}")
+ else()
+ set(make_program "${CMAKE_MAKE_PROGRAM}")
+ endif()
+
add_test(module_includes ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMAKE_CURRENT_BINARY_DIR}/module_includes/"
"${CMAKE_CURRENT_BINARY_DIR}/module_includes/build"
--build-config "${CMAKE_BUILD_TYPE}"
--build-generator "${CMAKE_GENERATOR}"
- --build-makeprogram "${CMAKE_MAKE_PROGRAM}"
+ --build-makeprogram "${make_program}"
--build-project module_includes
- --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST}
+ --build-options ${option_list}
)
endfunction()