mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-30 18:29:37 -06:00
file(GET_RUNTIME_DEPENDENCIES): propagate transitive parent's rpath
This fixes incorrect runtime dependency resolution when the dependency is located in rpaths of a transitive parent. Instead of supplying only the rpaths of the immediate parent, it combines the rpaths of all transitive parents and passes them down. Fixes: #24172
This commit is contained in:
@@ -154,8 +154,13 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
|
||||
if (!this->Archive->IsPostExcluded(path)) {
|
||||
bool unique;
|
||||
this->Archive->AddResolvedPath(dep, path, unique);
|
||||
if (unique && !this->ScanDependencies(path, rpaths)) {
|
||||
return false;
|
||||
if (unique) {
|
||||
std::vector<std::string> combinedParentRpaths = parentRpaths;
|
||||
combinedParentRpaths.insert(combinedParentRpaths.end(),
|
||||
rpaths.begin(), rpaths.end());
|
||||
if (!this->ScanDependencies(path, combinedParentRpaths)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -61,6 +61,7 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
|
||||
if(NOT CMAKE_C_COMPILER_ID MATCHES "^XL")
|
||||
run_install_test(linux)
|
||||
run_install_test(linux-parent-rpath-propagation)
|
||||
run_install_test(file-filter)
|
||||
endif()
|
||||
run_install_test(linux-unresolved)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
enable_language(C)
|
||||
cmake_policy(SET CMP0095 NEW)
|
||||
|
||||
# Force linker to set RPATH instead of RUNPATH
|
||||
add_link_options("-Wl,--disable-new-dtags")
|
||||
|
||||
# bin/exe (RPATH = "lib1:lib2:lib3")
|
||||
# ^
|
||||
# |
|
||||
# lib1/libone.so (RPATH erased)
|
||||
# ^
|
||||
# |
|
||||
# lib2/libtwo.so (RPATH erased)
|
||||
# ^
|
||||
# |
|
||||
# lib3/libthree.so (RPATH erased)
|
||||
# GET_RUNTIME_DEPENDENCIES(bin/exe) should resolve all three libraries
|
||||
|
||||
set(TEST_SOURCE_DIR "linux/parent-rpath-propagation")
|
||||
|
||||
add_library(three SHARED "${TEST_SOURCE_DIR}/three.c")
|
||||
|
||||
add_library(two SHARED "${TEST_SOURCE_DIR}/two.c")
|
||||
target_link_libraries(two PUBLIC three)
|
||||
|
||||
add_library(one SHARED "${TEST_SOURCE_DIR}/one.c")
|
||||
target_link_libraries(one PUBLIC two)
|
||||
|
||||
add_executable(exe "${TEST_SOURCE_DIR}/main.c")
|
||||
target_link_libraries(exe PUBLIC one)
|
||||
|
||||
set_property(TARGET exe PROPERTY INSTALL_RPATH
|
||||
$ORIGIN/../lib1
|
||||
$ORIGIN/../lib2
|
||||
$ORIGIN/../lib3
|
||||
)
|
||||
|
||||
install(TARGETS exe DESTINATION bin)
|
||||
install(TARGETS one DESTINATION lib1)
|
||||
install(TARGETS two DESTINATION lib2)
|
||||
install(TARGETS three DESTINATION lib3)
|
||||
|
||||
install(CODE [[
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
EXECUTABLES
|
||||
"${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:exe>"
|
||||
PRE_INCLUDE_REGEXES
|
||||
"^lib(one|two|three)\\.so$"
|
||||
"^libc\\.so"
|
||||
PRE_EXCLUDE_REGEXES ".*"
|
||||
POST_INCLUDE_REGEXES "^.*/lib(one|two|three)\\.so$"
|
||||
POST_EXCLUDE_REGEXES ".*"
|
||||
)
|
||||
]])
|
||||
@@ -0,0 +1,12 @@
|
||||
extern void one(void);
|
||||
extern void two(void);
|
||||
extern void three(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
one();
|
||||
two();
|
||||
three();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
extern void two(void);
|
||||
extern void three(void);
|
||||
|
||||
void one(void)
|
||||
{
|
||||
two();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
void three(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
extern void three(void);
|
||||
|
||||
void two(void)
|
||||
{
|
||||
three();
|
||||
}
|
||||
Reference in New Issue
Block a user