summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2020-06-18 10:07:22 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2020-06-29 12:47:34 +0200
commitd7fd6848612760124871f0f3b55917250d078dd5 (patch)
tree49f97ad5f16f5fd32cf69a5497c20581bf65b592 /cmake
parentb0f9c06a9b199a7474eb94a6292b5824364344b6 (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.cmake1
-rw-r--r--cmake/QtBuild.cmake91
-rw-r--r--cmake/QtSetup.cmake21
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)