Question: Whats the best practice to include generated ros messages/services in code outside catkin workplace, in CMakeLists.txt?
Context: So in the current project I've started working on, the build system is based on CMake but some of the codes/executable's uses ROS. I've decided to follow the same pattern, and create most of the executables outside ROS catkin workplace. Now due to some new requirement I needed to create my own ROS message/services, and have added those as packages in the catkin workplace, and generate them using catkin_make. The directory tree is as below
root
|-CMakeLists.txt
|-src
|-|--myExecutable.cpp
|-catkin_ws
|--|--src
|--|--|--myPackage
|--|--|---|--srv
|--|--|---|--msg
|--|--|---|--package.xml
|--|--|---|--CMakeLists.txt
|-otherLibraries
|--|--CMakeLists.txt
Now, for my own usage I just run catkin_make
once to generate the header files for msg/srv and source catkin_ws/devel/setup.bash
(actually added to my ~/.bashrc
) for building the project, with the top CMakeLists.txt. In the top CMakeLists.txt I have find_package(myPackage)
and this works fine for my usage, myExecutable.cpp
which uses the message/service defined in myPackage
and libraries made by others in otherLibraries
compiles and run just fine.
Now another member of the project which uses Visual Studio Code complained that find_package(myPackage)
gives error on his IDE CMake tools. I know that this is caused by source catkin_ws/devel/setup.bash
not being run on the IDE.
My CMake knowledge is a patchwork at best, but I know that people in the project prefer Modern CMake and I'm not sure whats the best practice to solve this. (Should I run the setup.bash
script inside the top CMakeLists.txt? Should I manually add the location of the generated header/lib using set()
?)
I have had a similar case where I was using some C++ libraries independent of ROS and then I had the need to use ROS.
What I ended-up doing was to create a catkin package in my catkin_ws
for my software and alter the CMakeLists.txt
for the non-ROS needs. This way I am using catkin_make
to build the entire project including ROS-related stuff and non-ROS related stuff. In fact, the case I am talking about is open-source here, you can have a look.
You can then let your IDE know where to look and it should pick up everything. Personally, I opened my catkin package in CLion IDE and CLion picked-up everything. I was able to build, compile, run and debug within the same IDE without a hassle, it really is a great setup for my needs (bridging ROS and non-ROS code, fully functional IDE with debugging tools!).
The icing on the cake is that I did all the above within a Singularity container. Having all these in a single singularity container is very portable and shareable. You take/share the Singularity recipe or even a pre-built Singularity image, anyone can use it on their computer and have the exact same configuration as yours! We have an example of such Singularity configuration on GitHub here to provide a fully functional and contained UR5 controller for OpenRAVE.