Migrating ROS/ROS2 off of catkin/colcon (towards pure CMake)

The OP of @actinium226 brought up some interesting points, but the later comments seem to go more into the direction of “we need better documentation” and “my use-case/preferred use of a build tool isn’t sufficiently being covered by catkin_make/catkin_tools/colcon”. Those are valid concerns, but the thread started with “how about doing all of this with pure CMake?” and I’d like to hear more about that part specifically.

Over the years there have been quite a few comments about “why a custom build system/tool?”. I expect @dirk-thomas may have some comments on the rationale for Colcon fi, but as @christophebedard mentioned, some of it has to do with managing sets of packages with (inter)dependencies (and their dependencies, and their dependencies, and so on).

@actinium226: could you comment on how you’d approach this with pure CMake projects? Especially also with multiple different types of projects and many of which may not use CMake or a language that needs to be compiled or needs special setup of the (build) environment for other projects to be able to find them?

This is a strong statement which I doubt is true (Python nodes don’t need to be Catkin / ROS packages at all fi). The most you could say (and based on my understanding) is that the build tools we have work in a certain way because ROS uses a package based approach to distribution of code. Not the other way around.

I’m not sure it was completely intentional, but freedom-from-choice is a very valuable thing for many users. Especially those not up-to-speed on how build tools work but “just want their packages built”.

This invariably means that more advanced (or involved) use-cases are going to be slightly less supported (or somewhat more involved to get working), but it doesn’t mean that everything is horrible. Just that different choices were made.

Being able to “choose whether or not they want to deal with those issues and accept the tradeoff in order to have a single context build that can more easily integrate with various tools” is valuable, but it would also mean the (average?) user would have to know when to make that choice, which is not apparent and would make it even harder to get started.

I would also add that you have to remember that quite a bit of what you might see as duplication or unnecessary has only become unnecessary because modern CMake started doing many of the same things over the past few years (exporting target dependencies, interface only libraries, transitive dependency resolution, federated builds, etc).

Admittedly I’m very familiar with the way Catkin & Colcon work (so I’m biased), but really, this (ie: the emphasised part) is one of the things I like about the tools we use. It’s very, very frustrating to deal with projects that don’t use something similar and require me to follow 18+ steps in a readme with every step running autotools, cmake, ninja or other tools manually (and 18+ points at which I could make a mistake, something doesn’t work, or I used an incorrect or unexpected way of specifying flags, build options or other configuration).

True, but it would also complicate quite a few other use-cases (if not done carefully), many of which are part of the core development workflow of many of us, such as building packages from others without having to deal with their dependencies, not having to care about which package(s) to build first, etc. Granted, this is not all perfect, but I would not like to start doing that manually again.

This reads as if you have a particular target audience in mind for which this would be true. Could you elaborate?

Personally, for a few of my target audiences (students fi), it’s been a blessing to be able to summarise the entire build process as:

First, run rosdep install -y --from-paths /path/to/your/catkin_ws --ignore-src and then run catkin build in the root of the workspace and wait for it to finish

instead of:

For every project, please mkdir build, then cd build, then cmake ... Do not run this in the src directory (or wherever the project stores its source files). Solve any problems it notifies you of, then run make and then make install. Be sure to specify a suitable DESTDIR and/or other way of specifying where the installable artefacts should go, and please make sure to not try and run sudo make install. Also please do not do any of this for non-CMake projects (which don’t have CMakeLists.txt). Use the regular python setup.py install for Python (add --user for a non-system-wide install, you should know when you’d want that). If you are trying to build a Java based package, then do whatever you’d do with those. For other languages / build systems: please follow the readme, but make sure to maintain a sane build environment at all times.

And above all, please make sure you figure out the proper build order across all packages (both your own and those you downloaded earlier from others), and make sure to have all dependencies installed first.

This is of course exaggerated but helps get the point across.

In my experience, one of the best ways of seeing these suggestions implemented would be to show that they work. Show an example CMake-only build of a workspace with a representative set of packages (ie: containing .msg, .srv (or ROS 2 .idl), multiple different languages, specific environment setup hooks, etc). Show how you’d deal with dependency management and how you’d support the federated workflow.

I’m not saying “you get something for free so you cannot complain”, but with the community as it is right now, code is king and is how you get things changed.

3 Likes