diff options
Diffstat (limited to 'cmake/QtWrapperScriptHelpers.cmake')
-rw-r--r-- | cmake/QtWrapperScriptHelpers.cmake | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/cmake/QtWrapperScriptHelpers.cmake b/cmake/QtWrapperScriptHelpers.cmake new file mode 100644 index 0000000000..8eb4416e6d --- /dev/null +++ b/cmake/QtWrapperScriptHelpers.cmake @@ -0,0 +1,333 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Creates and installs the following wrapper CMake scripts: +# qt-make +# qt-cmake-private +# qt-configure-module +# qt-cmake-private-install +# And other helper scripts. +function(qt_internal_create_wrapper_scripts) + # Provide a convenience cmake wrapper. + + if(QT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS) + set(generate_unix TRUE) + set(generate_non_unix TRUE) + elseif(CMAKE_HOST_UNIX) + set(generate_unix TRUE) + else() + set(generate_non_unix TRUE) + endif() + + set(extra_qt_cmake_code "") + if(generate_unix) + + if(UIKIT) + set(extra_qt_cmake_code [=[ +# Specify Xcode as the default generator by assigning it to the CMAKE_GENERATOR env var. +# An explicit -G or -D CMAKE_GENERATOR given on the command line will still take precedence. +export CMAKE_GENERATOR=Xcode +]=]) + endif() + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake" @ONLY + NEWLINE_STYLE LF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake" + DESTINATION "${INSTALL_BINDIR}") + endif() + if(generate_non_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake.bat" @ONLY + NEWLINE_STYLE CRLF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake.bat" + DESTINATION "${INSTALL_BINDIR}") + endif() + + if(generate_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-create.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create" @ONLY + NEWLINE_STYLE LF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create" + DESTINATION "${INSTALL_BINDIR}") + endif() + if(generate_non_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-create.bat.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create.bat" @ONLY + NEWLINE_STYLE CRLF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create.bat" + DESTINATION "${INSTALL_BINDIR}") + endif() + + # Reset the contents for the next script. + set(extra_qt_cmake_code "") + + # Provide a private convenience wrapper with options that should not be propagated via the + # public qt-cmake wrapper e.g. CMAKE_GENERATOR. + # These options can not be set in a toolchain file, but only on the command line. + # These options should not be in the public wrapper, because a consumer of Qt might want to + # build their CMake app with the Unix Makefiles generator, while Qt should be built with the + # Ninja generator. In a similar vein, we do want to use the same compiler for all Qt modules, + # but not for user applications. + # The private wrapper is more convenient for building Qt itself, because a developer doesn't + # need to specify the same options for each qt module built. + set(__qt_cmake_extra "-G\"${CMAKE_GENERATOR}\" -DQT_USE_ORIGINAL_COMPILER=ON") + if(generate_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in" + "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-cmake-private" @ONLY + NEWLINE_STYLE LF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-cmake-private" + DESTINATION "${INSTALL_LIBEXECDIR}") + endif() + if(generate_non_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" @ONLY + NEWLINE_STYLE CRLF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" + DESTINATION "${INSTALL_BINDIR}") + endif() + unset(__qt_cmake_extra) + + # Provide a script to configure Qt modules. + if(QT_WILL_INSTALL) + set(__relative_path_to_cmake_scripts_dir + "${__GlobalConfig_relative_path_from_bin_dir_to_cmake_config_dir}") + else() + file(RELATIVE_PATH __relative_path_to_cmake_scripts_dir + "${__qt_bin_dir_absolute}" "${CMAKE_CURRENT_LIST_DIR}") + endif() + file(TO_NATIVE_PATH "${__relative_path_to_cmake_scripts_dir}" + __relative_path_to_cmake_scripts_dir) + if(generate_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-configure-module.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-configure-module" @ONLY + NEWLINE_STYLE LF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-configure-module" + DESTINATION "${INSTALL_BINDIR}") + endif() + if(generate_non_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-configure-module.bat.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-configure-module.bat" @ONLY + NEWLINE_STYLE CRLF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-configure-module.bat" + DESTINATION "${INSTALL_BINDIR}") + endif() + unset(__relative_path_to_cmake_scripts_dir) + + # Provide a private convenience wrapper to configure and build one or more standalone tests. + # Calling CMake directly on a Qt test project won't work because the project does not call + # find_package(Qt...) to get all dependencies like examples do. + # Instead a template CMakeLists.txt project is used which sets up all the necessary private bits + # and then calls add_subdirectory on the provided project path. + set(__qt_cmake_standalone_test_name "qt-cmake-standalone-test") + if(generate_unix) + set(__qt_cmake_standalone_test_libexec_path + "${INSTALL_LIBEXECDIR}/${__qt_cmake_standalone_test_name}") + endif() + if(generate_non_unix) + set(__qt_cmake_standalone_test_bin_path + "${INSTALL_BINDIR}/${__qt_cmake_standalone_test_name}") + endif() + + # Configuring a standalone test on iOS should use the Xcode generator, but qt-cmake-private uses + # the generator that was used to build Qt itself (e.g. Ninja). + # Use qt-cmake instead, which does use the Xcode generator since Qt 6.2.5, 6.3.1, 6.4. + if(IOS) + set(__qt_cmake_private_path + "${QT_STAGING_PREFIX}/${INSTALL_BINDIR}/qt-cmake") + else() + if(generate_unix) + set(__qt_cmake_private_path + "${QT_STAGING_PREFIX}/${INSTALL_LIBEXECDIR}/qt-cmake-private") + endif() + if(generate_non_unix) + set(__qt_cmake_private_path + "${QT_STAGING_PREFIX}/${INSTALL_BINDIR}/qt-cmake-private") + endif() + endif() + + set(__qt_cmake_standalone_test_path + "${__build_internals_install_dir}/${__build_internals_standalone_test_template_dir}") + + if(QT_WILL_INSTALL) + # Need to prepend the staging prefix when doing prefix builds, because the build internals + # install dir is relative in that case.. + qt_path_join(__qt_cmake_standalone_test_path + "${QT_STAGING_PREFIX}" + "${__qt_cmake_standalone_test_path}") + endif() + + if(generate_unix) + get_filename_component(rel_base_path + "${QT_STAGING_PREFIX}/${__qt_cmake_standalone_test_libexec_path}" + DIRECTORY) + + file(RELATIVE_PATH __qt_cmake_private_relpath "${rel_base_path}" + "${__qt_cmake_private_path}") + file(RELATIVE_PATH __qt_cmake_standalone_test_relpath "${rel_base_path}" + "${__qt_cmake_standalone_test_path}") + + set(__qt_cmake_standalone_test_os_prelude "#!/bin/sh") + set(__qt_cmake_standalone_test_script_relpath "SCRIPT_DIR=`dirname $0`") + string(PREPEND __qt_cmake_private_relpath "exec $SCRIPT_DIR/") + string(PREPEND __qt_cmake_standalone_test_relpath "$SCRIPT_DIR/") + set(__qt_cmake_standalone_passed_args "\"$@\" -DPWD=\"$PWD\"") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-standalone-test.in" + "${QT_BUILD_DIR}/${__qt_cmake_standalone_test_libexec_path}" + NEWLINE_STYLE LF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${__qt_cmake_standalone_test_libexec_path}" + DESTINATION "${INSTALL_LIBEXECDIR}") + endif() + if(generate_non_unix) + get_filename_component(rel_base_path + "${QT_STAGING_PREFIX}/${__qt_cmake_standalone_test_bin_path}" + DIRECTORY) + + file(RELATIVE_PATH __qt_cmake_private_relpath "${rel_base_path}" + "${__qt_cmake_private_path}") + file(RELATIVE_PATH __qt_cmake_standalone_test_relpath "${rel_base_path}" + "${__qt_cmake_standalone_test_path}") + + set(__qt_cmake_standalone_test_os_prelude "@echo off") + set(__qt_cmake_standalone_test_script_relpath "set SCRIPT_DIR=%~dp0") + string(APPEND __qt_cmake_standalone_test_bin_path ".bat") + string(APPEND __qt_cmake_private_relpath ".bat") + string(PREPEND __qt_cmake_private_relpath "%SCRIPT_DIR%") + string(PREPEND __qt_cmake_standalone_test_relpath "%SCRIPT_DIR%") + set(__qt_cmake_standalone_passed_args "%* -DPWD=\"%CD%\"") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-standalone-test.in" + "${QT_BUILD_DIR}/${__qt_cmake_standalone_test_bin_path}" + NEWLINE_STYLE CRLF) + qt_install(PROGRAMS "${QT_BUILD_DIR}/${__qt_cmake_standalone_test_bin_path}" + DESTINATION "${INSTALL_BINDIR}") + endif() + + # Create an installation script that the CI can use to handle installation for both + # single and multiple configurations. + set(__qt_cmake_install_script_name "qt-cmake-private-install.cmake") + if(CMAKE_CONFIGURATION_TYPES) + set(__qt_configured_configs "${CMAKE_CONFIGURATION_TYPES}") + elseif(CMAKE_BUILD_TYPE) + set(__qt_configured_configs "${CMAKE_BUILD_TYPE}") + endif() + + if( + # Skip stripping pure debug builds so it's easier to debug issues in CI VMs. + (NOT QT_FEATURE_debug_and_release + AND QT_FEATURE_debug + AND NOT QT_FEATURE_separate_debug_info) + + # Skip stripping on MSVC because ${CMAKE_STRIP} might contain a MinGW strip binary + # and the breaks the linker version flag embedded in the binary and causes Qt Creator + # to mis-identify the Kit ABI. + OR MSVC + ) + set(__qt_skip_strip_installed_artifacts TRUE) + else() + set(__qt_skip_strip_installed_artifacts FALSE) + endif() + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/${__qt_cmake_install_script_name}.in" + "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${__qt_cmake_install_script_name}" @ONLY) + qt_install(FILES "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${__qt_cmake_install_script_name}" + DESTINATION "${INSTALL_LIBEXECDIR}") + + qt_internal_create_qt_configure_part_wrapper_script("STANDALONE_TESTS") + qt_internal_create_qt_configure_part_wrapper_script("STANDALONE_EXAMPLES") + qt_internal_create_qt_configure_redo_script() +endfunction() + +function(qt_internal_create_qt_configure_part_wrapper_script component) + if(QT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS) + set(generate_unix TRUE) + set(generate_non_unix TRUE) + elseif(CMAKE_HOST_UNIX) + set(generate_unix TRUE) + else() + set(generate_non_unix TRUE) + endif() + + # Create a private wrapper script to configure and build all standalone tests / examples. + # + # The script uses qt-cmake instead of qt-cmake-private on purpose. That's to ensure we build + # only one configuration of tests (e.g RelWithDebInfo only) when Qt is configured with more + # than one configuration (RelWithDebInfo;Debug). + # Meant to be used by our CI instructions. + # + # The script takes a path to the repo for which the standalone tests / examples will be + # configured. + + if(component STREQUAL "STANDALONE_TESTS") + set(script_name "qt-internal-configure-tests") + set(script_passed_args "-DQT_BUILD_STANDALONE_TESTS=ON -DQT_BUILD_EXAMPLES=OFF") + elseif(component STREQUAL "STANDALONE_EXAMPLES") + set(script_name "qt-internal-configure-examples") + set(script_passed_args "-DQT_BUILD_STANDALONE_EXAMPLES=ON -DQT_BUILD_TESTS=OFF") + else() + message(FATAL_ERROR "Invalid component type: ${component}") + endif() + + string(APPEND script_passed_args " -DQT_USE_ORIGINAL_COMPILER=ON") + + file(RELATIVE_PATH relative_path_from_libexec_dir_to_bin_dir + ${__qt_libexec_dir_absolute} + ${__qt_bin_dir_absolute}) + file(TO_NATIVE_PATH "${relative_path_from_libexec_dir_to_bin_dir}" + relative_path_from_libexec_dir_to_bin_dir) + + if(generate_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libexec/${script_name}.in" + "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${script_name}" @ONLY + NEWLINE_STYLE LF) + + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${script_name}" + DESTINATION "${INSTALL_LIBEXECDIR}") + endif() + if(generate_non_unix) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libexec/${script_name}.bat.in" + "${QT_BUILD_DIR}/${INSTALL_BINDIR}/${script_name}.bat" @ONLY + NEWLINE_STYLE CRLF) + + qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/${script_name}.bat" + DESTINATION "${INSTALL_BINDIR}") + endif() +endfunction() + +# Create a shell wrapper script to reconfigure Qt with the original configure arguments and +# any additional ones passed. +# +# Removes CMakeCache.txt and friends, either manually, or using CMake's --fresh. +# +# The script is created in the root of the build dir and is called config.redo +# It has the same contents as the 'config.status' script we created in qt 5. +function(qt_internal_create_qt_configure_redo_script) + set(input_script_name "qt-internal-config.redo") + set(input_script_path "${CMAKE_CURRENT_SOURCE_DIR}/libexec/${input_script_name}") + + # We don't use QT_BUILD_DIR because we want the file in the root of the build dir in a top-level + # build. + set(output_script_name "config.redo") + set(output_path "${CMAKE_BINARY_DIR}/${output_script_name}") + + if(QT_SUPERBUILD) + set(configure_script_path "${Qt_SOURCE_DIR}") + else() + set(configure_script_path "${QtBase_SOURCE_DIR}") + endif() + string(APPEND configure_script_path "/configure") + + # Used in the file contents. + file(TO_NATIVE_PATH "${configure_script_path}" configure_path) + + if(CMAKE_HOST_UNIX) + string(APPEND input_script_path ".in") + set(newline_style "LF") + else() + string(APPEND input_script_path ".bat.in") + string(APPEND output_path ".bat") + set(newline_style "CRLF") + endif() + + configure_file("${input_script_path}" "${output_path}" @ONLY NEWLINE_STYLE ${newline_style}) +endfunction() |