summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtAppHelpers.cmake1
-rw-r--r--cmake/QtBuildInformation.cmake18
-rw-r--r--cmake/QtModuleHelpers.cmake1
-rw-r--r--cmake/QtPluginHelpers.cmake1
-rw-r--r--cmake/QtRpathHelpers.cmake51
-rw-r--r--cmake/QtToolHelpers.cmake2
6 files changed, 73 insertions, 1 deletions
diff --git a/cmake/QtAppHelpers.cmake b/cmake/QtAppHelpers.cmake
index d0cca849f3..719b9d4793 100644
--- a/cmake/QtAppHelpers.cmake
+++ b/cmake/QtAppHelpers.cmake
@@ -111,4 +111,5 @@ function(qt_internal_finalize_app target)
# Rpaths need to be applied in the finalizer, because the MACOSX_BUNDLE property might be
# set after a qt_internal_add_app call.
qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${INSTALL_BINDIR}" RELATIVE_RPATH)
+ qt_internal_apply_staging_prefix_build_rpath_workaround()
endfunction()
diff --git a/cmake/QtBuildInformation.cmake b/cmake/QtBuildInformation.cmake
index 24dd0ab0d1..9676d5db78 100644
--- a/cmake/QtBuildInformation.cmake
+++ b/cmake/QtBuildInformation.cmake
@@ -8,9 +8,27 @@ function(qt_print_feature_summary)
OPTIONAL_PACKAGES_NOT_FOUND
RUNTIME_PACKAGES_NOT_FOUND
FATAL_ON_MISSING_REQUIRED_PACKAGES)
+ qt_internal_run_additional_summary_checks()
qt_configure_print_summary()
endfunction()
+function(qt_internal_run_additional_summary_checks)
+ get_property(
+ rpath_workaround_enabled
+ GLOBAL PROPERTY _qt_internal_staging_prefix_build_rpath_workaround)
+ if(rpath_workaround_enabled)
+ set(message
+ "Due to CMAKE_STAGING_PREFIX usage and an unfixed CMake bug,
+ to ensure correct build time rpaths, directory-level install
+ rules like ninja src/gui/install will not work.
+ Check QTBUG-102592 for further details.")
+ qt_configure_add_report_entry(
+ TYPE NOTE
+ MESSAGE "${message}"
+ )
+ endif()
+endfunction()
+
function(qt_print_build_instructions)
if((NOT PROJECT_NAME STREQUAL "QtBase" AND
NOT PROJECT_NAME STREQUAL "Qt") OR
diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake
index c7ae9590f2..ea1bf9cdfe 100644
--- a/cmake/QtModuleHelpers.cmake
+++ b/cmake/QtModuleHelpers.cmake
@@ -726,6 +726,7 @@ set(QT_LIBINFIX \"${QT_LIBINFIX}\")")
if(BUILD_SHARED_LIBS)
qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${INSTALL_LIBDIR}" RELATIVE_RPATH)
+ qt_internal_apply_staging_prefix_build_rpath_workaround()
endif()
if (ANDROID AND NOT arg_HEADER_MODULE)
diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake
index 7023e705e8..49fbe0eed2 100644
--- a/cmake/QtPluginHelpers.cmake
+++ b/cmake/QtPluginHelpers.cmake
@@ -422,6 +422,7 @@ function(qt_internal_add_plugin target)
)
if(BUILD_SHARED_LIBS)
qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${install_directory}" RELATIVE_RPATH)
+ qt_internal_apply_staging_prefix_build_rpath_workaround()
endif()
endif()
diff --git a/cmake/QtRpathHelpers.cmake b/cmake/QtRpathHelpers.cmake
index 9d65415bde..fc75b8f554 100644
--- a/cmake/QtRpathHelpers.cmake
+++ b/cmake/QtRpathHelpers.cmake
@@ -183,3 +183,54 @@ function(qt_apply_rpaths)
set_property(TARGET "${target}" APPEND PROPERTY "${prop_name}" ${rpaths})
endif()
endfunction()
+
+# Overrides the CMAKE_STAGING_PREFIX in a subdirectory scope, to stop CMake from rewriting build
+# rpaths to point into the original staging prefix, and thus breaking running executables from
+# the build directory.
+# See details at https://bugreports.qt.io/browse/QTBUG-102592
+# and https://gitlab.kitware.com/cmake/cmake/-/issues/23421
+#
+# This macro is only meant to be called in functions like
+# qt_internal_add_module / qt_internal_add_tool to ensure the variable is set in the
+# subdirectory scope of the calling function, and not in the actual function scope (where the
+# variable assignment would have no effect).
+#
+# This is the best workaround we can currently do, but it comes with the disadvantage that calling
+# subdirectory-scoped install targets does not work anymore.
+# e.g. calling ninja src/gui/install will try to install to the fake prefix and fail.
+# A regular ninja install call works fine.
+#
+# Usage of this macro assumes there are no binaries or libraries added in the root CMakeLists.txt
+# of the project because that would mean the macro is called at root level scope, which would
+# break installation.
+#
+# The implementation has to be a macro, so we can propagate the variable into the calling
+# subdirectory scope. The implementation can't use return().
+macro(qt_internal_apply_staging_prefix_build_rpath_workaround)
+ set(__qt_internal_should_apply_staging_prefix_build_rpath_workaround TRUE)
+ # Allow an opt out.
+ if(QT_NO_STAGING_PREFIX_BUILD_RPATH_WORKAROUND)
+ set(__qt_internal_should_apply_staging_prefix_build_rpath_workaround FALSE)
+ endif()
+
+ # No need for workaround if CMAKE_STAGING_PREFIX is not set.
+ if(NOT CMAKE_STAGING_PREFIX)
+ set(__qt_internal_should_apply_staging_prefix_build_rpath_workaround FALSE)
+ endif()
+
+ # No rpath support for win32, android, ios, so nothing to do.
+ if(WIN32 OR ANDROID OR UIKIT)
+ set(__qt_internal_should_apply_staging_prefix_build_rpath_workaround FALSE)
+ endif()
+
+ # Set the staging prefix to a non-existent directory, which is unlikely to have permissions
+ # for installation.
+ # The verbose directory name is chosen to attract the user's attention in case if they end up
+ # calling a subdirectory-scope install file.
+ if(__qt_internal_should_apply_staging_prefix_build_rpath_workaround)
+ set_property(GLOBAL PROPERTY _qt_internal_staging_prefix_build_rpath_workaround TRUE)
+ set(CMAKE_STAGING_PREFIX
+ "/qt_fake_staging_prefix/check_qt_internal_apply_staging_prefix_build_rpath_workaround"
+ PARENT_SCOPE)
+ endif()
+endmacro()
diff --git a/cmake/QtToolHelpers.cmake b/cmake/QtToolHelpers.cmake
index d640f146ae..054680f502 100644
--- a/cmake/QtToolHelpers.cmake
+++ b/cmake/QtToolHelpers.cmake
@@ -306,7 +306,7 @@ function(qt_internal_add_tool target_name)
endif()
qt_apply_rpaths(TARGET "${target_name}" INSTALL_PATH "${install_dir}" RELATIVE_RPATH)
-
+ qt_internal_apply_staging_prefix_build_rpath_workaround()
endif()
qt_enable_separate_debug_info(${target_name} "${install_dir}" QT_EXECUTABLE)