ros_logo ROS

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

Conan provides integration for your Robot Operating System (ROS) C/C++ based projects. This will allow you to consume Conan packages inside your ROS package projects. The Conan packages can be installed and used in CMake with the help of the ROSEnv generator created for the purpose.

It provides a clean integration that requires no Conan-specific modifications in your CMakeLists.txt.

Important

This integration supports ROS2, it has been developed using its Humble version and the aim is to support newer versions going forward. If you have any issues with other ROS versions, please let us know by opening an issue in our GitHub repository.

Note

Pre-requisites to run the example:

  1. In order to run the example, it is expected that you have an Ubuntu environment (22.04 LTS preferred) with ROS2 Humble version installed. For convenience, you can also use this Docker File instead:

    1. FROM osrf/ros:humble-desktop
    2. RUN apt-get update && apt-get install -y \
    3. curl \
    4. python3-pip \
    5. git \
    6. ros-humble-nav2-msgs \
    7. && rm -rf /var/lib/apt/lists/*
    8. RUN pip3 install --upgrade pip && pip3 install conan==2.*
    9. RUN conan profile detect
    10. CMD ["bash"]

Simply copy the Dockerfile, build your image with docker build -t conanio/ros-humble ., and finally run it with docker run -it conanio/ros-humble.

  1. The files for this example can be found at our examples repository. Clone it like so to get started:

    1. $ git clone https://github.com/conan-io/examples2.git
    2. $ cd examples2/examples/tools/ros/rosenv

Consuming Conan packages using the ROSEnv generator

Imagine we have a ROS C++ package called str_printer that uses some functionality from the third party string formatting library fmt to print fancy strings.

We have the following project structure:

  1. $ tree /f
  2. workspace
  3. ├───str_printer
  4. CMakeLists.txt
  5. conanfile.txt
  6. package.xml
  7. ├───include
  8. └──str_printer
  9. str_printer.h
  10. └───src
  11. str_printer.cpp
  12. └───consumer
  13. CMakeLists.txt
  14. package.xml
  15. └───src
  16. main.cpp

Where:

  • The str_printer is a ROS package that implements a function and depends on the fmt Conan package.

  • The consumer is also a ROS package that depends on the str_printer ROS package and uses its functionality in a final executable.

The only difference in the str_printer package with respect to a normal ROS package is that it includes a conanfile.txt file. This is the file used by Conan to install the required dependencies and generate the files needed to perform the build.

str_printer/conanfile.txt

  1. [requires]
  2. fmt/11.0.2
  3. [generators]
  4. CMakeDeps
  5. CMakeToolchain
  6. ROSEnv

In this case, we will install the 11.0.2 version of fmt and Conan will generate files for CMake and ROS so we can build the str_printer package later.

To install the fmt library using Conan we should do the following:

  1. $ cd workspace
  2. $ conan install str_printer/conanfile.txt --build missing --output-folder install/conan
  3. ======== Computing dependency graph ========
  4. fmt/11.0.2: Not found in local cache, looking in remotes...
  5. fmt/11.0.2: Checking remote: conancenter
  6. fmt/11.0.2: Downloaded recipe revision 5c7438ef4d5d69ab106a41e460ce11f3
  7. Graph root
  8. conanfile.txt: /home/user/examples2/examples/tools/ros/rosenv/workspace/str_printer/conanfile.txt
  9. Requirements
  10. fmt/11.0.2#5c7438ef4d5d69ab106a41e460ce11f3 - Downloaded (conancenter)
  11. ======== Computing necessary packages ========
  12. Requirements
  13. fmt/11.0.2#5c7438ef4d5d69ab106a41e460ce11f3:29da3f322a17cc9826b294a7ab191c2f298a9f49#d8d27fde7061f89f7992c671d98ead71 - Download (conancenter)
  14. ======== Installing packages ========
  15. -------- Downloading 1 package --------
  16. fmt/11.0.2: Retrieving package 29da3f322a17cc9826b294a7ab191c2f298a9f49 from remote 'conancenter'
  17. fmt/11.0.2: Package installed 29da3f322a17cc9826b294a7ab191c2f298a9f49
  18. fmt/11.0.2: Downloaded package revision d8d27fde7061f89f7992c671d98ead71
  19. ======== Finalizing install (deploy, generators) ========
  20. conanfile.txt: Writing generators to /home/user/examples2/examples/tools/ros/rosenv/workspace/install/conan
  21. conanfile.txt: Generator 'CMakeDeps' calling 'generate()'
  22. conanfile.txt: CMakeDeps necessary find_package() and targets for your CMakeLists.txt
  23. find_package(fmt)
  24. target_link_libraries(... fmt::fmt)
  25. conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'
  26. conanfile.txt: CMakeToolchain generated: conan_toolchain.cmake
  27. conanfile.txt: Preset 'conan-release' added to CMakePresets.json. Invoke it manually using 'cmake --preset conan-release' if using CMake>=3.23
  28. conanfile.txt: If your CMake version is not compatible with CMakePresets (<3.23) call cmake like: 'cmake <path> -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/danimtb/examples2/examples/tools/ros/rosenv/workspace/install/conan/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release'
  29. conanfile.txt: CMakeToolchain generated: CMakePresets.json
  30. conanfile.txt: CMakeToolchain generated: ../../str_printer/CMakeUserPresets.json
  31. conanfile.txt: Generator 'ROSEnv' calling 'generate()'
  32. conanfile.txt: Generated ROSEnv Conan file: conanrosenv.sh
  33. Use 'source /home/user/examples2/examples/tools/ros/rosenv/workspace/install/conan/conanrosenv.sh' to set the ROSEnv Conan before 'colcon build'
  34. conanfile.txt: Generating aggregated env files
  35. conanfile.txt: Generated aggregated env files: ['conanrosenv.sh']
  36. Install finished successfully

This will download the fmt Conan package to the local cache and generate the CMake and ROS environment files in the conan subfolder of the install directory.

Now we can source our ROS environment, then source the Conan ROSEnv environment, so the conan-installed package are found by CMake, and then we can build the str_printer package as usual with Colcon.

  1. $ source /opt/ros/humble/setup.bash
  2. $ source install/conan/conanrosenv.sh
  3. $ colcon build --packages-select str_printer
  4. Starting >>> str_printer
  5. Finished <<< str_printer [10.8s]
  6. Summary: 1 package finished [12.4s]

Bridging the Conan-provided transitive dependencies to another ROS package

As the consumer ROS package depends on str_printer, the targets of transitive dependencies should be exported. This is done as usual in the str_printers’s CMakeLists.txt using ament_export_dependencies():

str_printer/CMakeLists.txt

  1. cmake_minimum_required(VERSION 3.8)
  2. project(str_printer)
  3. if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  4. add_compile_options(-Wall -Wextra -Wpedantic)
  5. endif()
  6. # find dependencies
  7. find_package(ament_cmake REQUIRED)
  8. find_package(fmt REQUIRED) # Retrieved with Conan C/C++ Package Manager
  9. add_library(str_printer src/str_printer.cpp)
  10. target_include_directories(str_printer PUBLIC
  11. $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/str_printer>
  12. $<INSTALL_INTERFACE:include>)
  13. target_compile_features(str_printer PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
  14. ament_target_dependencies(str_printer fmt)
  15. ament_export_targets(str_printerTargets HAS_LIBRARY_TARGET)
  16. ament_export_dependencies(fmt)
  17. install(
  18. DIRECTORY include/
  19. DESTINATION include
  20. )
  21. install(
  22. TARGETS str_printer
  23. EXPORT str_printerTargets
  24. LIBRARY DESTINATION lib
  25. ARCHIVE DESTINATION lib
  26. RUNTIME DESTINATION bin
  27. INCLUDES DESTINATION include
  28. )
  29. ament_package()

To build the consumer ROS package, you can proceed as usual (make sure that you have both the ROS environment and the Conan ROSEnv environment sourced before building as in previous step):

  1. $ colcon build --packages-select consumer
  2. Starting >>> consumer
  3. Finished <<< consumer [7.9s]
  4. Summary: 1 package finished [9.4s]

And after this, our consumer application should be ready to run with just:

  1. $ source install/setup.bash
  2. $ ros2 run consumer main
  3. Hi there! I am using fmt library fetched with Conan C/C++ Package Manager

See also