I will put you in context:
I have 2 third party shared libraries: libA.so and libB.so. My program contains only calls to libA.so symbols. The libA.so internaly needs to call to libB.so. If I readelf LibA.so it has a RunPath pointing to a path from the third party developer that doesn't exsist in my system.
My program builds with cmake. I use find_library(A) and find_libary(B) and then add them to my program executable target with target_link_libraries(my_executable PUBLIC A B)
With this setup the generated executable contains a correct RUNPATH for both libA.so and libB.so. The problem is that when running the executable the libB.so file is not found.
I need to keep the .so files in the place they are. Setting up LD_LIBRARY_PATH env variable or moving to a ldd valid folder is not an option. I have tried these solutions and they work btw.
How could I make the executable to find libB.so in this case.
Thanks in advance.
CodePudding user response:
You can change RPATH with a tool named patchelf:
sudo apt install patchelf
patchelf --set-rpath \$ORIGIN libMyLibrary.so
Note that $ORIGIN here means "search in the folder where this library located". You can also combine values like this: \$ORIGIN:\$ORIGIN/../lib. This is convenient if you want to keep unix-like installation structure (executables in bin, libraries in lib).
CodePudding user response:
If I readelf LibA.so it has a RunPath pointing to a path from the third party developer that doesn't [exist] in my system.
Ah, classic case of bad software distribution. Not to worry, CMake allows you to add entries to the build RPATH of all targets in your tree. Just set:
# For example:
find_library(LIB_B_LIBRARY NAMES libB ...)
cmake_path(GET LIB_B_LIBRARY PARENT_PATH LIB_B_DIR)
# Here is the important line:
list(APPEND CMAKE_BUILD_RPATH "${LIB_B_DIR}")
# The above must come before this line:
add_executable(my_executable ...)
early in your CMakeLists.txt (before any other targets are created). This will add RPATH entries to your compiled binaries that should enable my_executable to find libB inside the build tree. When you go to install my_executable and libB, just make sure that my_executable has a sane install RPATH like $ORIGIN:$ORIGIN/../lib and that libB is installed to a standard location.
