Why ros2 run executables are installed in "lib/{PROJECT_NAME}"
Hi. I would like to query you about a simple annoyance I have had with debugging "No executable with this name" from ros2 run. By current design, executables are forced to be installed in "workspace/install/projectname/lib/projectname", whilst actual libraries from this package reside directly in "/project_name/lib". Sending them to "/project_name/bin", like one might expect, is unacceptable...
Is there a concrete reason for this project_name doubling? (ros2pkg is forcing this dir structure)
Asked by ROSignol on 2020-09-09 22:44:07 UTC
Answers
By current design, executables are forced to be installed in "workspace/install/project_name/lib/project_name"
There are two things going on.
First, this looks like an isolated workspace. Isolated workspaces are a feature of colcon
, and they're the default because they help catch undeclared dependencies. The first project name install/project_name
is just where colcon asked the package to be installed to when it invoke CMake. It's also possible to build a merged install workspace, which would result in workspace/install/lib/project_name
. What's really going on here is <install_prefix>/lib/project_name
.
Second, you may be asking why lib/project_name
instead of bin
?
Sending them to "/project_name/bin", like one might expect, is unacceptable..
I'm reading this as Sending them to "<install_prefix>/bin", like one might expect, is unacceptable..
. You can install executables to bin
, and that would make them globally available. Instead of typing ros2 run <package> <executable>
you could type <executable>
. Some tools do this, like RViz. Type rviz2
after sourcing /opt/ros/foxy/setup.bash
. The downside of making executables globally available is there will be a conflict when two packages make an executable with the same name.
Why does ros2 run
not invoke executables in <install_prefix>/bin
? Say someone ran ros2 run baz foobar
. How would it know the executable /opt/ros/foxy/bin/foobar
was provided by package baz
? To solve this ros2 run
looks in <install_prefix>/lib/package_name
, which is a standard spot. See /usr/libexec
in https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf .
/usr/libexec includes internal binaries that are not intended to be executed directly by users or shellscripts. Applications may use a single subdirectory under /usr/libexec
So applications can put executables not intended to be executed directly into /usr/libexec/package_name
, and ...
Some previous versions of this document did not support /usr/libexec, despite it beingstandard practice in a number of environments. 6 To accomodate this restriction, it became common practice to use /usr/lib instead. Either practice is now acceptable, but each application must choose one way or the other to organize itself
.. /usr/lib/package_name
is acceptable for this purpose too. Executables meant to be used with ros2 run
are executed by ros2 run
, so they're not executed directly by the user.
You might also be interested in the lib/<ros-package-name>
section of REP 122
Asked by sloretz on 2020-09-11 14:18:48 UTC
Comments
Thanks for this great summary, I've wondered about this since transitioning to ros2 after starting with ros1 from kinetic. Also nice to read REP 122 providing some background info on the layout.
Asked by Mbuijs on 2020-09-21 06:59:15 UTC
Comments