Determine a base directory of a colcon workspace

Hello all!

I’m now trying to gradually migrate our system from ROS1 to ROS2 and getting used to the colcon and many other ROS2 tools.
I realized that the colcon build command needs to be invoked on the specific directory (Given the following structure, we need to be at <base>)

├── src/
│   ├── package1/
│   └── package2/
├── build/
├── log/
└── install/

I thought it’s very useful if there is a way to find the <base> directory for making an extension to make colcon find it automatically.

I can somehow sense the concept of the “base” directory from the colcon-cd extension:

The extension leaves it up to the user to decide.

Do we have any way to find the <base> directory, or if it is not yet decided, I would propose determining it.


Great initiative!

In fact, I’ve found that production systems often would not use catkin/colcon tools but only cmake. I think it’s a good idea to tailor the default behaviour of CLI tools to the common folk :wink:

Do I understand correctly that you want to be able to build your packages from any directory? If yes then check out Colcon Build from Any Directory and Need to Re-build for changes in Launch file - ROS Answers: Open Source Q&A Forum

This has been a pain point for me as well. I went a slightly different route and implemented ros_command to be able to find the workspace root, enabling roscd and rosbuild from any directory.

With catkin the workspace base always contained the .catkin_tools directory, and using an upwards find function you could search for the <base> directory. A colcon workspace doesn’t have anything like that in the root directory. For my personal use I’ve used an empty dot file at the root as a point to search for ie <base>/.ws_root. Otherwise its hard to guarantee its the workspace base and avoid searching up through the entire filesystem. Admittedly seems a little silly to add as a required file in colcon, but thats what I’ve done.

You can define those src/build/install paths in a colcon configuration file. You can even juggle between different configurations files using the COLCON_DEFAULTS_FILE env var.


# /home/ubuntu/custom_colcon_config.yaml
        "": {"log-base": "/home/ubuntu/workspace/log"},
        "build": {
            "base-paths": "/home/ubuntu/workspace/my_cool_project/src"
            "build-base": "/home/ubuntu/workspace/bar/build",
            "install-base": "/home/ubuntu/workspace/global/install",
cd ~/
COLCON_DEFAULTS_FILE=/home/ubuntu/custom_colcon_config.yaml colcon build
1 Like

Hi, I did some work on an extension to make this possible a while back. It was a private repository while soliciting for design feedback, but I think this is a good time to get some general feedback and get the extension released.

Please have a look at this and let me know what you think: Initial implementation by cottsay · Pull Request #1 · colcon/colcon-top-level-workspace · GitHub

Thanks for the link!

Thank you for introducing such an exciting project! I’ll look into it.

And I want to propose the “official” way to define it so we don’t need to make another wrapper to handle it easily (these tools must not be hard to use.)

Thank you for the suggestion!
It works well if we have one workspace.
However, when we have to manage multiple underlying workspaces, it will be a hassle.
(Now we use ros1_bridge which requires at least three workspaces)

Thank you for sharing the repo! I’ll try it.
And I want to clarify here how I can determine the base directory.
Is there any specification of how to find the base directory?
I originally thought of using COLCON_PREFIX_PATH to find it, but it turned out that the environment variable is not always available.
As @trocks mentioned, on ROS1, the catkin_tools makes a designated directory .catkin_tools on the workspace root directory and utilizes it as a landmark.

Just for completeness, you do not have to follow the usual structure described above with the src, build and install folders contained in the same “base” folder. Colcon supports passing --build-base, --install-base and --base-paths to customize that layout. I have been using this extensively to reduce the friction for new developers, and remove the need for a “workspace layout” which is very familiar to experienced ROS developers, not so much to others. So I am kind of against making this layout an enforced convention and would like to keep the flexibility to put my build results wherever I’d like :slight_smile:

I think @Jeremie has the right answer for colcon currently, but that does require a lot of extra typing by the user, while catkin build by itself could be invoked anywhere in the workspace. As @haudren brings up, the top level of the colcon ws does not require any directory layout and shouldn’t need to (I don’t think catkin did either?).

So I think the question is should colcon include a “landmark” at the workspace root. And while I miss the functionality I think the answer might be no. There is no colcon init step to setup the workspace, it is unclear when the user would create the landmark. If it is optional then you have the possibility that every colcon build call will search up through your entire directory structure which is not desirable. This would require a non-trivial change to existing workspaces and the colcon workflow.

While I think the ability to call the build command from anywhere in the workspace without setting environment variables is desirable, it might need to be implemented by the user. Definitely a loss in functionality from catkin.

The extension I mentioned anchors off from the layout marker file created in the build space. It should work as desired with no additional configuration, given that the workspace was already established by invoking the first build at the top level.

The PR discussion touches on other possible heuristics for identifying the workspace root as well.

That is assuming that the build directory is above the current directory, otherwise the user needs to include a full path to the build directory. While I think 90% of the time the build directory is in the workspace root, that is not 100%. There are several things that HINT at which folder is the workspace root, but as far as I can tell nothing the necessarily defines that folder.

Specifying an absolute path to a build directory does disable the extension, however any relative path for the build directory set by a global defaults file or mixin should still work with the extension even if it isn’t below the top level workspace.

Specifying any value on the command line resolves the path from the invocation point and not the top level, so any --build-base argument on the command line would also disable discovery.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.