diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 79fabc6b5f..c20066204d 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -296,10 +296,12 @@ qt_copy_or_install(DIRECTORY DESTINATION "${__GlobalConfig_install_dir}/config.tests" ) -# Install qt-internal-strip files. +# Install qt-internal-strip and qt-internal-ninja files. set(__qt_internal_strip_wrappers libexec/qt-internal-strip.in libexec/qt-internal-strip.bat.in + libexec/qt-internal-ninja.in + libexec/qt-internal-ninja.bat.in ) qt_copy_or_install(PROGRAMS ${__qt_internal_strip_wrappers} diff --git a/libexec/qt-internal-ninja.bat.in b/libexec/qt-internal-ninja.bat.in new file mode 100644 index 0000000000..98742e1aec --- /dev/null +++ b/libexec/qt-internal-ninja.bat.in @@ -0,0 +1,3 @@ +:: Make sure we don't echo, because CMake uses the output to parse out ninja's version +@echo off +@original_ninja@ @ninja_arguments@ %* diff --git a/libexec/qt-internal-ninja.in b/libexec/qt-internal-ninja.in new file mode 100755 index 0000000000..742a06d597 --- /dev/null +++ b/libexec/qt-internal-ninja.in @@ -0,0 +1,2 @@ +#!/bin/sh +@original_ninja@ @ninja_arguments@ "$@" diff --git a/src/corelib/Qt6CTestMacros.cmake b/src/corelib/Qt6CTestMacros.cmake index 05130a1555..28a97f45f6 100644 --- a/src/corelib/Qt6CTestMacros.cmake +++ b/src/corelib/Qt6CTestMacros.cmake @@ -17,6 +17,65 @@ foreach(_mod ${CMAKE_MODULES_UNDER_TEST}) message("CMAKE_${_mod}_MODULE_PATCH_VERSION: ${CMAKE_${_mod}_MODULE_PATCH_VERSION}") endforeach() +# 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 : stores the CMAKE_PREFIX_PATH value in the output variable. @@ -238,9 +297,14 @@ macro(_qt_internal_test_expect_pass _dir) endif() # Allow setting a different make program. - set(make_program "${CMAKE_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 @@ -418,13 +482,22 @@ list(APPEND CMAKE_PREFIX_PATH \"${__expect_fail_prefixes}\") " ) + + 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 ${option_list} ) @@ -522,13 +595,22 @@ function(_qt_internal_test_module_includes) ) _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 ${option_list} )