From 24f12d0cefe00adfe1b11cf41efbb146d529a6cd Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Tue, 18 Aug 2020 18:13:03 +0200 Subject: [PATCH] CMake: Build examples with qmake against a CMake built Qt We want to remove the Qt .pro files for projects, except examples, because examples are still meant to build with qmake. To not lose coverage on examples built with qmake, add instructions that will build the qtrepo/examples folder with qmake when the CMake configuration has -DQT_BUILD_EXAMPLES=ON. This means that such configurations will build examples both with CMake and qmake. Aside from making sure that our examples will still build with qmake, it will gives us some some coverage that a CMake-built qmake works correctly. Implementation-wise, add new instructions files that can call qmake and make depending on configuration and target type. Pick-to: 6.0 Fixes: QTBUG-85986 Change-Id: Ie8f4cbcda03c94da2aef455e32f48dad41a4bdb0 Reviewed-by: Alexandru Croitor --- cmake/QtBaseGlobalTargets.cmake | 5 ++ ...compilation_module_build_instructions.yaml | 5 ++ ...compilation_qtbase_build_instructions.yaml | 5 ++ .../cmake_module_build_instructions.yaml | 5 ++ .../cmake_qtbase_build_instructions.yaml | 5 ++ coin/instructions/qmake/call_make.yaml | 55 ++++++++++++++ coin/instructions/qmake/ensure_pro_file.cmake | 16 +++++ .../qmake/get_qmake_location_host.yaml | 16 +++++ .../qmake/get_qmake_location_target.yaml | 29 ++++++++ ...ild_qmake_examples_inner_instructions.yaml | 71 +++++++++++++++++++ .../build_qmake_examples_instructions.yaml | 23 ++++++ .../get_examples_source_location.yaml | 16 +++++ 12 files changed, 251 insertions(+) create mode 100644 coin/instructions/qmake/call_make.yaml create mode 100644 coin/instructions/qmake/ensure_pro_file.cmake create mode 100644 coin/instructions/qmake/get_qmake_location_host.yaml create mode 100644 coin/instructions/qmake/get_qmake_location_target.yaml create mode 100644 coin/instructions/qmake_examples/build_qmake_examples_inner_instructions.yaml create mode 100644 coin/instructions/qmake_examples/build_qmake_examples_instructions.yaml create mode 100644 coin/instructions/qmake_examples/get_examples_source_location.yaml diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 1f12b7206a7..8c1c9d2bd06 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -237,3 +237,8 @@ if(MACOS) DESTINATION "${__GlobalConfig_install_dir}/macos" ) endif() + +# Install CI support files to libexec. +qt_path_join(__qt_libexec_install_dir "${QT_INSTALL_DIR}" "${INSTALL_LIBEXECDIR}") +qt_copy_or_install(FILES coin/instructions/qmake/ensure_pro_file.cmake + DESTINATION "${__qt_libexec_install_dir}") diff --git a/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml b/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml index c6818a128db..e5e257f1813 100644 --- a/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml +++ b/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml @@ -73,3 +73,8 @@ instructions: transferType: UploadModuleBuildArtifact maxTimeInSeconds: 1200 maxTimeBetweenOutput: 1200 + - type: EnvironmentVariable + variableName: COIN_CONFIG_TYPE + variableValue: "Target" + - !include "{{qt/qtbase}}/qmake/get_qmake_location_target.yaml" + - !include "{{qt/qtbase}}/qmake_examples/build_qmake_examples_instructions.yaml" diff --git a/coin/instructions/cmake_cross_compilation_qtbase_build_instructions.yaml b/coin/instructions/cmake_cross_compilation_qtbase_build_instructions.yaml index 601e952c710..844eeab10d9 100644 --- a/coin/instructions/cmake_cross_compilation_qtbase_build_instructions.yaml +++ b/coin/instructions/cmake_cross_compilation_qtbase_build_instructions.yaml @@ -91,3 +91,8 @@ instructions: transferType: UploadModuleBuildArtifact maxTimeInSeconds: 1200 maxTimeBetweenOutput: 1200 + - type: EnvironmentVariable + variableName: COIN_CONFIG_TYPE + variableValue: "Target" + - !include "{{qt/qtbase}}/qmake/get_qmake_location_target.yaml" + - !include "{{qt/qtbase}}/qmake_examples/build_qmake_examples_instructions.yaml" diff --git a/coin/instructions/cmake_module_build_instructions.yaml b/coin/instructions/cmake_module_build_instructions.yaml index e148321d39b..05a3567e28e 100644 --- a/coin/instructions/cmake_module_build_instructions.yaml +++ b/coin/instructions/cmake_module_build_instructions.yaml @@ -38,3 +38,8 @@ instructions: transferType: UploadModuleBuildArtifact maxTimeInSeconds: 1200 maxTimeBetweenOutput: 1200 + - type: EnvironmentVariable + variableName: COIN_CONFIG_TYPE + variableValue: "Host" + - !include "{{qt/qtbase}}/qmake/get_qmake_location_host.yaml" + - !include "{{qt/qtbase}}/qmake_examples/build_qmake_examples_instructions.yaml" diff --git a/coin/instructions/cmake_qtbase_build_instructions.yaml b/coin/instructions/cmake_qtbase_build_instructions.yaml index 4ed3e1ae6e9..b7ba32daffd 100644 --- a/coin/instructions/cmake_qtbase_build_instructions.yaml +++ b/coin/instructions/cmake_qtbase_build_instructions.yaml @@ -40,3 +40,8 @@ instructions: transferType: UploadModuleBuildArtifact maxTimeInSeconds: 1200 maxTimeBetweenOutput: 1200 + - type: EnvironmentVariable + variableName: COIN_CONFIG_TYPE + variableValue: "Host" + - !include "{{qt/qtbase}}/qmake/get_qmake_location_host.yaml" + - !include "{{qt/qtbase}}/qmake_examples/build_qmake_examples_instructions.yaml" diff --git a/coin/instructions/qmake/call_make.yaml b/coin/instructions/qmake/call_make.yaml new file mode 100644 index 00000000000..59babe9e0c0 --- /dev/null +++ b/coin/instructions/qmake/call_make.yaml @@ -0,0 +1,55 @@ +type: Group +instructions: + # Call jom when host os is Windows + MSVC + - type: Group + instructions: + # Clear the automatically set MAKEFLAGS variable + - type: EnvironmentVariable + variableName: MAKEFLAGS + variableValue: "" + # Call jom + - type: ExecuteCommand + command: "{{.Env.ENV_PREFIX}} {{.Env.CI_JOM_PATH}}\\jom.exe" + executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution + maxTimeInSeconds: 6000 + maxTimeBetweenOutput: 1200 + userMessageOnFailure: > + Failed to call jom. + enable_if: + condition: and + conditions: + - condition: property + property: host.os + equals_value: Windows + - condition: property + property: host.compiler + not_contains_value: "Mingw" + # Call make when host os is not Windows (Linux, macOS) + - type: ExecuteCommand + command: "{{.Env.CALL_MAKE_ENV_PREFIX}} make" + executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution + maxTimeInSeconds: 6000 + maxTimeBetweenOutput: 1200 + userMessageOnFailure: > + Failed to call make. + enable_if: + condition: property + property: target.os + not_equals_value: Windows + # Call mingw32-make when host os is Windows + MinGW (this includes building for Android) + - type: ExecuteCommand + command: "{{.Env.CALL_MAKE_ENV_PREFIX}} mingw32-make" + executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution + maxTimeInSeconds: 6000 + maxTimeBetweenOutput: 1200 + userMessageOnFailure: > + Failed to call mingw32-make. + enable_if: + condition: and + conditions: + - condition: property + property: host.os + equals_value: Windows + - condition: property + property: host.compiler + contains_value: "Mingw" diff --git a/coin/instructions/qmake/ensure_pro_file.cmake b/coin/instructions/qmake/ensure_pro_file.cmake new file mode 100644 index 00000000000..0dd8b4a8e7e --- /dev/null +++ b/coin/instructions/qmake/ensure_pro_file.cmake @@ -0,0 +1,16 @@ +# CMake script to ensure that a qmake project file exists. +# +# Usage: cmake -DPRO_FILE=.../project.pro -P .../ensure_pro_file.cmake +# +# This script checks for existence of ${PRO_FILE} and creates a fake one, if needed. +# + +if(NOT EXISTS "${PRO_FILE}") + get_filename_component(dir "${PRO_FILE}" DIRECTORY) + if(NOT IS_DIRECTORY "${dir}") + file(MAKE_DIRECTORY "${dir}") + endif() + + file(WRITE "${PRO_FILE}" "TEMPLATE = aux +") +endif() diff --git a/coin/instructions/qmake/get_qmake_location_host.yaml b/coin/instructions/qmake/get_qmake_location_host.yaml new file mode 100644 index 00000000000..e43602a9a26 --- /dev/null +++ b/coin/instructions/qmake/get_qmake_location_host.yaml @@ -0,0 +1,16 @@ +type: Group +instructions: + - type: EnvironmentVariable + variableName: COIN_QMAKE_LOCATION + variableValue: "{{.InstallDir}}\\bin\\qmake" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: EnvironmentVariable + variableName: COIN_QMAKE_LOCATION + variableValue: "{{.InstallDir}}/bin/qmake" + disable_if: + condition: property + property: host.os + equals_value: Windows diff --git a/coin/instructions/qmake/get_qmake_location_target.yaml b/coin/instructions/qmake/get_qmake_location_target.yaml new file mode 100644 index 00000000000..13940bdad20 --- /dev/null +++ b/coin/instructions/qmake/get_qmake_location_target.yaml @@ -0,0 +1,29 @@ +type: Group +instructions: + - type: EnvironmentVariable + variableName: COIN_QMAKE_LOCATION + variableValue: "{{.InstallDir}}\\target\\bin\\qmake.bat" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: Group + disable_if: + condition: property + property: host.os + equals_value: Windows + instructions: + - type: EnvironmentVariable + variableName: COIN_QMAKE_LOCATION + variableValue: "{{.InstallDir}}/target/bin/qmake" + disable_if: + condition: property + property: target.osVersion + equals_value: QEMU + - type: EnvironmentVariable + variableName: COIN_QMAKE_LOCATION + variableValue: "{{.InstallDir}}/target/bin/host-qmake" + enable_if: + condition: property + property: target.osVersion + equals_value: QEMU diff --git a/coin/instructions/qmake_examples/build_qmake_examples_inner_instructions.yaml b/coin/instructions/qmake_examples/build_qmake_examples_inner_instructions.yaml new file mode 100644 index 00000000000..9bb765642db --- /dev/null +++ b/coin/instructions/qmake_examples/build_qmake_examples_inner_instructions.yaml @@ -0,0 +1,71 @@ +type: Group +instructions: + - type: Group + instructions: + # Prepare directories to build examples with qmake. + - type: ChangeDirectory + directory: "{{.SourceDir}}" + - type: MakeDirectory + directory: "{{.SourceDir}}_qmake/examples" + - type: SetBuildDirectory + directory: "{{.SourceDir}}_qmake/examples" + - type: ChangeDirectory + directory: "{{.BuildDir}}" + - !include "{{qt/qtbase}}/qmake_examples/get_examples_source_location.yaml" + + # Setup qemu cross-compiled qmake to work. + - !include "{{qt/qtbase}}/coin_module_test_qemu_env_vars.yaml" + + # Set either host or target env prefix for qmake and make depending on + # tested configuration. + - type: Group + instructions: + - type: EnvironmentVariable + variableName: CALL_MAKE_ENV_PREFIX + variableValue: "{{.Env.ENV_PREFIX}}" + enable_if: + condition: runtime + env_var: COIN_CONFIG_TYPE + equals_value: "Host" + - type: EnvironmentVariable + variableName: CALL_MAKE_ENV_PREFIX + variableValue: "{{.Env.TARGET_ENV_PREFIX}}" + enable_if: + condition: runtime + env_var: COIN_CONFIG_TYPE + equals_value: "Target" + + # Ensure that we have an examples/examples.pro file. + # If it doesn't exist, write a dummy project file. + # The CMake that does this is installed to INSTALL_LIBEXEC, which defaults to "bin" on Windows. + - type: ExecuteCommand + enable_if: + condition: property + property: host.os + equals_value: Windows + command: "cmake --trace-expand -DPRO_FILE={{.SourceDir}}\\examples\\examples.pro -P {{.InstallDir}}\\bin\\ensure_pro_file.cmake" + maxTimeInSeconds: 20 + maxTimeBetweenOutput: 20 + userMessageOnFailure: > + Failed to run cmake -P ensure_pro_file.cmake + - type: ExecuteCommand + disable_if: + condition: property + property: host.os + equals_value: Windows + command: "cmake --trace-expand -DPRO_FILE={{.SourceDir}}/examples/examples.pro -P {{.InstallDir}}/libexec/ensure_pro_file.cmake" + maxTimeInSeconds: 20 + maxTimeBetweenOutput: 20 + userMessageOnFailure: > + Failed to run cmake -P ensure_pro_file.cmake + + # Run qmake to configure the examples. The env prefix is important for qemu. + - type: ExecuteCommand + command: "{{.Env.CALL_MAKE_ENV_PREFIX}} {{.Env.COIN_QMAKE_LOCATION}} {{.Env.COIN_EXAMPLES_SOURCE_LOCATION}}" + maxTimeInSeconds: 6000 + maxTimeBetweenOutput: 1200 + userMessageOnFailure: > + Failed to run qmake to build examples. + + # Run make to build the examples. + - !include "{{qt/qtbase}}/qmake/call_make.yaml" diff --git a/coin/instructions/qmake_examples/build_qmake_examples_instructions.yaml b/coin/instructions/qmake_examples/build_qmake_examples_instructions.yaml new file mode 100644 index 00000000000..7b8a6376f90 --- /dev/null +++ b/coin/instructions/qmake_examples/build_qmake_examples_instructions.yaml @@ -0,0 +1,23 @@ +type: Group +instructions: + # Only enable building examples if -DQT_BUILD_EXAMPLES=ON was passed to the CMake config in some + # form. The variable to check unfortunately depends on host vs target, and qtbase vs non-qtbase. + - type: Group + instructions: + - !include "{{qt/qtbase}}/qmake_examples/build_qmake_examples_inner_instructions.yaml" + enable_if: + condition: or + conditions: + # qtbase host case + - condition: runtime + env_var: CONFIGURE_ARGS + contains_value: "QT_BUILD_EXAMPLES=ON" + # qtbase target case + - condition: runtime + env_var: TARGET_CONFIGURE_ARGS + contains_value: "QT_BUILD_EXAMPLES=ON" + # non-qtbase host case + # non-qtbase target case + - condition: runtime + env_var: COIN_CMAKE_ARGS + contains_value: "QT_BUILD_EXAMPLES=ON" diff --git a/coin/instructions/qmake_examples/get_examples_source_location.yaml b/coin/instructions/qmake_examples/get_examples_source_location.yaml new file mode 100644 index 00000000000..ca360e8727b --- /dev/null +++ b/coin/instructions/qmake_examples/get_examples_source_location.yaml @@ -0,0 +1,16 @@ +type: Group +instructions: + - type: EnvironmentVariable + variableName: COIN_EXAMPLES_SOURCE_LOCATION + variableValue: "{{.SourceDir}}\\examples" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: EnvironmentVariable + variableName: COIN_EXAMPLES_SOURCE_LOCATION + variableValue: "{{.SourceDir}}/examples" + disable_if: + condition: property + property: host.os + equals_value: Windows