summaryrefslogtreecommitdiffstats
path: root/src/corelib/Qt6CoreDeploySupport.cmake
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2022-09-29 13:06:12 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2022-10-15 13:00:04 +0200
commit5430fb22439db9fc1ad1df4cbf0319b63346b0a5 (patch)
tree4c25135c0fb476dbb36bb2601d094d42b3e4b638 /src/corelib/Qt6CoreDeploySupport.cmake
parent5ca714318c4b0c02f3b9ef98c5fc1c948c35219e (diff)
CMake: Set RPATH of deployed plugins on Linux
When deploying into some directory structure where CMAKE_INSTALL_LIBDIR is different from Qt's lib dir, we need to set the RPATH of installed plugins such that Qt libraries are found. We do this using CMake's undocumented file(RPATH_SET) command and pray that this command is safe to use across current and future CMake versions. For CMake versions < 3.21, we use patchelf, which must be installed on the host system. The adjustment of rpaths can be turned on explicitly by setting QT_DEPLOY_FORCE_ADJUST_RPATHS to ON. The usage of patchelf can be forced by setting QT_DEPLOY_USE_PATCHELF to ON regardless of the CMake version. Change-Id: I62ced496b4c12bf6d46735d2af7ff35130148acb Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src/corelib/Qt6CoreDeploySupport.cmake')
-rw-r--r--src/corelib/Qt6CoreDeploySupport.cmake59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/corelib/Qt6CoreDeploySupport.cmake b/src/corelib/Qt6CoreDeploySupport.cmake
index 6a300bdfdf..98d6b2b553 100644
--- a/src/corelib/Qt6CoreDeploySupport.cmake
+++ b/src/corelib/Qt6CoreDeploySupport.cmake
@@ -111,6 +111,50 @@ function(_qt_internal_re_escape out_var str)
set(${out_var} ${regex} PARENT_SCOPE)
endfunction()
+function(_qt_internal_set_rpath)
+ if(NOT CMAKE_HOST_UNIX OR CMAKE_HOST_APPLE)
+ message(WARNING "_qt_internal_set_rpath is not implemented on this platform.")
+ return()
+ endif()
+
+ set(no_value_options "")
+ set(single_value_options FILE NEW_RPATH)
+ set(multi_value_options "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+ if(__QT_DEPLOY_USE_PATCHELF)
+ message(STATUS "Setting runtime path of '${arg_FILE}' to '${arg_NEW_RPATH}'.")
+ execute_process(
+ COMMAND ${__QT_DEPLOY_PATCHELF_EXECUTABLE} --set-rpath "${arg_NEW_RPATH}" "${arg_FILE}"
+ RESULT_VARIABLE process_result
+ )
+ if(NOT process_result EQUAL "0")
+ if(process_result MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "patchelf failed with exit code ${process_result}.")
+ else()
+ message(FATAL_ERROR "patchelf failed: ${process_result}.")
+ endif()
+ endif()
+ else()
+ # Warning: file(RPATH_SET) is CMake-internal API.
+ file(RPATH_SET
+ FILE "${arg_FILE}"
+ NEW_RPATH "${arg_NEW_RPATH}"
+ )
+ endif()
+endfunction()
+
+# Store the platform-dependent $ORIGIN marker in out_var.
+function(_qt_internal_get_rpath_origin out_var)
+ if(__QT_DEPLOY_SYSTEM_NAME STREQUAL "Darwin")
+ set(rpath_origin "@loader_path")
+ else()
+ set(rpath_origin "$ORIGIN")
+ endif()
+ set(${out_var} ${rpath_origin} PARENT_SCOPE)
+endfunction()
+
function(_qt_internal_generic_deployqt)
set(no_value_options
NO_TRANSLATIONS
@@ -196,6 +240,11 @@ function(_qt_internal_generic_deployqt)
FOLLOW_SYMLINK_CHAIN
)
+ # Determine the runtime path origin marker if necessary.
+ if(__QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH)
+ _qt_internal_get_rpath_origin(rpath_origin)
+ endif()
+
# Deploy the Qt plugins.
foreach(file_path IN LISTS __QT_DEPLOY_PLUGINS)
file(RELATIVE_PATH destination
@@ -205,6 +254,16 @@ function(_qt_internal_generic_deployqt)
get_filename_component(destination "${destination}" DIRECTORY)
string(PREPEND destination "${QT_DEPLOY_PREFIX}/${arg_PLUGINS_DIR}/")
file(INSTALL ${file_path} DESTINATION ${destination})
+
+ if(__QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH)
+ get_filename_component(file_name ${file_path} NAME)
+ file(RELATIVE_PATH rel_lib_dir "${destination}"
+ "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_LIB_DIR}")
+ _qt_internal_set_rpath(
+ FILE "${destination}/${file_name}"
+ NEW_RPATH "${rpath_origin}/${rel_lib_dir}"
+ )
+ endif()
endforeach()
# Deploy translations.