summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2022-09-29 16:55:46 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2022-10-15 13:00:13 +0200
commit1407e0fe501c26bfc16f31750d4a84b4f5d37ea4 (patch)
tree43b81307747449850c36388c4c52b7343de1d076
parent5430fb22439db9fc1ad1df4cbf0319b63346b0a5 (diff)
CMake: Deploy runtime dependencies outside of the Qt prefix too
We restricted the runtime dependencies we deployed on Linux to libraries within the Qt installation prefix. This restriction was supposed to prevent the deployment of all kinds of system libraries, which is most likely not wanted. However, the user might link against non-system libraries, and those should be deployed. The same holds for QML backend libraries that exist outside the Qt installation prefix in the build directory of the project. Now, we restrict deployment to libraries that are not in default system library directories. This can be overridden with the new qt_deploy_runtime_dependencies option POST_EXCLUDE_REGEXES. We add the following options to qt_deploy_runtime_dependencies, which are then forwarded to file(GET_RUNTIME_DEPENDENCIES): PRE_INCLUDE_REGEXES, PRE_EXCLUDE_REGEXES, POST_INCLUDE_REGEXES, POST_EXCLUDE_REGEXES, and POST_INCLUDE_FILES. Change-Id: I99a98fd91218abedda270609d0bafbb7f3e0feeb Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r--src/corelib/Qt6CoreDeploySupport.cmake89
-rw-r--r--src/corelib/Qt6CoreMacros.cmake21
-rw-r--r--src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc29
-rw-r--r--src/corelib/doc/src/cmake/qt_deploy_runtime_dependencies.qdoc20
4 files changed, 128 insertions, 31 deletions
diff --git a/src/corelib/Qt6CoreDeploySupport.cmake b/src/corelib/Qt6CoreDeploySupport.cmake
index 98d6b2b553..d149796b21 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 721f20ebdd..d72d16a04a 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 8182dd74e4..6be2639b21 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 16e3672b19..b503b4b8d8 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()