RobotWebTools / rclnodejs

Node.js version of ROS 2.0 client
https://docs.ros.org/en/humble/Concepts/Basic/About-Client-Libraries.html?highlight=rclnodejs#community-maintained
Apache License 2.0
319 stars 70 forks source link

Static build rclnodejs.node problem #718

Closed cwyark closed 3 years ago

cwyark commented 3 years ago

Has any one tried static build rclnodejs.node with ROS2 foxy ?
I'm trying to use rclnodejs with electron, but rclnodejs.node relies on librcl.so, librmw.so, and some ros2 core shared libraries. One approach is source /opt/ros/foxy/setup.bash every time when electron start, but personally I don't prefer this approach, because most electron application is a deliverable software, it supposed to double clicked to launch this app.

minggangw commented 3 years ago

Thanks for your question. I haven't tried to build rclnodejs.node as a static library because node loads C++ addon as a dynamically-linked shared library when require() is executed. Can appending source /opt/ros/foxy/setup.bash to your .bashrc meet your requirement? `

cwyark commented 3 years ago

Sorry , I missuse static build word. I'm trying to static link to ROS2 core, like librcl.a, librmw.a .. That say, I would like to write an electron application and use rclnodejs as it's dependency. But I don't want to rclnodejs.node dynamically link to librcl.so, librmw.so because this deliverable electron application is portable to other PC and doesn't need to install ROS2 on other PC.

minggangw commented 3 years ago

Currently, rclnodejs itself loads rosidl_message_type_support_t/rosidl_service_type_support_t from .so library dynamatically, see https://github.com/RobotWebTools/rclnodejs/blob/d41f7e91510cd55ff672dad8f7f0be095ed8c00c/src/rcl_utilities.cpp#L57-L68 so you have to use dynamic libraries.

But I don't want to rclnodejs.node dynamically link to librcl.so, librmw.so because this deliverable electron application is portable to other PC and doesn't need to install ROS2 on other PC.

I'm not sure whether it's feasible to do so, it sounds you want to link all ROS2 into rclnodejs.node statically if I understand right. I found the following threads for your reference:

koonpeng commented 3 years ago

Due to ROS2's design, it is very hard to link everything statically, the biggest problem is the middleware layer and typesupport libraries, as @minggangw mentioned, the typesupport for each message is loaded dynamically because we cannot know ahead of time which messages are installed in the system (and also which middleware is used).

In theory you could achieve "one click" launch by adding a level of indirection, i.e. have a script that scans for installed ros location, source it and launch your electron app.

minggangw commented 3 years ago

If we don't have more discussion here, I will close this issue. Please reopen it if you still have problems, thanks!

anmilleriii commented 3 years ago

@cwyark I have a similar requirement to you where I would like to maintain the production release capability enabled by Electron's autoUpdater, if possible without the additional liability/complexity of an external script that the end-user may need to update as well.

While ideally static ROS2 could be bundled in this Electron application I understand that to be inaccessible.

So, assuming the end-user's environment has ROS2 installed, I was curious if you went down the path of using source /opt/ros/foxy/setup.bash or instead had made headway with a static version of rclnodejs.

Also, in either scenario did you get rclnodejs working beyond an Electron development server and into a bundled distributable executable?

Thanks in advance.

anmilleriii commented 2 years ago

As distributing rclnodejs in a bundle was a hard requirement for my use case, I spent the time to develop a workaround and have compiled it in this example repository for posterity.

After evaluating the alternatives discussed here (including building rclnodejs statically or using a launch file), I wrote a launch file (similar to sourcing from ~/.bashsrc as suggested by @minggangw).

This is not an ideal solution in production, since it requires the distribution of 2 files (the Electron executable, and the launch executable). This introduces challenges in automatically updating the entire distributed code (i.e., the Electron app is auto-updatable but the launch file is not).

Nonetheless, a well-designed distribution strategy (e.g., through a tar and some good instructions on how to launch to the end-user) should generally be sufficient.