Gegenwärtig wird find_library
direkt in die Suche nach Bibliotheken entlang LD_LIBRARY_PATH
verschoben, anstatt zuerst geladene Bibliotheken abzufragen. Eine der 3 aktuellen Implementierungen:
https://github.com/ros2/rmw_implementation/blob/32c3de1/rmw_implementation/src/functions.cpp#L77
Es wäre schön, wenn dieser Code stattdessen aktuell geladene Bibliotheken bevorzugen würde, um Anwendungscode zu unterstützen, der nicht die Möglichkeit
Hier ist ein funktionierender Prototyp unter Linux:
https://github.com/EricCousineau-TRI/rcpputils/commit/b66a3d9e02ace44e6c3b6022eeb3447b121d3311
Cribbing von Drake Quelle:
https://github.com/RobotLocomotion/drake/blob/4c6246197/common/find_loaded_library.cc
Bei diesem Commit für dieses Bazel-Repro-Projekt kann ich jetzt entweder die RMW-Implementierung zum Zeitpunkt der Verknüpfung angeben oder auf Umgebungsvariablen zurückgreifen:
https://github.com/EricCousineau-TRI/repro/commit/cea11026722b340580257564dc49cb0f59b55178
@ dirk-thomas Ich würde das sehr nützlich finden. Kann ich fragen, welche (wenn überhaupt) Beweise Sie dazu veranlassen könnten, dies in Betracht zu ziehen? : D.
Kann ich fragen, welche (wenn überhaupt) Beweise Sie dazu veranlassen könnten, dies in Betracht zu ziehen?
Da das Ziel einer Distribution darin besteht, die Stabilität zu gewährleisten, dienen Backports nur zur Behebung von Fehlern. Verbesserungen sollten auf die nächste Distribution abzielen.
Die ersten Testpakete von Dashing sollen in der ersten Aprilwoche verfügbar sein.
Ja, hört sich gut an. Wartet auf die Zusammenführung von https://github.com/ros2/rcpputils/issues/3 und reicht dies dann gegen den Dev-Zweig ein. Vielen Dank!
Wir haben einen ros2-Knoten, für den Funktionen erforderlich sind, die über setcap
was dazu führt, dass LD_LIBRARY_PATH
während der Ausführung weggelassen wird. Also setzen wir RPATH
in der Binärdatei, um gemeinsam genutzte Bibliotheken zu finden. Da sich find_library_path
auf LD_LIBRARY_PATH
stützt, fällt der Knoten mit aus
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
Wenn ich das richtig verstehe, würde der Vorschlag von @ EricCousineau-TRI dieses Problem lösen. Gibt es eine Chance, diese Funktionalität in der nächsten Version zu erhalten? Oder Vorschläge für eine Problemumgehung?
@ EricCousineau-TRI planen Sie, dies zu wiederholen?
Wenn ich das richtig verstehe, würde der Vorschlag von @ EricCousineau-TRI dieses Problem lösen.
@wieset Wie würde es das Problem lösen, wenn die Bibliothek, die Sie suchen / laden möchten, noch nicht geladen ist?
@ivanpauno Wahrscheinlich nicht in naher Zukunft (~ 6 Monate bis 1 Jahr), leider :(
@ dirk-thomas Ich habe mir den Beispielcode von @ EricCousineau-TRI angesehen und Sie haben Recht, es würde mein Problem nicht lösen, wenn die Bibliothek nicht bereits geladen ist. Ich denke, ich könnte es beim Erstellen verknüpfen, damit es beim Programmstart geladen wird?
Um das Laden zur Laufzeit beizubehalten, werden jedoch zwei Optionen angezeigt: Entweder müsste nach RPATH
gesucht werden, die ich über CMAKE_INSTALL_RPATH
festlegen kann, oder es könnte eine andere Umgebungsvariable anstelle von LD_LIBRARY_PATH
, zB RMW_LIBRARY_PATH
. Ich habe beide Optionen in https://github.com/ros2/rcpputils/issues/40 erwähnt.
@wieset Das Anpassen Ihres Builds für die Verwendung von rpath für diesen Anwendungsfall klingt nach dem richtigen Weg.
@ dirk-thomas Einverstanden, und ich verwende bereits RPATH
, um alle anderen Bibliotheken zu laden. Aber das bringt mich nicht um die Tatsache herum, dass find_library_path()
für die rmw-Bibliothek derzeit nicht dort angezeigt wird. Oder fehlt mir etwas?
Aber das bringt mich nicht um die Tatsache herum, dass
find_library_path()
für die RTW-Bibliothek derzeit nicht dort angezeigt wird.
Du hast recht. Ich habe den Kontext auf diesem Ticket verpasst.
Ich frage mich, ob es sinnvoll ist, hierfür eine separate Umgebungsvariable einzuführen, oder ob Sie beim Ausführen von ausführbaren Dateien als Root nur sicherstellen sollten, dass die vorhandenen Umgebungsvariablen selbst explizit festgelegt werden.
Soweit ich weiß, wird LD_LIBRARY_PATH
für setcap
/ setuid
ausführbare Dateien vollständig ignoriert, daher würde es leider nicht helfen, sie selbst festzulegen. Siehe http://man7.org/linux/man-pages/man8/ld.so.8.html
Ich bin mir nicht sicher, ob die Einführung einer neuen Umgebung wie ROS_LIBRARY_PATH
zur Umgehung dieser Sicherheitsbeschränkung eine gute Idee ist. ld
würde das nur nicht filtern, weil es nichts davon weiß und LD_LIBRARY_PATH
aus Sicherheitsgründen ignoriert.
Bitte zögern Sie nicht, PRs vorzuschlagen, um diese Verbesserung hinzuzufügen (wie auf dem Etikett "Hilfe gesucht" angegeben).
Werde mich darum kümmern!
Erstellt eine Pull-Anfrage unter https://github.com/ros2/rcpputils/pull/44
FWIW @hidmic , @iantheengineer und ich Drake .
Hmm, ich frage mich, warum wir zuerst rcpputils::find_library_path()
brauchen. Wenn wir einfach rcutils_load_shared_library()
oder seinen rcpputils::SharedLibrary
Wrapper mit einem relativen Pfad versehen, suchen dlopen
und LoadLibrary
nach Pfaden und liefern geladene Objektdateien. Die Dokumentation für beide legt nahe, dass bereits geladene Objektdateien nicht erneut abgerufen werden. Auf diese Weise werden RPATHs, LD_LIBRARY_PATHs, RUNPATHs, PATHs und vorinstallierte Bibliotheken standardmäßig berücksichtigt.
CC @ EricCousineau-TRI @wieset @clalancette.
Okay, siehe # 320 und angeschlossene PRs für einen ersten Versuch. @wieset Dies sollte (indirekt) auch Ihre Probleme lösen. Diese Änderungen machen rcpputils::find_library_path
veraltet (zur Verwendung in Kernpaketen).
@hidmic Jetzt, wo wir # 320 und Freunde gelandet sind, können wir das schließen?
In der Tat können wir. Danke für die Beule!
Vielen Dank @hidmic , ich denke, das bringt mich auf halbem Weg dorthin. RUNPATH
noch richtig ausgefüllt werden. Ich werde die Diskussion mit @clalancette unter https://github.com/ros2/rcpputils/pull/44 fortsetzen.
Hilfreichster Kommentar
Hmm, ich frage mich, warum wir zuerst
rcpputils::find_library_path()
brauchen. Wenn wir einfachrcutils_load_shared_library()
oder seinenrcpputils::SharedLibrary
Wrapper mit einem relativen Pfad versehen, suchendlopen
undLoadLibrary
nach Pfaden und liefern geladene Objektdateien. Die Dokumentation für beide legt nahe, dass bereits geladene Objektdateien nicht erneut abgerufen werden. Auf diese Weise werden RPATHs, LD_LIBRARY_PATHs, RUNPATHs, PATHs und vorinstallierte Bibliotheken standardmäßig berücksichtigt.CC @ EricCousineau-TRI @wieset @clalancette.