-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Search RUNPATH to find library on Linux #44
Conversation
Signed-off-by: Tim Wiese <[email protected]>
Signed-off-by: Tim Wiese <[email protected]>
BUILD_RPATH is set to find test library INSTALL_RPATH_USE_LINK_PATH adds linked library paths to RUNPATH Signed-off-by: Tim Wiese <[email protected]>
Signed-off-by: Tim Wiese <[email protected]>
Signed-off-by: Tim Wiese <[email protected]>
Thanks for your contribution! The approach LGTM, a few nits about the implementation and test. |
Signed-off-by: Tim Wiese <[email protected]>
Signed-off-by: Tim Wiese <[email protected]>
Signed-off-by: Tim Wiese <[email protected]>
…_library test for RUNPATH test case This should avoid unintended effects of global environment changes, as cmake's set_tests_properties restores the environment to its previous state after the test is done. It also emulates better the effect of a setcap / setuid executable for the RUNPATH test case (LD_LIBRARY_PATH being dropped at execution). Signed-off-by: Tim Wiese <[email protected]>
Seems like the CI failed building the code. |
Co-Authored-By: Thomas Moulard <[email protected]> Signed-off-by: Tim Wiese <[email protected]>
Signed-off-by: Tim Wiese <[email protected]>
Fixed now, thanks for reviewing! |
set_target_properties(${PROJECT_NAME} PROPERTIES | ||
BUILD_RPATH ${CMAKE_CURRENT_BINARY_DIR} | ||
INSTALL_RPATH_USE_LINK_PATH TRUE | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The overall thing that concerns me about this is this bit. As far as I know, we don't currently set RPATH/RUNPATH on any of our shared objects. In order for this to truly work in general, we would have to start setting that, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for taking so long to reply. I think you are right, for this to work in general, you would need to have set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
for all projects.
What we are currently doing in our project is using set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
together with set(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags")
. This makes use of RPATH instead of RUNPATH. RPATH works with indirect shared library dependencies, whereas RUNPATH does not. This, together with the changes from this pull request, allows us to load all shared libraries without having to rely on LD_LIBRARY_PATH
. However, RPATH is deprecated, so I don't think this is a good general solution.
Would it be an option to set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
globally for ament_cmake? I am not sure about any downsides of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There has been no activity here in quite a while, so I just wanted to ask if there is any update on this. As a workaround, we are currently running our node in a root shell, but of course we would prefer not to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also wanted to check on the status of this. I'm working on a linuxdeploy plugin for building AppImages that bundle a ROS2 app and its dependencies (similar to the linuxdeploy qt plugin).
Certain dependencies, like RMW implementations, are searched for at runtime with RPATH/RUNPATH excluded, so even if the executable's RPATH points to the place where these libraries are located, find_library_path() fails to pick them up. Would be nice to not have to rely on setting environment variables like LD_LIBRARY_PATH or having to source the setup.bash scripts as a custom init step in the AppImage's entrypoint (they are already slow enough to start, due to the squashfs mounting step 🙂)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I think there are two different things going on in this PR (please correct me if I'm wrong):
- We are adding code to search the RPATH/RUNPATH for symbols (these are the changes in
find_library.cpp
). - We are switching the code to force RPATH instead of RUNPATH (this is the initial changes in CMakeLists.txt).
I'm fine with the first one; in our current system, that will really have no effect, but gets us closer to what @wieset and others want. I'm much less sure about the implications about the second one, which I think is what is mostly holding this up.
So my suggestion here is that we split out the second part from this PR, and just concentrate on getting the "search in RPATH" changes in. Once that is in, we can consider the "force RUNPATH -> RPATH" separately. Does that make sense?
(also, this PR needs a rebase since things have changed in the meantime)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, there are two things going on. I think the first one is obsolete now with ros2/rcutils#320 which is great! The second one is actually a bit different. It does not force RPATH
instead of RUNPATH
at all. Even though CMake uses RPATH
in their variable names, it refers to RUNPATH
since RPATH
is deprecated.
BUILD_RPATH ${CMAKE_CURRENT_BINARY_DIR}
is necessary so thatRUNPATH
in the build binary gets populated with the path to the test libraryINSTALL_RPATH_USE_LINK_PATH TRUE
is necessary so thatRUNPATH
in the installed binary gets populated properly
However, thinking about it again, INSTALL_RPATH_USE_LINK_PATH TRUE
needs to be set for ALL packages so that RUNPATH
can be used as an alternative to LD_LIBRARY_PATH
. The reason for this is that RUNPATH
only works for direct shared object dependencies. See also the discussion here: https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1737608
And this is what's necessary for us to be able to run a node with setcap
since it drops LD_LIBRARY_PATH
. A solution I see would be to have set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
in the ament_package()
macro.
I hope this explanation is clear. What do you think about closing this PR and continuing the discussion in https://github.com/ament/ament_cmake/?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope this explanation is clear. What do you think about closing this PR and continuing the discussion in https://github.com/ament/ament_cmake/?
That sounds reasonable to me, thanks. I'll go ahead and close this; please feel free to open an issue over there.
Proposal to fix #40
Based on a code snippet from Stack Overflow:
https://stackoverflow.com/questions/2836330/is-there-a-way-to-inspect-the-current-rpath-on-linux