Skip to content

Commit

Permalink
CMake: Fix implementation of qt_apply_rpaths
Browse files Browse the repository at this point in the history
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 67ee92f

Change-Id: I04168633ec51b3cc5d580b738a7dc280fe6e0d2d
Reviewed-by: Jörg Bornemann <[email protected]>
  • Loading branch information
alcroito committed Apr 19, 2022
1 parent e28a32e commit 8254ee6
Showing 1 changed file with 44 additions and 14 deletions.
58 changes: 44 additions & 14 deletions cmake/QtRpathHelpers.cmake
Original file line number Diff line number Diff line change
@@ -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
# like $ORIGIN / @loader_path
# Not all platforms support such tokens though, in which case the returned rpath will be invalid.
Expand All @@ -10,9 +23,10 @@ function(qt_compute_relative_rpath_base rpath install_location out_var)
get_filename_component(rpath_absolute "${rpath}"
ABSOLUTE BASE_DIR "${install_lib_dir_absolute}")

if(NOT IS_ABSOLUTE)
set(install_location_absolute "${CMAKE_INSTALL_PREFIX}/${install_location}")
endif()
set(install_location_absolute "${install_location}")
if(NOT IS_ABSOLUTE "${install_location_absolute}")
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
# will be placed (INSTALL_LIBDIR).
file(RELATIVE_PATH rpath_relative "${install_location_absolute}" "${rpath_absolute}")
Expand All @@ -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
# 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.
if(APPLE)
set(rpath_rel_base "@loader_path")
elseif(LINUX OR SOLARIS OR FREEBSD OR HURD)
set(rpath_rel_base "$ORIGIN")
else()
qt_internal_get_relative_rpath_base_token(rpath_rel_base)
if(rpath_rel_base STREQUAL "NO_KNOWN_RPATH_REL_BASE")
message(WARNING "No known RPATH_REL_BASE for target platform.")
set(rpath_rel_base "NO_KNOWN_RPATH_REL_BASE")
endif()

if(rpath_relative STREQUAL ".")
Expand Down Expand Up @@ -70,7 +80,8 @@ function(qt_apply_rpaths)
endif()

# 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()
endif()

Expand Down Expand Up @@ -124,8 +135,18 @@ function(qt_apply_rpaths)
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
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(
"${_default_install_rpath}" "${arg_INSTALL_PATH}" relative_rpath)
list(APPEND rpaths "${relative_rpath}")
Expand All @@ -135,11 +156,20 @@ function(qt_apply_rpaths)

# Somewhat similar to mkspecs/features/qt_build_extra.prf.
foreach(rpath ${QT_EXTRA_RPATHS})
if(IS_ABSOLUTE)
if(IS_ABSOLUTE "${rpath}")
list(APPEND rpaths "${rpath}")
else()
qt_compute_relative_rpath_base("${rpath}" "${arg_INSTALL_PATH}" relative_rpath)
list(APPEND rpaths "${relative_rpath}")
if(relative_rpath_supported)
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()
endforeach()

Expand Down

0 comments on commit 8254ee6

Please sign in to comment.