Closed Ryanf55 closed 1 year ago
For better or worse, this is by choice and by design.
First, let me address the use of the lib
directory. In all reality, according to FHS that should be libexec
; we made a mistake when we originally did this work, and we've never fixed it (it would also probably be somewhat painful to fix). So even though I'll say lib
below to match what is there, conceptually it should be libexec
.
Second, we made these decisions back in 2017 or 2018 on where to store the binaries. So my memory is somewhat fuzzy. But as I recall, there is a very major reason for our current setup:
Because ROS 2 is highly federated, it is very possible (and maybe even common) for multiple packages to create the exact same named binary. In our current lib
setup, this works fine; binaries are effectively namespaced by their package name.
If we were to put them all in bin
, then we could easily run into collisions. In an isolated build (the default when building from source on Linux or macOS), this wouldn't matter; every package would install them to install/<pkgname>/bin
directory, and they would avoid each other. Unfortunately, that would not be the case for merged installs (which we use on Windows), nor on our debian packages (where all packages are installed to /opt/ros/<distroname>
.
@ros2/team that's my (5 year old) recollection of why we made this decision; is there anything else I'm missing?
In order to make any changes here, we'd have to come up with an alternative way to avoid that particular problem.
I'd be happy to entertain the idea of installing runtime program binaries (nodes) to libexec
and using defaults for the rest of the install
command. I have a working patch to ros2cli that allows it to find and run nodes placed in libexec/PACKAGE_NAME
without any behavioral change to other packages that are currently using bin
.
This could be more clear to developers writing the CMake code than the current method.
that's my (5 year old) recollection of why we made this decision; is there anything else I'm missing?
I remember the same thing.
According to the GNU directory standard: The directory for installing executable programs that users can run. This should normally be /usr/local/bin. ROS does not look here for nodes.
IIRC part of the discussion was a decision that the executables aren't meant to be run directly by the user. They are meant to be run by another program like ros2 run ...
or ros2 launch ...
.
First, let me address the use of the lib directory. In all reality, according to FHS that should be libexec;
It looks like both are allowed:
Some previous versions of this document did not support /usr/libexec, despite it being standard practice in a number of environments. [[26]](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html#ftn.idm236091914528) 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.
I'd be happy to entertain the idea of installing runtime program binaries (nodes) to
libexec
and using defaults for the rest of theinstall
command
We can't exactly do that, anyway. Due to another problem with overlays, we also need to install headers to include/<pkgname>/<pkgname>
: see https://github.com/ros2/ros2/issues/1150 .
Fair enough. What about constraining any changes to allow installing nodes in libexec/PACKAGE_NAME
.
Fair enough. What about constraining any changes to allow installing nodes in
libexec/PACKAGE_NAME
.
Given what @sloretz posted above, I'm not really inclined to make the change at this time. That is, it doesn't seem any more "correct" than lib
and would result in a bunch of churn.
It also doesn't help the ament_cmake docs tell you to install your nodes in the wrong path.
It says to set the runtime destination for binaries to lib
instead of lib/${PROJECT_NAME}
, meanwhile the ROS tutorial's ros2 pkg create --build-type ament_cmake --node-name my_node my_package
CLI generates the following from the example.
install(TARGETS my_node
DESTINATION lib/${PROJECT_NAME})
Turtlesim, used in the tutorials, has this code, where it install the targets directly instead of using the export set.
install(TARGETS turtlesim_node turtle_teleop_key draw_square mimic
DESTINATION lib/${PROJECT_NAME})
It also doesn't help the ament_cmake docs tell you to install your nodes in the wrong path.
Oof, yeah, good call. That should really be corrected; I'll open a PR to do that.
Turtlesim, used in the tutorials, has this code, where it install the targets directly instead of using the export set.
Can you explain more about what you think the problem there is? As far as I can tell that is installing things like we expect.
I can do the work, no worries. I'll tag you when it's fixed, there's much cleaner ways such as using an export set to do the install.
The following recommendations for includes in colcon
are not obeyed in the ament_cmake
tutorial.
https://colcon.readthedocs.io/en/released/user/overriding-packages.html#install-headers-to-a-unique-include-directory
Bug report
Required Info:
ros-humble-ros2cli/jammy,now 0.18.7-1jammy.20230721.205747 amd64
Steps to reproduce issue
Create a ROS package, and perform the install like so using modern CMake with GNUInstallDirs
Expected behavior
A call to
ros2 executables list PROJECT_NAME
should show PROJECT_NAME_node above which resides ininstall/PROJECT_NAME/bin/PROJECT_NAME_node
Actual behavior
A call to
ros2 executables list PROJECT_NAME
does not show a nodeAdditional information
According to the GNU directory standard:
The directory for installing executable programs that users can run. This should normally be /usr/local/bin
. ROS does not look here for nodes.My ROS answers post from a while ago
CMake GnuInstallDirs Deep CMake for library authors slide 107
The actual cause for
ros2 pkg executables
is here: https://github.com/ros2/ros2cli/blob/4523cc5a1a8bb6800dafa62f9f6379023ea7ede3/ros2pkg/ros2pkg/api/__init__.py#L44 The cause for people using the wrong directory isros2 pkg create
also puts them in the wrong place: https://github.com/ros2/ros2cli/blob/4523cc5a1a8bb6800dafa62f9f6379023ea7ede3/ros2pkg/ros2pkg/resource/cmake/CMakeLists.txt.em#L90 Here is the relevant screenshot from docs: