From 4aa3149c67165952306ed457eeaaab52a90285a5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 29 Nov 2022 17:47:15 -0500 Subject: Tests: Simplify RunCMake.file-GET_RUNTIME_DEPENDENCIES case cleaning --- Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake index 07679b7..90b3797 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake @@ -4,10 +4,8 @@ include(RunCMake) # Function to build and install a project. function(run_install_test case) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build) - set(RunCMake_TEST_NO_CLEAN 1) - file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") - file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") run_cmake(${case}) + set(RunCMake_TEST_NO_CLEAN 1) run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug) # Check "all" components. set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-all) -- cgit v0.12 From 136622a2b20ee36808cdf4e8dc2bf64fdf7e2f07 Mon Sep 17 00:00:00 2001 From: Alex Lapenkou Date: Tue, 29 Nov 2022 15:04:31 -0600 Subject: 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 --- Source/cmBinUtilsLinuxELFLinker.cxx | 9 +++- .../RunCMakeTest.cmake | 1 + .../linux-parent-rpath-propagation.cmake | 54 ++++++++++++++++++++++ .../linux/parent-rpath-propagation/main.c | 12 +++++ .../linux/parent-rpath-propagation/one.c | 7 +++ .../linux/parent-rpath-propagation/three.c | 3 ++ .../linux/parent-rpath-propagation/two.c | 6 +++ 7 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-parent-rpath-propagation.cmake create mode 100644 Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/main.c create mode 100644 Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/one.c create mode 100644 Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/three.c create mode 100644 Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/two.c diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx index a69c00d..5972202 100644 --- a/Source/cmBinUtilsLinuxELFLinker.cxx +++ b/Source/cmBinUtilsLinuxELFLinker.cxx @@ -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 combinedParentRpaths = parentRpaths; + combinedParentRpaths.insert(combinedParentRpaths.end(), + rpaths.begin(), rpaths.end()); + if (!this->ScanDependencies(path, combinedParentRpaths)) { + return false; + } } } } else { diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake index 90b3797..75bfc07 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-parent-rpath-propagation.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-parent-rpath-propagation.cmake new file mode 100644 index 0000000..7e9b7a5 --- /dev/null +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-parent-rpath-propagation.cmake @@ -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/$" + PRE_INCLUDE_REGEXES + "^lib(one|two|three)\\.so$" + "^libc\\.so" + PRE_EXCLUDE_REGEXES ".*" + POST_INCLUDE_REGEXES "^.*/lib(one|two|three)\\.so$" + POST_EXCLUDE_REGEXES ".*" + ) + ]]) diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/main.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/main.c new file mode 100644 index 0000000..12aba5d --- /dev/null +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/main.c @@ -0,0 +1,12 @@ +extern void one(void); +extern void two(void); +extern void three(void); + +int main(void) +{ + one(); + two(); + three(); + + return 0; +} diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/one.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/one.c new file mode 100644 index 0000000..9998da8 --- /dev/null +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/one.c @@ -0,0 +1,7 @@ +extern void two(void); +extern void three(void); + +void one(void) +{ + two(); +} diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/three.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/three.c new file mode 100644 index 0000000..0be5f47 --- /dev/null +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/three.c @@ -0,0 +1,3 @@ +void three(void) +{ +} diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/two.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/two.c new file mode 100644 index 0000000..370baf7 --- /dev/null +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/parent-rpath-propagation/two.c @@ -0,0 +1,6 @@ +extern void three(void); + +void two(void) +{ + three(); +} -- cgit v0.12