Skip to content
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

Static build rclnodejs.node problem #718

Closed
cwyark opened this issue Nov 6, 2020 · 7 comments
Closed

Static build rclnodejs.node problem #718

cwyark opened this issue Nov 6, 2020 · 7 comments

Comments

@cwyark
Copy link

cwyark commented Nov 6, 2020

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
Copy link
Member

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
Copy link
Author

cwyark commented Nov 9, 2020

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
Copy link
Member

Currently, rclnodejs itself loads rosidl_message_type_support_t/rosidl_service_type_support_t from .so library dynamatically, see

const rosidl_message_type_support_t* GetMessageTypeSupport(
const std::string& package_name, const std::string& sub_folder,
const std::string& msg_name) {
void* function = GetTypeSupportFunctionByInterfaceSymbolName(
"rosidl_typesupport_c__get_message_type_support_handle__" + package_name +
"__" + sub_folder + "__" + msg_name,
lib_prefix + package_name + "__rosidl_typesupport_c" + lib_ext);
if (function)
return reinterpret_cast<GetMessageTypeSupportFunction>(function)();
else
return nullptr;
}

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
Copy link
Collaborator

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
Copy link
Member

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

@anmilleriii
Copy link

anmilleriii commented Aug 4, 2021

@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
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants