summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/Qt6CoreDeploySupport.cmake126
-rw-r--r--src/corelib/Qt6CoreMacros.cmake40
-rw-r--r--src/corelib/doc/src/cmake/qt_generate_deploy_app_script.qdoc8
3 files changed, 167 insertions, 7 deletions
diff --git a/src/corelib/Qt6CoreDeploySupport.cmake b/src/corelib/Qt6CoreDeploySupport.cmake
index 24ddc47bcb..7c307d18e0 100644
--- a/src/corelib/Qt6CoreDeploySupport.cmake
+++ b/src/corelib/Qt6CoreDeploySupport.cmake
@@ -105,6 +105,108 @@ if(NOT __QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
endfunction()
endif()
+# Copied from QtCMakeHelpers.cmake
+function(_qt_internal_re_escape out_var str)
+ string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" regex "${str}")
+ set(${out_var} ${regex} PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_generic_deployqt)
+ set(no_value_options
+ VERBOSE
+ )
+ set(single_value_options
+ EXECUTABLE
+ LIB_DIR
+ PLUGINS_DIR
+ )
+ set(multi_value_options
+ ADDITIONAL_EXECUTABLES
+ ADDITIONAL_LIBRARIES
+ ADDITIONAL_MODULES
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ if(arg_VERBOSE OR __QT_DEPLOY_VERBOSE)
+ set(verbose TRUE)
+ endif()
+
+ # Make input file paths absolute
+ foreach(var IN ITEMS EXECUTABLE ADDITIONAL_EXECUTABLES ADDITIONAL_LIBRARIES ADDITIONAL_MODULES)
+ string(PREPEND var arg_)
+ set(abspaths "")
+ foreach(path IN LISTS ${var})
+ get_filename_component(abspath "${path}" REALPATH BASE_DIR "${QT_DEPLOY_PREFIX}")
+ list(APPEND abspaths "${abspath}")
+ endforeach()
+ set(${var} "${abspaths}")
+ endforeach()
+
+ # We need to get the runtime dependencies of plugins too.
+ list(APPEND arg_ADDITIONAL_MODULES ${__QT_DEPLOY_PLUGINS})
+
+ set(file_args "")
+ if(arg_EXECUTABLE OR arg_ADDITIONAL_EXECUTABLES)
+ list(APPEND file_args EXECUTABLES ${arg_EXECUTABLE} ${arg_ADDITIONAL_EXECUTABLES})
+ endif()
+ if(arg_ADDITIONAL_LIBRARIES)
+ list(APPEND file_args LIBRARIES ${arg_ADDITIONAL_LIBRARIES})
+ endif()
+ if(arg_ADDITIONAL_MODULES)
+ list(APPEND file_args MODULES ${arg_ADDITIONAL_MODULES})
+ endif()
+
+ # Compile a list of regular expressions that represent the Qt installation prefixes.
+ set(prefix_regexes)
+ foreach(path IN LISTS __QT_DEPLOY_QT_INSTALL_PREFIX
+ __QT_DEPLOY_QT_ADDITIONAL_PACKAGES_PREFIX_PATH)
+ _qt_internal_re_escape(path_rex "${path}")
+ list(APPEND prefix_regexes "^${path_rex}")
+ endforeach()
+
+ # Get the runtime dependencies recursively, restricted to Qt's installation prefix.
+ file(GET_RUNTIME_DEPENDENCIES
+ ${file_args}
+ POST_INCLUDE_REGEXES ${prefix_regexes}
+ POST_EXCLUDE_REGEXES ".*"
+ RESOLVED_DEPENDENCIES_VAR resolved
+ UNRESOLVED_DEPENDENCIES_VAR unresolved
+ CONFLICTING_DEPENDENCIES_PREFIX conflicting
+ )
+ if(verbose)
+ message("file(GET_RUNTIME_DEPENDENCIES ${file_args})")
+ foreach(file IN LISTS resolved)
+ message(" resolved: ${file}")
+ endforeach()
+ foreach(file IN LISTS unresolved)
+ message(" unresolved: ${file}")
+ endforeach()
+ foreach(file IN LISTS conflicting_FILENAMES)
+ message(" conflicting: ${file}")
+ message(" with ${conflicting_${file}}")
+ endforeach()
+ endif()
+
+ # Deploy the Qt libraries.
+ file(INSTALL ${resolved}
+ DESTINATION "${QT_DEPLOY_PREFIX}/${arg_LIB_DIR}"
+ FOLLOW_SYMLINK_CHAIN
+ )
+
+ # Deploy the Qt plugins.
+ foreach(file_path IN LISTS __QT_DEPLOY_PLUGINS)
+ file(RELATIVE_PATH destination
+ "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_PLUGINS}"
+ "${file_path}"
+ )
+ get_filename_component(destination "${destination}" DIRECTORY)
+ string(PREPEND destination "${QT_DEPLOY_PREFIX}/${arg_PLUGINS_DIR}/")
+ file(INSTALL ${file_path} DESTINATION ${destination})
+ endforeach()
+endfunction()
+
# This function is currently in Technical Preview.
# Its signature and behavior might change.
function(qt6_deploy_runtime_dependencies)
@@ -202,6 +304,8 @@ function(qt6_deploy_runtime_dependencies)
list(APPEND tool_options --verbose 2)
elseif(__QT_DEPLOY_SYSTEM_NAME STREQUAL Darwin)
list(APPEND tool_options -verbose=3)
+ else()
+ list(APPEND tool_options VERBOSE)
endif()
endif()
@@ -228,10 +332,28 @@ function(qt6_deploy_runtime_dependencies)
# for debugging purposes. It may be removed at any time without warning.
list(APPEND tool_options ${__qt_deploy_tool_extra_options})
+ if(__QT_DEPLOY_TOOL STREQUAL "GRD")
+ message(STATUS "Running generic Qt deploy tool on ${arg_EXECUTABLE}")
+
+ # Forward the ADDITIONAL_* arguments.
+ foreach(file_type EXECUTABLES LIBRARIES MODULES)
+ if("${arg_ADDITIONAL_${file_type}}" STREQUAL "")
+ continue()
+ endif()
+ list(APPEND tool_options ADDITIONAL_${file_type} ${arg_ADDITIONAL_${file_type}})
+ endforeach()
+
+ _qt_internal_generic_deployqt(
+ EXECUTABLE "${arg_EXECUTABLE}"
+ LIB_DIR "${arg_LIB_DIR}"
+ PLUGINS_DIR "${arg_PLUGINS_DIR}"
+ ${tool_options}
+ )
+ return()
+ endif()
+
# Both windeployqt and macdeployqt don't differentiate between the different
# types of binaries, so we merge the lists and treat them all the same.
- # A purely CMake-based implementation would need to treat them differently
- # because of how file(GET_RUNTIME_DEPENDENCIES) works.
set(additional_binaries
${arg_ADDITIONAL_EXECUTABLES}
${arg_ADDITIONAL_LIBRARIES}
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 1587af1302..3bea0f135b 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -2437,6 +2437,8 @@ function(_qt_internal_setup_deploy_support)
set(safe_target_file
"$<TARGET_FILE:$<IF:${have_deploy_tool},${target_if_exists},${target}>>")
set(__QT_DEPLOY_TOOL "$<IF:${have_deploy_tool},${safe_target_file},${fallback}>")
+ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT CMAKE_CROSSCOMPILING)
+ set(__QT_DEPLOY_TOOL "GRD")
else()
# Android is handled as a build target, not via this install-based approach.
# Therefore, we don't consider androiddeployqt here.
@@ -2480,6 +2482,10 @@ set(__QT_DEPLOY_GENERATOR_IS_MULTI_CONFIG \"${is_multi_config}\")
set(__QT_DEPLOY_ACTIVE_CONFIG \"$<CONFIG>\")
set(__QT_NO_CREATE_VERSIONLESS_FUNCTIONS \"${QT_NO_CREATE_VERSIONLESS_FUNCTIONS}\")
set(__QT_DEFAULT_MAJOR_VERSION \"${QT_DEFAULT_MAJOR_VERSION}\")
+set(__QT_DEPLOY_QT_ADDITIONAL_PACKAGES_PREFIX_PATH \"${QT_ADDITIONAL_PACKAGES_PREFIX_PATH}\")
+set(__QT_DEPLOY_QT_INSTALL_PREFIX \"${QT6_INSTALL_PREFIX}\")
+set(__QT_DEPLOY_QT_INSTALL_PLUGINS \"${QT6_INSTALL_PLUGINS}\")
+set(__QT_DEPLOY_PLUGINS \"\")
# Define the CMake commands to be made available during deployment.
set(__qt_deploy_support_files
@@ -2593,6 +2599,21 @@ function(qt6_generate_deploy_script)
message(FATAL_ERROR "CONTENT must be specified")
endif()
+ # Check whether manual finalization is needed.
+ if(CMAKE_VERSION VERSION_LESS "3.19")
+ get_target_property(is_immediately_finalized ${arg_TARGET} _qt_is_immediately_finalized)
+ if(is_immediately_finalized)
+ message(WARNING
+ "Deployment of plugins for target '${arg_TARGET}' will not work. "
+ "Either, upgrade CMake to version 3.19 or newer, or call "
+ "qt_finalize_target(${arg_TARGET}) after generating the deployment script."
+ )
+ endif()
+ endif()
+
+ # Mark the target as "to be deployed".
+ set_property(TARGET ${arg_TARGET} PROPERTY _qt_marked_for_deployment ON)
+
# Create a file name that will be unique for this target and the combination
# of arguments passed to this command. This allows the project to call us
# multiple times with different arguments for the same target (e.g. to
@@ -2610,12 +2631,15 @@ function(qt6_generate_deploy_script)
set(file_name "${deploy_impl_dir}/deploy_${target_id}_${short_hash}")
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
- string(APPEND file_name "-$<CONFIG>")
+ set(config_infix "-$<CONFIG>")
+ else()
+ set(config_infix "")
endif()
- string(APPEND file_name ".cmake")
+ string(APPEND file_name "${config_infix}.cmake")
set(${arg_FILENAME_VARIABLE} "${file_name}" PARENT_SCOPE)
set(boiler_plate "include(${QT_DEPLOY_SUPPORT})
+include(\"\${CMAKE_CURRENT_LIST_DIR}/${arg_TARGET}-plugins${config_infix}.cmake\" OPTIONAL)
")
list(TRANSFORM arg_CONTENT REPLACE "\\$" "\$")
file(GENERATE OUTPUT ${file_name} CONTENT "${boiler_plate}${arg_CONTENT}")
@@ -2694,7 +2718,17 @@ qt6_deploy_runtime_dependencies(
qt6_deploy_runtime_dependencies(
EXECUTABLE $<TARGET_FILE:${arg_TARGET}>
GENERATE_QT_CONF
-)")
+)
+")
+
+ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND QT6_IS_SHARED_LIBS_BUILD)
+ qt6_generate_deploy_script(${generate_args}
+ CONTENT "
+qt6_deploy_runtime_dependencies(
+ EXECUTABLE $<TARGET_FILE:${arg_TARGET}>
+ GENERATE_QT_CONF
+)
+")
elseif(NOT arg_NO_UNSUPPORTED_PLATFORM_ERROR AND NOT QT_INTERNAL_NO_UNSUPPORTED_PLATFORM_ERROR)
# Currently we don't deploy runtime dependencies if cross-compiling or using a static Qt.
diff --git a/src/corelib/doc/src/cmake/qt_generate_deploy_app_script.qdoc b/src/corelib/doc/src/cmake/qt_generate_deploy_app_script.qdoc
index e3e4901512..8d059f4c86 100644
--- a/src/corelib/doc/src/cmake/qt_generate_deploy_app_script.qdoc
+++ b/src/corelib/doc/src/cmake/qt_generate_deploy_app_script.qdoc
@@ -48,8 +48,12 @@ which should come after the application's target has been installed using
The deployment script will call \l{qt_deploy_runtime_dependencies()} with a
suitable set of options for the standard install layout.
-Currently, this is only implemented for macOS app bundles built on a macOS
-host and Windows executables built on a Windows host.
+Currently, this is only implemented for
+\list
+ \li macOS app bundles built on a macOS host,
+ \li Linux executables built on a Linux host,
+ \li and Windows executables built on a Windows host.
+\endlist
Cross-building a Windows executable on a Linux host, as well as similar
scenarios, are not currently supported.
Calling \c{qt_generate_deploy_app_script()} in such a case will result