Skip to content

Commit 5417d48

Browse files
committed
[CMake] Set rpath for individual targets and not globally
When using the `rpath=ON` option, the global CMake variable `CMAKE_INSTALL_RPATH` is mutated, which is problematic in several corner cases. Furthermore, the path is set to match the install tree, resulting in nonsensical relative rpath for the build tree if the directory structure is different (e.g. because of `gnuinstall=ON`). This commit suggests to append the rpaths at the target property level, and also set the rpaths for the build tree separately so they make sense. New ROOT macros are introduced for this rpath setting, which are also used for the PyROOT libraries, which also need custom rpaths. Closes #19327 and #19134.
1 parent f1fb562 commit 5417d48

File tree

4 files changed

+95
-69
lines changed

4 files changed

+95
-69
lines changed

bindings/pyroot/cppyy/CPyCppyy/CMakeLists.txt

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -112,47 +112,13 @@ target_include_directories(CPyCppyy
112112
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
113113
)
114114

115-
if(NOT MSVC)
116-
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
117-
118-
file(RELATIVE_PATH pymoduledir_to_libdir_build ${localruntimedir} "${localruntimedir}")
119-
file(RELATIVE_PATH pymoduledir_to_libdir_install ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_PYTHONDIR} "${CMAKE_INSTALL_FULL_LIBDIR}")
120-
121-
if(APPLE)
122-
set_target_properties(cppyy PROPERTIES
123-
BUILD_RPATH "@loader_path/${pymoduledir_to_libdir_build}"
124-
INSTALL_RPATH "@loader_path/${pymoduledir_to_libdir_install}"
125-
)
126-
else()
127-
set_target_properties(cppyy PROPERTIES
128-
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
129-
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
130-
)
131-
endif()
132-
133-
endif()
134-
135115
set_property(GLOBAL APPEND PROPERTY ROOT_EXPORTED_TARGETS CPyCppyy)
136116
set_property(GLOBAL APPEND PROPERTY ROOT_EXPORTED_TARGETS cppyy)
137117

138118
if(NOT MSVC)
139119
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
140-
141-
file(RELATIVE_PATH pymoduledir_to_libdir_build ${localruntimedir} "${localruntimedir}")
142-
file(RELATIVE_PATH pymoduledir_to_libdir_install ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_PYTHONDIR} "${CMAKE_INSTALL_FULL_LIBDIR}")
143-
144-
if(APPLE)
145-
set_target_properties(${libname} PROPERTIES
146-
BUILD_RPATH "@loader_path/${pymoduledir_to_libdir_build}"
147-
INSTALL_RPATH "@loader_path/${pymoduledir_to_libdir_install}"
148-
)
149-
else()
150-
set_target_properties(${libname} PROPERTIES
151-
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
152-
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
153-
)
154-
endif()
155-
120+
ROOT_APPEND_LIBDIR_TO_BUILD_RPATH(cppyy)
121+
ROOT_APPEND_LIBDIR_TO_INSTALL_RPATH(cppyy ${CMAKE_INSTALL_PYTHONDIR})
156122
endif()
157123

158124
# Install library

bindings/pyroot/pythonizations/CMakeLists.txt

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -227,22 +227,8 @@ endif()
227227

228228
if(NOT MSVC)
229229
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
230-
231-
file(RELATIVE_PATH pymoduledir_to_libdir_build ${pymoduledir_build} "${localruntimedir}")
232-
file(RELATIVE_PATH pymoduledir_to_libdir_install ${CMAKE_INSTALL_PREFIX}/${pymoduledir_install} "${CMAKE_INSTALL_FULL_LIBDIR}")
233-
234-
if(APPLE)
235-
set_target_properties(${libname} PROPERTIES
236-
BUILD_RPATH "@loader_path/${pymoduledir_to_libdir_build}"
237-
INSTALL_RPATH "@loader_path/${pymoduledir_to_libdir_install}"
238-
)
239-
else()
240-
set_target_properties(${libname} PROPERTIES
241-
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
242-
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
243-
)
244-
endif()
245-
230+
ROOT_APPEND_LIBDIR_TO_BUILD_RPATH(${libname})
231+
ROOT_APPEND_LIBDIR_TO_INSTALL_RPATH(${libname} ${pymoduledir_install})
246232
endif()
247233

248234
# Install library

cmake/modules/RootBuildOptions.cmake

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -423,23 +423,6 @@ include(RootInstallDirs)
423423
# add to RPATH any directories outside the project that are in the linker search path
424424
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
425425

426-
if(rpath)
427-
file(RELATIVE_PATH BINDIR_TO_LIBDIR "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}")
428-
429-
if(APPLE)
430-
set(CMAKE_MACOSX_RPATH TRUE)
431-
set(CMAKE_INSTALL_NAME_DIR "@rpath")
432-
433-
set(_rpath_values "@loader_path" "@loader_path/${BINDIR_TO_LIBDIR}")
434-
else()
435-
set(_rpath_values "$ORIGIN" "$ORIGIN/${BINDIR_TO_LIBDIR}")
436-
endif()
437-
438-
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH-CACHED};${_rpath_values}" CACHE STRING "Install RPATH" FORCE)
439-
440-
unset(BINDIR_TO_LIBDIR)
441-
endif()
442-
443426
#---deal with the DCMAKE_IGNORE_PATH------------------------------------------------------------
444427
if(macos_native)
445428
if(APPLE)

cmake/modules/RootMacros.cmake

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,8 +973,15 @@ function(ROOT_LINKER_LIBRARY library)
973973
endforeach()
974974
endif()
975975

976+
if(rpath)
977+
ROOT_APPEND_LIBDIR_TO_BUILD_RPATH(${library})
978+
endif()
979+
976980
#----Installation details-------------------------------------------------------
977981
if(NOT ARG_TEST AND NOT ARG_NOINSTALL AND CMAKE_LIBRARY_OUTPUT_DIRECTORY)
982+
if(rpath)
983+
ROOT_APPEND_LIBDIR_TO_INSTALL_RPATH(${library} ${CMAKE_INSTALL_LIBDIR})
984+
endif()
978985
if(ARG_CMAKENOEXPORT)
979986
install(TARGETS ${library} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libraries
980987
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries
@@ -1435,8 +1442,16 @@ function(ROOT_EXECUTABLE executable)
14351442
set_property(TARGET ${executable}
14361443
APPEND PROPERTY LINK_LIBRARIES ROOT::ROOTStaticSanitizerConfig)
14371444
endif()
1445+
1446+
if(rpath)
1447+
ROOT_APPEND_LIBDIR_TO_BUILD_RPATH(${executable})
1448+
endif()
1449+
14381450
#----Installation details------------------------------------------------------
14391451
if(NOT ARG_NOINSTALL AND CMAKE_RUNTIME_OUTPUT_DIRECTORY)
1452+
if(rpath)
1453+
ROOT_APPEND_LIBDIR_TO_INSTALL_RPATH(${executable} ${CMAKE_INSTALL_BINDIR})
1454+
endif()
14401455
if(ARG_CMAKENOEXPORT)
14411456
install(TARGETS ${executable} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications)
14421457
else()
@@ -2073,6 +2088,82 @@ function(generateManual name input output)
20732088
install(FILES ${output} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
20742089
endfunction()
20752090

2091+
#----------------------------------------------------------------------------
2092+
# --- ROOT_APPEND_LIBDIR_TO_BUILD_RPATH(target)
2093+
# Sets the BUILD_RPATH for a given target so that it can find the ROOT shared
2094+
# libraries at runtime. The RPATH is set relative to the target's own location
2095+
# using $ORIGIN (or @loader_path on macOS).
2096+
#
2097+
# Arguments:
2098+
# target - The CMake target (e.g., a shared library or executable)
2099+
#----------------------------------------------------------------------------
2100+
function(ROOT_APPEND_LIBDIR_TO_BUILD_RPATH target)
2101+
get_target_property(target_type ${target} TYPE)
2102+
2103+
if(target_type STREQUAL "EXECUTABLE")
2104+
get_target_property(output_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
2105+
elseif(target_type STREQUAL "STATIC_LIBRARY")
2106+
get_target_property(output_dir ${target} ARCHIVE_OUTPUT_DIRECTORY)
2107+
elseif(target_type STREQUAL "SHARED_LIBRARY")
2108+
get_target_property(output_dir ${target} LIBRARY_OUTPUT_DIRECTORY)
2109+
else()
2110+
message(FATAL_ERROR "${target} is of type ${target_type}, which is not supported by ROOT_APPEND_LIBDIR_TO_BUILD_RPATH")
2111+
endif()
2112+
2113+
# If the output directory propert was not set, the output will default to the
2114+
# current binary directory.
2115+
if(output_dir STREQUAL "output_dir-NOTFOUND")
2116+
get_target_property(output_dir ${target} BINARY_DIR)
2117+
endif()
2118+
2119+
# Figure out the output directory of the main ROOT libraries. We can't use
2120+
# any variables like CMAKE_LIBRARY_OUTPUT_DIRECTORY for this, because the
2121+
# ROOT CMake code temporarily changes them in some cases (e.g. in roottest).
2122+
get_target_property(main_libdir Core LIBRARY_OUTPUT_DIRECTORY)
2123+
2124+
file(RELATIVE_PATH to_libdir "${output_dir}" "${main_libdir}")
2125+
2126+
# New path
2127+
if(APPLE)
2128+
set(new_rpath "@loader_path/${to_libdir}")
2129+
else()
2130+
set(new_rpath "$ORIGIN/${to_libdir}")
2131+
endif()
2132+
2133+
# Append to existing RPATH
2134+
get_target_property(existing_rpath ${target} BUILD_RPATH)
2135+
list(APPEND existing_rpath "${new_rpath}")
2136+
set_target_properties(${target} PROPERTIES BUILD_RPATH "${existing_rpath}")
2137+
endfunction()
2138+
2139+
#----------------------------------------------------------------------------
2140+
# --- ROOT_APPEND_LIBDIR_TO_INSTALL_RPATH(target install_dir)
2141+
#
2142+
# Sets the INSTALL_RPATH for a given target so that it can find the ROOT shared
2143+
# libraries at runtime. The RPATH is set relative to the target's own location
2144+
# using $ORIGIN (or @loader_path on macOS).
2145+
#
2146+
# Arguments:
2147+
# target - The CMake target (e.g., a shared library or executable)
2148+
# install_dir - The install subdirectory relative to CMAKE_INSTALL_PREFIX
2149+
#----------------------------------------------------------------------------
2150+
function(ROOT_APPEND_LIBDIR_TO_INSTALL_RPATH target install_dir)
2151+
file(RELATIVE_PATH to_libdir "${CMAKE_INSTALL_PREFIX}/${install_dir}" "${CMAKE_INSTALL_FULL_LIBDIR}")
2152+
2153+
# New path
2154+
if(APPLE)
2155+
set(new_rpath "@loader_path/${to_libdir}")
2156+
else()
2157+
set(new_rpath "$ORIGIN/${to_libdir}")
2158+
endif()
2159+
2160+
# Append to existing RPATH
2161+
get_target_property(existing_rpath ${target} INSTALL_RPATH)
2162+
list(APPEND existing_rpath "${new_rpath}")
2163+
set_target_properties(${target} PROPERTIES INSTALL_RPATH "${existing_rpath}")
2164+
endfunction()
2165+
2166+
20762167
#-------------------------------------------------------------------------------
20772168
#
20782169
# Former RoottestMacros.cmake starts here

0 commit comments

Comments
 (0)