Rcutils: find_library:优先选择当前加载的库而不是搜索`LD_LIBRARY_PATH`。

创建于 2019-03-25  ·  22评论  ·  资料来源: ros2/rcutils

目前, find_library会直接沿着LD_LIBRARY_PATH进入搜索库,而不是首先查询已加载的库。 当前的三种实现之一:
https://github.com/ros2/rmw_implementation/blob/32c3de1/rmw_implementation/src/functions.cpp#L77

如果此代码代替了当前加载的库,以支持那些不希望在运行时切换DDS实现(例如简化repro案例等)的应用程序代码,而RPATH链接了相应的库,那就太好了。

help wanted

最有用的评论

嗯,我开始怀疑为什么我们需要rcpputils::find_library_path()开始。 如果我们只为rcutils_load_shared_library()或其rcpputils::SharedLibrary包装器提供相对路径,则dlopenLoadLibrary将搜索路径并生成加载的目标文件。 两者的文档都建议不再加载已加载的目标文件。 这样,默认情况下将遵循RPATH,LD_LIBRARY_PATH,RUNPATH,PATH和预加载的库。

CC @ EricCousineau-TRI @wieset @clalancette。

所有22条评论

在此Bazel repro项目的提交中,我现在可以在链接时指定RMW实施,或遵循环境变量:
https://github.com/EricCousineau-TRI/repro/commit/cea11026722b340580257564dc49cb0f59b55178

@ dirk-thomas我会发现这非常有用。 请问有什么证据(如果有的话)会影响您的考虑? :D

请问有什么证据(如果有的话)会影响您的考虑?

由于发行版的目的是确保稳定性backport仅用于错误修复。 增强功能应针对下一个发行版。

Dashing的第一个测试包计划于4月的第一周提供。

是的,听起来不错。 将等待https://github.com/ros2/rcpputils/issues/3的合并,然后将其提交给dev分支。 谢谢!

我们有一个ros2节点,需要通过setcap设置功能,这会导致在执行过程中省略LD_LIBRARY_PATH 。 因此,我们在二进制文件中设置RPATH来查找共享库。 但是,由于find_library_path依赖于LD_LIBRARY_PATH因此节点失败

terminate called after throwing an instance of 'rclcpp::exceptions::RCLError'
  what():  failed to initialized rcl init options: failed to find shared library of rmw implementation. Searched rmw_fastrtps_cpp, at /tmp/binarydeb/ros-eloquent-rmw-implementation-0.8.2/src/functions.cpp:130, at /tmp/binarydeb/ros-eloquent-rcl-0.8.3/src/rcl/init_options.c:55

如果我理解正确,@ EricCousineau-TRI的建议将解决此问题。 有机会在下一个版本中获得此功能吗? 或任何解决方法的建议?

@ EricCousineau-TRI您打算对此进行迭代吗?

如果我理解正确,@ EricCousineau-TRI的建议将解决此问题。

@wieset如果您要查找/加载的库尚未加载,

@ivanpauno很可能在不久的将来(

@ dirk-thomas我看了@ EricCousineau-TRI的示例代码,您是对的,如果尚未加载该库,它将无法解决我的问题。 我想我可以在构建时链接它,以便在程序启动时加载它?

但是,要保留运行时的加载,我看到两个选项:必须搜索RPATH ,可以通过CMAKE_INSTALL_RPATH ,也可以使用另一个环境变量代替LD_LIBRARY_PATH ,例如RMW_LIBRARY_PATH 。 我在https://github.com/ros2/rcpputils/issues/40中提到了这两个选项

@wieset自定义构建,以将rpath用于此用例听起来像是要走的路。

@ dirk-thomas同意,我已经在使用RPATH来加载所有其他库。 但这并不能绕过rmw库的find_library_path()当前不在那的事实。 还是我错过了什么?

但这并不能绕开rtw库的find_library_path()当前不在那的事实。

你是对的。 我错过了这张票的背景。

我想知道为此引入一个单独的环境变量是否有意义,还是只应确保在以root用户身份运行可执行文件时自行显式设置现有环境变量。

据我了解,对于setcap / setuid可执行文件, LD_LIBRARY_PATH被完全忽略,因此不幸的是自己进行设置。 参见http://man7.org/linux/man-pages/man8/ld.so.8.html

不知道是否引入像ROS_LIBRARY_PATH这样的新环境变量来绕过该安全限制是否是一个好主意。 ld只不会过滤它,因为它不知道,并且出于安全考虑,它会忽略LD_LIBRARY_PATH

请随意提出PR来添加此增强功能(如“需要帮助”标签所示)。

会调查一下!

https://github.com/ros2/rcpputils/pull/44创建了一个拉取请求

FWIW @hidmic@ iantheengineer和我开始与TRI的其他人讨论这个问题。 首先是针对我们的内部使用,然后是与Drake之类的东西集成。

嗯,我开始怀疑为什么我们需要rcpputils::find_library_path()开始。 如果我们只为rcutils_load_shared_library()或其rcpputils::SharedLibrary包装器提供相对路径,则dlopenLoadLibrary将搜索路径并生成加载的目标文件。 两者的文档都建议不再加载已加载的目标文件。 这样,默认情况下将遵循RPATH,LD_LIBRARY_PATH,RUNPATH,PATH和预加载的库。

CC @ EricCousineau-TRI @wieset @clalancette。

好的,有关此问题的第一个信息,请参阅#320和已连接的PR。 @wieset这也应该(间接)解决您的问题。 这些更改使rcpputils::find_library_path过时(用于核心软件包)。

@hidmic现在我们已经排名#320和朋友,我们可以解决这个问题吗?

确实可以。 感谢您的加油!

非常感谢@hidmic ,我认为这使我半途而废。 RUNPATH仍然需要正确填充。 我将在https://github.com/ros2/rcpputils/pull/44中继续使用@clalancette进行讨论

此页面是否有帮助?
0 / 5 - 0 等级