How to build and include a 3rd party library in a ROS2 package?
I have source code for a library (and test application) which I have written. I configure and compile it fine as a standalone application.
Now I would like to reference the library portion of it from a ros2 node that looks surprisingly similar to the publisher_member_function.cpp
node documented here.
I suppose I could build my library manually, install it in the file system on my development host, and then add that as a dependency to the publisher node project... maybe I would need to invent a mylibConfig.cmake
file, but there has got to be a better way than doing that.
I would prefer to check out my code into the src
directory in my workspace, perhaps create a package.xml
file for it, update CMakeLists.txt
for the cpp_pubsub
package, and have colcon make everything work like magic for me.
Is there a tutorial somewhere that explains how to do this? I can't seem to figure out the best keywords to plug into Google to find it myself, so I figured I would just ask.
Complicating matters somewhat... my library depends on somebody else's library (which probably, in turn, depends on one or more -dev
packages installed on my build machine). I'm hoping that if I can figure out how to manage this custom dependency thing once, then I can make it apply recursively... but if there are any gotchas I should be aware of for this sort of dependency chain, it sure would be nice if I could learn that sooner rather than later.
Basically, I think I'm asking how to modify the CMakeLists.txt
file and/or packages.xml
file in the cpp_pubsub
example to reference code in a directory parallel to the cpp_pubsub
directory, and probably, what requirements, (such as the presence and contents of a package.xml
file) are imposed on the project maintained in that parallel directory.
Answering some of my question...
I was able to build the 3rd party library by putting it (sdbus-cpp) into its own directory adjacent to the cpp_pubsub
directory and creating a package.xml
file that looked like this:
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>sdbus-cpp</name>
<version>0.0.0</version>
<description>sdbus-c++</description>
<maintainer email="fill@in.later>wpd</maintainer>
<license>Double Check This</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>libsystemd-dev</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
With this in place, I could run
$ rosdep install -i --from-path src --rosdistro foxy -y
and install the libsystemd-dev
dependency. Then I was able to run:
$ colcon install --packages-select sdbus-cpp
and build sdbus-cpp
. Yay. Now I'm working on creating the package.xml
file for my own library (which depends on sdbus-cpp
), following the same procedure. That basically worked, except that I don't have the machinery in place to create and install the .cmake
file(s) necessary to reference my library from ...
If you create a ament-cmake package using the
ros2 pkg create
command, it will create the basic skeleton of these things for you. You can then merge in your existing CMake configuration to suit and you should build packages findable by ROS2 ament-cmake packages.This may be personal, but according to what I believe is best practice, you would not try to build and install system dependencies (which your library appears to be) in a Catkin/Colcon workspace. ROS 2 has not changed that.
Colcon (and actually
catkin_tools
as well) have made it slightly easier to build non-ROS packages in ROS workspaces, so it can be done (as you found out), but it will require your 3rdparty project to use a supported build system (ie: CMake,setuptools
, etc). The only thing Colcon then does is invoke those for you -- nothing more.