diff --git a/src/corelib/Qt6CoreDeploySupport.cmake b/src/corelib/Qt6CoreDeploySupport.cmake index 98d6b2b5531..d149796b212 100644 --- a/src/corelib/Qt6CoreDeploySupport.cmake +++ b/src/corelib/Qt6CoreDeploySupport.cmake @@ -161,15 +161,21 @@ function(_qt_internal_generic_deployqt) VERBOSE ) set(single_value_options - EXECUTABLE LIB_DIR PLUGINS_DIR ) - set(multi_value_options - ADDITIONAL_EXECUTABLES - ADDITIONAL_LIBRARIES - ADDITIONAL_MODULES + set(file_GRD_options + EXECUTABLES + LIBRARIES + MODULES + PRE_INCLUDE_REGEXES + PRE_EXCLUDE_REGEXES + POST_INCLUDE_REGEXES + POST_EXCLUDE_REGEXES + POST_INCLUDE_FILES + POST_EXCLUDE_FILES ) + set(multi_value_options ${file_GRD_options}) cmake_parse_arguments(PARSE_ARGV 0 arg "${no_value_options}" "${single_value_options}" "${multi_value_options}" ) @@ -179,7 +185,7 @@ function(_qt_internal_generic_deployqt) endif() # Make input file paths absolute - foreach(var IN ITEMS EXECUTABLE ADDITIONAL_EXECUTABLES ADDITIONAL_LIBRARIES ADDITIONAL_MODULES) + foreach(var IN ITEMS EXECUTABLES LIBRARIES MODULES) string(PREPEND var arg_) set(abspaths "") foreach(path IN LISTS ${var}) @@ -190,32 +196,31 @@ function(_qt_internal_generic_deployqt) endforeach() # We need to get the runtime dependencies of plugins too. - list(APPEND arg_ADDITIONAL_MODULES ${__QT_DEPLOY_PLUGINS}) + list(APPEND arg_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}") + # Forward the arguments that are exactly the same for file(GET_RUNTIME_DEPENDENCIES). + set(file_GRD_args "") + foreach(var IN LISTS file_GRD_options) + if(NOT "${arg_${var}}" STREQUAL "") + list(APPEND file_GRD_args ${var} ${arg_${var}}) + endif() endforeach() - # Get the runtime dependencies recursively, restricted to Qt's installation prefix. + # Compile a list of regular expressions that represent ignored library directories. + if("${arg_POST_EXCLUDE_REGEXES}" STREQUAL "") + set(regexes "") + foreach(path IN LISTS QT_DEPLOY_IGNORED_LIB_DIRS) + _qt_internal_re_escape(path_rex "${path}") + list(APPEND regexes "^${path_rex}") + endforeach() + if(regexes) + list(APPEND file_GRD_args POST_EXCLUDE_REGEXES ${regexes}) + endif() + endif() + + # Get the runtime dependencies recursively. file(GET_RUNTIME_DEPENDENCIES - ${file_args} - POST_INCLUDE_REGEXES ${prefix_regexes} - POST_EXCLUDE_REGEXES ".*" + ${file_GRD_args} RESOLVED_DEPENDENCIES_VAR resolved UNRESOLVED_DEPENDENCIES_VAR unresolved CONFLICTING_DEPENDENCIES_PREFIX conflicting @@ -294,6 +299,16 @@ function(qt6_deploy_runtime_dependencies) PLUGINS_DIR QML_DIR ) + set(file_GRD_options + # The following include/exclude options are only used if the "generic deploy tool" is + # used. The options are what file(GET_RUNTIME_DEPENDENCIES) supports. + PRE_INCLUDE_REGEXES + PRE_EXCLUDE_REGEXES + POST_INCLUDE_REGEXES + POST_EXCLUDE_REGEXES + POST_INCLUDE_FILES + POST_EXCLUDE_FILES + ) set(multi_value_options # These ADDITIONAL_... options are based on what file(GET_RUNTIME_DEPENDENCIES) # supports. We differentiate between the types of binaries so that we keep @@ -303,6 +318,7 @@ function(qt6_deploy_runtime_dependencies) ADDITIONAL_EXECUTABLES ADDITIONAL_LIBRARIES ADDITIONAL_MODULES + ${file_GRD_options} ) cmake_parse_arguments(PARSE_ARGV 0 arg "${no_value_options}" "${single_value_options}" "${multi_value_options}" @@ -404,12 +420,23 @@ function(qt6_deploy_runtime_dependencies) 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) + # Construct the EXECUTABLES, LIBRARIES and MODULES arguments. + list(APPEND tool_options EXECUTABLES ${arg_EXECUTABLE}) + if(NOT "${arg_ADDITIONAL_EXECUTABLES}" STREQUAL "") + list(APPEND tool_options ${arg_ADDITIONAL_EXECUTABLES}) + endif() + foreach(file_type LIBRARIES MODULES) if("${arg_ADDITIONAL_${file_type}}" STREQUAL "") continue() endif() - list(APPEND tool_options ADDITIONAL_${file_type} ${arg_ADDITIONAL_${file_type}}) + list(APPEND tool_options ${file_type} ${arg_ADDITIONAL_${file_type}}) + endforeach() + + # Forward the arguments that are exactly the same for file(GET_RUNTIME_DEPENDENCIES). + foreach(var IN LISTS file_GRD_options) + if(NOT "${arg_${var}}" STREQUAL "") + list(APPEND tool_options ${var} ${arg_${var}}) + endif() endforeach() if(arg_NO_TRANSLATIONS) diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index 721f20ebdd7..d72d16a04a5 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -2452,6 +2452,24 @@ function(_qt_internal_setup_deploy_support) _qt_internal_add_deploy_support("${CMAKE_CURRENT_LIST_DIR}/Qt6CoreDeploySupport.cmake") + set(deploy_ignored_lib_dirs "") + if(__QT_DEPLOY_TOOL STREQUAL "GRD" AND NOT "${QT6_INSTALL_PREFIX}" STREQUAL "") + # Set up the directories we want to ignore when running file(GET_RUNTIME_DEPENDENCIES). + # If the Qt prefix is the root of one of those directories, don't ignore that directory. + # For example, if Qt's installation prefix is /usr, then we don't want to ignore /usr/lib. + foreach(link_dir IN LISTS CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES) + file(RELATIVE_PATH relative_dir "${QT6_INSTALL_PREFIX}" "${link_dir}") + if(relative_dir STREQUAL "") + # The Qt prefix is exactly ${link_dir}. + continue() + endif() + if(IS_ABSOLUTE "${relative_dir}" OR relative_dir MATCHES "^\\.\\./") + # The Qt prefix is outside of ${link_dir}. + list(APPEND deploy_ignored_lib_dirs "${link_dir}") + endif() + endforeach() + endif() + # Check whether we will have to adjust the RPATH of plugins. if("${QT_DEPLOY_FORCE_ADJUST_RPATHS}" STREQUAL "") set(must_adjust_plugins_rpath "") @@ -2503,6 +2521,9 @@ endif() if(QT_DEPLOY_PREFIX STREQUAL \"\") set(QT_DEPLOY_PREFIX .) endif() +if(NOT QT_DEPLOY_IGNORED_LIB_DIRS) + set(QT_DEPLOY_IGNORED_LIB_DIRS \"${deploy_ignored_lib_dirs}\") +endif() # These are internal implementation details. They may be removed at any time. set(__QT_DEPLOY_SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\") diff --git a/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc b/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc index 8182dd74e4c..6be2639b21d 100644 --- a/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc +++ b/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc @@ -241,3 +241,32 @@ This variable is not meaningful when deploying on macOS or Windows. \sa QT_DEPLOY_SUPPORT, QT_DEPLOY_PREFIX, QT_DEPLOY_BIN_DIR, QT_DEPLOY_LIB_DIR, QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR */ + +/*! +\page cmake-variable-QT_DEPLOY_IGNORED_LIB_DIRS.html +\ingroup cmake-variables-qtcore + +\title QT_DEPLOY_IGNORED_LIB_DIRS +\target cmake-variable-QT_DEPLOY_IGNORED_LIB_DIRS + +\summary {Directories that are excluded from runtime dependencies search} + +\include cmake-deploy-var-usage.qdocinc + +\cmakevariablesince 6.5 +\preliminarycmakevariable + +This variable contains a list of directories that are not taken into account +when searching for runtime dependencies with \l{qt_deploy_runtime_dependencies}. + +Projects may alter this variable before calling +\l{qt_deploy_runtime_dependencies} to control from which directory runtime +dependencies are deployed. + +This variable is ignored if the \c{POST_EXCLUDE_REGEXES} option is specified in +the \l{qt_deploy_runtime_dependencies} call. + +This variable is not meaningful when deploying on macOS or Windows. + +\sa qt_deploy_runtime_dependencies +*/ diff --git a/src/corelib/doc/src/cmake/qt_deploy_runtime_dependencies.qdoc b/src/corelib/doc/src/cmake/qt_deploy_runtime_dependencies.qdoc index 16e3672b196..b503b4b8d82 100644 --- a/src/corelib/doc/src/cmake/qt_deploy_runtime_dependencies.qdoc +++ b/src/corelib/doc/src/cmake/qt_deploy_runtime_dependencies.qdoc @@ -39,6 +39,12 @@ qt_deploy_runtime_dependencies( [NO_OVERWRITE] [NO_APP_STORE_COMPLIANCE] [NO_TRANSLATIONS] + [PRE_INCLUDE_REGEXES regexes...] + [PRE_EXCLUDE_REGEXES regexes...] + [POST_INCLUDE_REGEXES regexes...] + [POST_EXCLUDE_REGEXES regexes...] + [POST_INCLUDE_FILES files...] + [POST_EXCLUDE_FILES files...] ) \endcode @@ -119,6 +125,20 @@ inhibit this behavior, specify \c{NO_TRANSLATIONS}. Use \l{qt6_deploy_translations}{qt_deploy_translations} to deploy translations in a customized way. +On Linux, deploying runtime dependencies is based on CMake's +\c{file(GET_RUNTIME_DEPENDENCIES)} command. The options \c{PRE_INCLUDE_REGEXES}, +\c{PRE_EXCLUDE_REGEXES}, \c{POST_INCLUDE_REGEXES}, \c{POST_EXCLUDE_REGEXES}, +\c{POST_INCLUDE_FILES}, and \c{POST_EXCLUDE_FILES} are only meaningful in this +context and are forwarded unaltered to \c{file(GET_RUNTIME_DEPENDENCIES)}. See +the documentation of that command for details. + +On Linux, runtime dependencies that are located in system library directories +are not deployed by default. If \c{POST_EXCLUDE_REGEXES} is specified, this +automatic exclusion is not performed. + +The default value of \c{POST_EXCLUDE_REGEXES} is constructed from the value of +\l{QT_DEPLOY_IGNORED_LIB_DIRS}. + \sa {qt6_generate_deploy_app_script}{qt_generate_deploy_app_script()}, qt_deploy_qt_conf(), qt_deploy_qml_imports()