diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-06-18 10:07:22 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-06-29 12:47:34 +0200 |
commit | d7fd6848612760124871f0f3b55917250d078dd5 (patch) | |
tree | 49f97ad5f16f5fd32cf69a5497c20581bf65b592 /cmake | |
parent | b0f9c06a9b199a7474eb94a6292b5824364344b6 (diff) |
CMake: Support cross-compilation with qmake
When cross-compiling, we now create a target_qt.conf file that's to be
used with the host Qt's qmake. With "qmake -qtconf .../target_qt.conf"
projects can be cross-built against the cross-built Qt.
We also create wrapper scripts for the host qmake to save the user from
passing the -qtconf argument.
Fixes: QTBUG-82581
Change-Id: Ib5866e7e820369efea9eb3171e3e3e3ca5c0c3c1
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtBaseGlobalTargets.cmake | 1 | ||||
-rw-r--r-- | cmake/QtBuild.cmake | 91 | ||||
-rw-r--r-- | cmake/QtSetup.cmake | 21 |
3 files changed, 104 insertions, 9 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 1c35270096..66b71421e3 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -293,6 +293,7 @@ qt_feature_module_end(GlobalConfig OUT_VAR_PREFIX "__GlobalConfig_") qt_generate_global_config_pri_file() qt_generate_global_module_pri_file() +qt_generate_qmake_wrapper_for_target() add_library(Qt::GlobalConfig ALIAS GlobalConfig) diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index e562138006..a2463fdccf 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -295,8 +295,11 @@ elseif(EMSCRIPTEN) set(QT_QMAKE_TARGET_MKSPEC wasm-emscripten) endif() -# TODO: Fixme to be correct. -set(QT_QMAKE_HOST_MKSPEC "${QT_QMAKE_TARGET_MKSPEC}") +if(CMAKE_CROSSCOMPILING) + set(QT_QMAKE_HOST_MKSPEC "${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_QMAKE_MKSPEC}") +else() + set(QT_QMAKE_HOST_MKSPEC "${QT_QMAKE_TARGET_MKSPEC}") +endif() # Platform definition dir provided by user on command line. # Derive the absolute one relative to the current source dir. @@ -1303,6 +1306,90 @@ CONFIG += ${private_config_joined} qt_install(FILES "${qmodule_pri_target_path}" DESTINATION ${INSTALL_MKSPECSDIR}) endfunction() +# In the cross-compiling case, creates a wrapper around the host Qt's +# qmake executable. Also creates a qmake configuration file that sets +# up the host qmake's properties for cross-compiling with this Qt +# build. +function(qt_generate_qmake_wrapper_for_target) + if(NOT CMAKE_CROSSCOMPILING) + return() + endif() + + # Call the configuration file something else but qt.conf to avoid + # being picked up by the qmake executable that's created if + # QT_BUILD_TOOLS_WHEN_CROSSCOMPILING is enabled. + qt_path_join(qt_conf_path "${INSTALL_BINDIR}" "target_qt.conf") + + set(prefix "${CMAKE_INSTALL_PREFIX}") + set(ext_prefix "${CMAKE_STAGING_PREFIX}") + if(ext_prefix STREQUAL "") + set(ext_prefix "${prefix}") + endif() + + set(host_prefix "${QT_HOST_PATH}") + file(RELATIVE_PATH host_prefix_relative_to_conf_file "${ext_prefix}/${INSTALL_BINDIR}" + "${host_prefix}") + file(RELATIVE_PATH ext_prefix_relative_to_conf_file "${ext_prefix}/${INSTALL_BINDIR}" + "${ext_prefix}") + file(RELATIVE_PATH ext_prefix_relative_to_host_prefix "${host_prefix}" "${ext_prefix}") + + set(content "") + if(ext_prefix STREQUAL prefix) + set(sysrootify_prefix true) + else() + set(sysrootify_prefix false) + string(APPEND content "[DevicePaths] +Prefix=${prefix} +") + endif() + + if(NOT QT_WILL_INSTALL) + # The shadow build directory of a non-prefix build does not contain a copy of the mkspecs + # directory. Let $$[QT_HOST_DATA/src] point to the qtbase source directory. + string(APPEND content "[EffectiveSourcePaths] +HostData=${CMAKE_CURRENT_SOURCE_DIR} +") + + # Set $$[QT_HOST_DATA/get] to avoid falling back to the source dir where it isn't explicitly + # requested. + string(APPEND content "[EffectivePaths] +HostData=${ext_prefix} +") + endif() + + string(APPEND content + "[Paths] +Prefix=${ext_prefix_relative_to_conf_file} +HostPrefix=${host_prefix_relative_to_conf_file} +HostData=${ext_prefix_relative_to_host_prefix} +Sysroot=${CMAKE_SYSROOT} +SysrootifyPrefix=${sysrootify_prefix} +TargetSpec=${QT_QMAKE_TARGET_MKSPEC} +HostSpec=${QT_QMAKE_HOST_MKSPEC} +") + file(GENERATE OUTPUT "${qt_conf_path}" CONTENT "${content}") + + qt_path_join(qmake_wrapper_in_file "${CMAKE_CURRENT_SOURCE_DIR}/bin/qmake-wrapper-for-target") + qt_path_join(qmake_wrapper "preliminary" "qmake") + if(QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) + # Avoid collisions with the cross-compiled qmake binary. + string(PREPEND qmake_wrapper "host-") + endif() + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + string(APPEND qmake_wrapper_in_file ".bat") + string(APPEND qmake_wrapper ".bat") + endif() + string(APPEND qmake_wrapper_in_file ".in") + + set(host_qt_bindir "${host_prefix}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}") + + configure_file("${qmake_wrapper_in_file}" "${qmake_wrapper}" @ONLY) + qt_install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${qt_conf_path}" + DESTINATION "${INSTALL_BINDIR}") + qt_copy_or_install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${qmake_wrapper}" + DESTINATION "${INSTALL_BINDIR}") +endfunction() + # Takes a list of path components and joins them into one path separated by forward slashes "/", # and saves the path in out_var. function(qt_path_join out_var) diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake index 4bed289453..b23b9924e0 100644 --- a/cmake/QtSetup.cmake +++ b/cmake/QtSetup.cmake @@ -152,6 +152,20 @@ option(QT_NO_MAKE_EXAMPLES "Should examples be built as part of the default 'all # Build Benchmarks option(QT_BUILD_BENCHMARKS "Build Qt Benchmarks" ${__build_benchmarks}) +## Find host tools (if non native): +set(QT_HOST_PATH "" CACHE PATH "Installed Qt host directory path, used for cross compiling.") + +if (CMAKE_CROSSCOMPILING) + if(NOT IS_DIRECTORY ${QT_HOST_PATH}) + message(FATAL_ERROR "You need to set QT_HOST_PATH to cross compile Qt.") + endif() + list(PREPEND CMAKE_PREFIX_PATH "${QT_HOST_PATH}") + list(PREPEND CMAKE_FIND_ROOT_PATH "${QT_HOST_PATH}") + find_package(Qt${PROJECT_VERSION_MAJOR}HostInfo REQUIRED) + list(POP_FRONT CMAKE_PREFIX_PATH) + list(POP_FRONT CMAKE_FIND_ROOT_PATH) +endif() + ## Android platform settings if(ANDROID) include(QtPlatformAndroid) @@ -175,13 +189,6 @@ qt_set_up_nonprefix_build() qt_set_language_standards() -## Find host tools (if non native): -set(QT_HOST_PATH "" CACHE PATH "Installed Qt host directory path, used for cross compiling.") - -if (CMAKE_CROSSCOMPILING AND NOT IS_DIRECTORY ${QT_HOST_PATH}) - message(FATAL_ERROR "You need to set QT_HOST_PATH to cross compile Qt.") -endif() - ## Enable support for sanitizers: qt_internal_set_up_sanitizer_features() include(${CMAKE_CURRENT_LIST_DIR}/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake) |