# Revision history [back]

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