В настоящее время find_library
сразу попадает в поисковые библиотеки по LD_LIBRARY_PATH
, а не сначала запрашивает загруженные библиотеки. Одна из трех текущих реализаций:
https://github.com/ros2/rmw_implementation/blob/32c3de1/rmw_implementation/src/functions.cpp#L77
Было бы неплохо, если бы этот код вместо этого предпочитал загруженные в настоящее время библиотеки для поддержки кода приложения, которому не нужна возможность переключения реализаций DDS (например, упрощение случаев воспроизведения и т. Д.) Во время выполнения, и вместо этого RPATH связывает соответствующие библиотеки.
Вот рабочий прототип в Linux:
https://github.com/EricCousineau-TRI/rcpputils/commit/b66a3d9e02ace44e6c3b6022eeb3447b121d3311
Прикручивание из источника Дрейка:
https://github.com/RobotLocomotion/drake/blob/4c6246197/common/find_loaded_library.cc
В этом коммите для этого репро-проекта Bazel теперь я могу либо указать реализацию RMW во время компоновки, либо отложить до переменных среды:
https://github.com/EricCousineau-TRI/repro/commit/cea11026722b340580257564dc49cb0f59b55178
@ dirk-thomas Я считаю это чрезвычайно полезным. Могу я спросить, какие доказательства (если они есть) могут побудить вас задуматься об этом? : D
Могу я спросить, какие доказательства (если они есть) могут побудить вас задуматься об этом?
Поскольку цель дистрибутива - обеспечить стабильность, бэкпорты предназначены только для исправления ошибок. Улучшения должны быть нацелены на следующий дистрибутив.
Первые тестовые пакеты Dashing будут доступны в первую неделю апреля.
Да, звучит хорошо. Дождется слияния 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 К сожалению, не в ближайшее время (от 6 месяцев до 1 года) :(
@ 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
для загрузки всех остальных библиотек. Но это не позволяет мне осознать тот факт, что find_library_path()
для библиотеки rmw в настоящее время туда не смотрит. Или я что-то упускаю?
Но это не позволяет мне осознать тот факт, что
find_library_path()
для библиотеки rtw в настоящее время туда не смотрит.
Ты прав. Я упустил контекст этого билета.
Интересно, имеет ли смысл вводить для этого отдельную переменную среды или вам просто нужно убедиться, что при запуске исполняемых файлов от имени пользователя root необходимо явно устанавливать существующие переменные среды.
Насколько я понимаю, LD_LIBRARY_PATH
полностью игнорируется для исполняемых файлов setcap
/ setuid
, поэтому его установка, к сожалению, не поможет. См. Http://man7.org/linux/man-pages/man8/ld.so.8.html
Не уверен, что введение нового env var, такого как ROS_LIBRARY_PATH
чтобы обойти это ограничение безопасности, является хорошей идеей. ld
не будет фильтровать это только потому, что не знает об этом, и игнорирует LD_LIBRARY_PATH
из соображений безопасности.
Пожалуйста, не стесняйтесь предлагать PR для добавления этого улучшения (как указано меткой «требуется помощь»).
Разберемся в этом!
Создал пул-реквест на https://github.com/ros2/rcpputils/pull/44
FWIW @hidmic , @iantheengineer и я начинаем обсуждать это с другими Drake .
Хм, я начинаю задумываться, зачем нам для начала rcpputils::find_library_path()
. Если мы просто предоставим rcutils_load_shared_library()
или его оболочку rcpputils::SharedLibrary
с относительным путем, dlopen
и LoadLibrary
будут искать пути и возвращать загруженные объектные файлы. Документация для обоих предполагает, что уже загруженные объектные файлы больше не будут извлечены. При этом по умолчанию будут учитываться RPATH, LD_LIBRARY_PATH, RUNPATH, PATH и предварительно загруженные библиотеки.
CC @ EricCousineau-TRI @wieset @clalancette.
Хорошо, см. №320 и связанные PR для первого удара по этому. @wieset это также должно (косвенно) решить ваши проблемы. Эти изменения делают rcpputils::find_library_path
устаревшим (для использования в основных пакетах).
@hidmic Теперь, когда мы приземлились на №320 и друзья, можем ли мы закрыть это?
Действительно можем. Спасибо за шишку!
Большое спасибо @hidmic , я думаю, что это меня на полпути. RUNPATH
прежнему необходимо правильно заполнить. Я продолжу обсуждение с @clalancette в https://github.com/ros2/rcpputils/pull/44.
Самый полезный комментарий
Хм, я начинаю задумываться, зачем нам для начала
rcpputils::find_library_path()
. Если мы просто предоставимrcutils_load_shared_library()
или его оболочкуrcpputils::SharedLibrary
с относительным путем,dlopen
иLoadLibrary
будут искать пути и возвращать загруженные объектные файлы. Документация для обоих предполагает, что уже загруженные объектные файлы больше не будут извлечены. При этом по умолчанию будут учитываться RPATH, LD_LIBRARY_PATH, RUNPATH, PATH и предварительно загруженные библиотеки.CC @ EricCousineau-TRI @wieset @clalancette.