CMake: Fix implementation of qt_apply_rpaths

There were a few things that were not ported correctly.

Make sure to disable rpath manipulation if the rpath feature is
disabled.

Fix if(IS_ABSOLUTE) conditions to actually take values.

Don't embed bogus relative rpaths if the platform does not support
it. QNX is such a platform, it does not support $ORIGIN (at least from
my scouring of QNX documentation and manual testing via QEMU).

Handle the extra rpath case where they are relative, but the platform
does not support relative rpaths, by transforming them into absolute
ones.

Amends 67ee92f4d898ee76c40b7efd8e69782a6a4a3754

Task-number: QTBUG-103777
Change-Id: I04168633ec51b3cc5d580b738a7dc280fe6e0d2d
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 8254ee6a3bc6310cd7701450cc000fb04bf85671)
This commit is contained in:
Alexandru Croitor 2022-04-13 18:12:05 +02:00
parent 1bdeb16e39
commit c0e1fd501e

View File

@ -1,3 +1,16 @@
# Returns the platform-specific relative rpath base token, if it's supported.
# If it's not supported, returns the string NO_KNOWN_RPATH_REL_BASE.
function(qt_internal_get_relative_rpath_base_token out_var)
if(APPLE)
set(rpath_rel_base "@loader_path")
elseif(LINUX OR SOLARIS OR FREEBSD OR HURD)
set(rpath_rel_base "$ORIGIN")
else()
set(rpath_rel_base "NO_KNOWN_RPATH_REL_BASE")
endif()
set(${out_var} "${rpath_rel_base}" PARENT_SCOPE)
endfunction()
# Computes a relative rpath between ${rpath} and ${install_location} using tokens # Computes a relative rpath between ${rpath} and ${install_location} using tokens
# like $ORIGIN / @loader_path # like $ORIGIN / @loader_path
# Not all platforms support such tokens though, in which case the returned rpath will be invalid. # Not all platforms support such tokens though, in which case the returned rpath will be invalid.
@ -10,9 +23,10 @@ function(qt_compute_relative_rpath_base rpath install_location out_var)
get_filename_component(rpath_absolute "${rpath}" get_filename_component(rpath_absolute "${rpath}"
ABSOLUTE BASE_DIR "${install_lib_dir_absolute}") ABSOLUTE BASE_DIR "${install_lib_dir_absolute}")
if(NOT IS_ABSOLUTE) set(install_location_absolute "${install_location}")
set(install_location_absolute "${CMAKE_INSTALL_PREFIX}/${install_location}") if(NOT IS_ABSOLUTE "${install_location_absolute}")
endif() set(install_location_absolute "${CMAKE_INSTALL_PREFIX}/${install_location}")
endif()
# Compute relative rpath from where the target will be installed, to the place where libraries # Compute relative rpath from where the target will be installed, to the place where libraries
# will be placed (INSTALL_LIBDIR). # will be placed (INSTALL_LIBDIR).
file(RELATIVE_PATH rpath_relative "${install_location_absolute}" "${rpath_absolute}") file(RELATIVE_PATH rpath_relative "${install_location_absolute}" "${rpath_absolute}")
@ -25,13 +39,9 @@ function(qt_compute_relative_rpath_base rpath install_location out_var)
# Prepend $ORIGIN / @loader_path style tokens (qmake's QMAKE_REL_RPATH_BASE), to make the # Prepend $ORIGIN / @loader_path style tokens (qmake's QMAKE_REL_RPATH_BASE), to make the
# relative rpaths work. qmake does this automatically when generating a project, so it wasn't # relative rpaths work. qmake does this automatically when generating a project, so it wasn't
# needed in the .prf files, but for CMake we need to prepend them ourselves. # needed in the .prf files, but for CMake we need to prepend them ourselves.
if(APPLE) qt_internal_get_relative_rpath_base_token(rpath_rel_base)
set(rpath_rel_base "@loader_path") if(rpath_rel_base STREQUAL "NO_KNOWN_RPATH_REL_BASE")
elseif(LINUX OR SOLARIS OR FREEBSD)
set(rpath_rel_base "$ORIGIN")
else()
message(WARNING "No known RPATH_REL_BASE for target platform.") message(WARNING "No known RPATH_REL_BASE for target platform.")
set(rpath_rel_base "NO_KNOWN_RPATH_REL_BASE")
endif() endif()
if(rpath_relative STREQUAL ".") if(rpath_relative STREQUAL ".")
@ -70,7 +80,8 @@ function(qt_apply_rpaths)
endif() endif()
# Rpaths explicitly disabled (like for uikit), equivalent to qmake's no_qt_rpath. # Rpaths explicitly disabled (like for uikit), equivalent to qmake's no_qt_rpath.
if(QT_DISABLE_RPATH) # Or feature was turned OFF.
if(QT_DISABLE_RPATH OR NOT QT_FEATURE_rpath)
return() return()
endif() endif()
@ -124,8 +135,18 @@ function(qt_apply_rpaths)
endif() endif()
endif() endif()
qt_internal_get_relative_rpath_base_token(rpath_base_token)
if(rpath_base_token STREQUAL "NO_KNOWN_RPATH_REL_BASE")
set(relative_rpath_supported FALSE)
else()
set(relative_rpath_supported TRUE)
endif()
# Somewhat similar to mkspecs/features/qt.prf # Somewhat similar to mkspecs/features/qt.prf
if(arg_RELATIVE_RPATH) # Embed either an absolute path to the installed Qt lib dir, or a relative one, based on
# where ${target} is installed.
# Don't embed relative rpaths if the platform does not support it.
if(arg_RELATIVE_RPATH AND relative_rpath_supported)
qt_compute_relative_rpath_base( qt_compute_relative_rpath_base(
"${_default_install_rpath}" "${arg_INSTALL_PATH}" relative_rpath) "${_default_install_rpath}" "${arg_INSTALL_PATH}" relative_rpath)
list(APPEND rpaths "${relative_rpath}") list(APPEND rpaths "${relative_rpath}")
@ -135,11 +156,20 @@ function(qt_apply_rpaths)
# Somewhat similar to mkspecs/features/qt_build_extra.prf. # Somewhat similar to mkspecs/features/qt_build_extra.prf.
foreach(rpath ${QT_EXTRA_RPATHS}) foreach(rpath ${QT_EXTRA_RPATHS})
if(IS_ABSOLUTE) if(IS_ABSOLUTE "${rpath}")
list(APPEND rpaths "${rpath}") list(APPEND rpaths "${rpath}")
else() else()
qt_compute_relative_rpath_base("${rpath}" "${arg_INSTALL_PATH}" relative_rpath) if(relative_rpath_supported)
list(APPEND rpaths "${relative_rpath}") qt_compute_relative_rpath_base("${rpath}" "${arg_INSTALL_PATH}" relative_rpath)
list(APPEND rpaths "${relative_rpath}")
else()
# Any extra relative rpaths on a platform that does not support relative rpaths,
# need to be transformed into absolute ones.
set(install_lib_dir_absolute "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
get_filename_component(rpath_absolute "${rpath}"
ABSOLUTE BASE_DIR "${install_lib_dir_absolute}")
list(APPEND rpaths "${rpath_absolute}")
endif()
endif() endif()
endforeach() endforeach()