How to Add Custom Libraries to a ROS 2 C++ Package
Learn to add custom libraries to your ROS 2 C++ packages. Enhance your robotics projects with reusable code and streamline your development process!

Share :
Quick answer
Learn to add custom libraries to your ROS 2 C++ packages. Enhance your robotics projects with reusable code and streamline your development process!
Quick Answer
Learn to add custom libraries to your ROS 2 C++ packages. Enhance your robotics projects with reusable code and streamline your development process!
Who This Is For
- ROS 2 Learner
- Mobile Robotics Student
- Robotics Career Shifter
What You Will Learn
What Nav2 means in practical robotics.
How this topic connects to real robot projects.
What to learn or build next after this article.
Introduction
When developing projects in robotics, the need for additional features often arises, such as advanced motion planning or sensor fusion techniques. Implementing these functionalities from scratch can be time-consuming. In such cases, leveraging existing libraries that offer these features can significantly accelerate development. For example, in the domain of mobile robotics, utilizing libraries for path planning or simultaneous localization and mapping (SLAM) can greatly enhance the capabilities of autonomous robots. This article aims to clarify concepts around incorporating external libraries into ROS 2 C++ packages, facilitating faster development and expanding the capabilities of robotic applications.
Starting Point
No understanding of
- ROS 2 C++ libraries and components
- ROS 2 C++ Package Structure
- Creating custom libraries
Learning outcomes
Easily able to
- Creating Custom Modules into ROS 2 Packages
- Install External Libraries to your ROS 2 Packages
- Concept clearning of Python Package, Library and module
Understanding C++ Terminologies
You can find our very useful open source C++-based libraries, but to utilize them in your projects, you need to understand that C++ requires the step of getting compiled to run it. For that, we need to have a system like CmakeLists.txt to compile and produce an executable that we can run. Lets first understand difference between a library and simple code inclusion.
C++ Included Code
Including a C++ source file (#include "my_functions.cpp") directly into another fileis more like copying and pastingthe contents of that file. It's not a standard way to distribute reusable code and this is not a library.
// my_functions.cpp
#include <iostream>
void sayHello() {
std::cout << "Hello, Robotisim!" << std::endl;
}
// main.cpp
#include "my_functions.cpp"
int main() {
sayHello();
return 0;
}

C++** Libraries**
A library is aprecompiled set of functions and codethat can be reused by other programs. It is typically distributed as a binary file (**libexample.a** for static libraries or **libexample.so** for dynamic/shared libraries) that can be linked to an executable.
Lets understand through a popular example
- Header only library but no compiled .a or .so file
- In this example, **
#include <iostream>**includes theiostreamheader file, which provides functionality for input and output operations
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
Creating Custom C++ Library
Lets look at an example of static library creation , to build our understanding about the process and get rid of copy pasting of source codes.
Header File
#ifndef BOT_MOVE_H
#define BOT_MOVE_H
enum DIR { FORWARD, BACKWARD};
bool botMove(DIR direction);
void botStop();
#endif
Source File
#include "bot_move.h"
bool botMove(Dir direction)
{std::cout << "Moving robot";
return true;}
void botStop() {
std::cout << "Stop";}
Compile Library
g++ -c bot_move.cpp
ar rcs libbot_move.a bot_move.o
Library Files Understanding
After compiling, you will obtain a static library file**libbot_move.a**that contains the compiled code for the botMove and botStop functions.
This library can be linked to other programs that need to control a robot's movement.
Utilising our custom Library
Once these library files are created then you can utilize them or link them into your C++ ROS 2 Code
Main Code
#include "bot_move.h"
int main() {
moveRobot(FORWARD); // Move the robot forward at speed 50
stopRobot(); // Stop the robot
return 0;
}
This code is inlcuding the header file but when we will compile we will mention that do not take definitions of header files from .cpp instead take from .a compile library
Linking Command
g++ main.cpp -L. -lbot_move -o robot_movement
Explanation
main.cppis your main C++ file that uses the functions from thebot_movelibrary.**-L**.tells the compiler to look for libraries in the current directory.**-lbot_move**specifies the name of the library to link**(libbot_move.a).****-o robot_movement**specifies the output executable name.
ROS 2 C++ Package Strucutre
When we create a python package using ROS 2 command, we have couple of things to understand
**ros2 pkg create**: This is the command used to create a new ROS 2 package.**--build-type ament_cmake**: This option specifies the build system to use for the package. In this case,ament_cmakeis selected.**--node-name sensor_fusion_node**: This option specifies that a node named**sensor_fusion_pkg**: This is the name of the package that will be created.
ros2 pkg create --build-type ament_cmake --node-name sensor_fusion_node sensor_fusion_pkg
When we execute this command, we see a package with a node automatically created with a fixed structure. This below structure is produced mainly for keeping standards fixed for compatibility between tools and ease of maintenance. Lets look at its structure and important files
Node
**sensor_fusion_pkg**/
|-- include/
| `-- sensor_fusion_pkg/
| `-- sensor_fusion_node.hpp
|-- src/
| |-- sensor_fusion_node.cpp
| `-- CMakeLists.txt
|-- CMakeLists.txt
|-- package.xml
`-- README.md
Node
#include <rclcpp>
#include libraries
class Node{
publishers.create();
subscriber.create();
}
void main (){
Node.spin();
}
CmakeLists.txt
include_directories(include)
add_executable(sensor_fusion_node src/sensor_fusion_node.cpp)
ament_target_dependencies(sensor_fusion_node rclcpp)
Including OpenCV and Eigen Library into ROS 2 C++ Package
Lets bring in some popular libraries to be included into our ROS 2 C++ node afterinstallation , just to understand the process.
sensor_fusion_node.cpp
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include <opencv2/core.hpp>
#include <Eigen/Dense>
class SensorFusion : public rclcpp::Node
{
public:
SensorFusion()
: Node("sensor_fusion_node")
{
// Use OpenCV
cv::Mat image(100, 100, CV_8UC3, cv::Scalar(0, 255, 0));
cv::imshow("Image", image);
cv::waitKey(0);
// Use Eigen
Eigen::MatrixXd matrix(3, 3);
matrix << 1, 2, 3, 4, 5, 6, 7, 8, 9;
std::cout << "Eigen Matrix:\n" << matrix << std::endl;
}
};
int main(int argc, char*argv [])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<SensorFusion>();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
CmakeList.txt
cmake_minimum_required(VERSION 3.5)
project(**sensor_fusion_pkg**)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
# Find OpenCV package
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
# Find Eigen package
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# Create an executable
add_executable(SensorFusion_node src/SensorFusion.cpp)
# Link the OpenCV and Eigen libraries
target_link_libraries(SensorFusion_node ${OpenCV_LIBRARIES} ${EIGEN3_LIBRARIES})
ament_target_dependencies(my_node rclcpp std_msgs)
# Install the executable
install(TARGETS my_node
DESTINATION lib/${PROJECT_NAME})
ament_package()
Utilising Custom Library in ROS 2 C++ Package
- Includes necessary headers:
rclcppfor ROS 2 functionality,std_msgs/msg/string.hppfor standard message types, and**bot_move**.hfor your custom library. - Defines a class
BotMovethat inherits fromrclcpp::Node, providing a constructor that initializes the node with the name "bot_move". - Inside the constructor, it calls a function (
moveRobot()) from your custom librarybot_moveand logs the result usingRCLCPP_INFO.
sensor_fusion_node.cpp
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
## #include "bot_move.h"
class BotMove : public rclcpp::Node
{
public:
BotMove()
: Node("bot_move")
{
int result = moveRobot();
RCLCPP_INFO(this->get_logger(), "Result: %d", result);
}
};
int main(int argc, char*argv [])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<BotMove>();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
CmakeLists
cmake_minimum_required(VERSION 3.5)
project(sensor_fusion_pkg)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
include_directories(
include
${CMAKE_CURRENT_SOURCE_DIR}/lib
)
# create an executable
add_executable(bot_move_node src/bot_move.cpp)
# link your custom library
target_link_libraries(bot_move_node ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmove_bot.a)
ament_target_dependencies(sensor_fusion_node rclcpp)
# install the executable
install(TARGETS bot_move_node
DESTINATION lib/${PROJECT_NAME})
ament_package()
- Includes directories for the headers of your custom library (
${CMAKE_CURRENT_SOURCE_DIR}/lib). - Creates an executable named
BotMovefrombot_move.cppand links it with your custom library (target_link_libraries). - Specifies the dependencies (
ament_target_dependencies).
FAQ
Q: What is the standard structure of a ROS 2 C++ package?
A: A standard ROS 2 C++ package structure includes directories for include files, source files, a CMakeLists.txt file, a package.xml file, and other necessary files for building and running the package.
Q: How do you create a ROS 2 C++ package?
A: You can create a ROS 2 C++ package using the command:
bashCopy coderos2 pkg create --build-type ament_cmake --node-name sensor_fusion_node sensor_fusion_pkg
Q: How do you include OpenCV and Eigen libraries in a ROS 2 C++ package?
A: To include OpenCV and Eigen libraries, you need to find these packages and include their directories in your CMakeLists.txt file:
cmakeCopy codefind_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
Q: How do you use a custom library in a ROS 2 C++ package?
A: You include the header of your custom library in your node's source file and link the compiled library in your CMakeLists.txt file. For example, include the header in your .cpp file:
#include "bot_move.h"
And link the library in CMakeLists.txt:
cmakeCopy codetarget_link_libraries(bot_move_node ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmove_bot.a)
Q: Why is EIGEN3 not included in the target_link_libraries?
A: Eigen is a header-only library, which means its functionality is included directly through headers, and there are no compiled binaries to link against.
Q: Why is OpenCV written as OpenCV_LIBS while Boost is written as Boost_LIBRARIES?
A: The naming conventions for linking libraries in CMakeLists.txt can differ based on how the CMake configuration files for those libraries are set up. OpenCV_LIBS and Boost_LIBRARIES are the variables defined in their respective CMake configurations to hold the library linking information.
Lets take a Quiz
Practical Example
A practical way to use this article is to connect the concept to a small robot workflow: identify the input, the processing step, and the output you expect from the robot. If the article involves ROS 2, test the idea in a small workspace or simulation before applying it to a larger robot project.
Common Mistakes
- Trying to memorize the term without connecting it to a robot behavior.
- Skipping the prerequisite concepts that make the workflow easier to debug.
- Copying commands or code without checking what each node, topic, file, or parameter is responsible for.
- Treating one tutorial as a complete roadmap instead of linking it to the next concept.
How This Connects to Other Topics
- Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry
- Robot Starter Kit Guide: Choose the Right Beginner Robot Parts
- ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan
- From STL to Autonomy: Building an Indoor Self-Driving Robot
- ROS 2 Dataset Guide: Foxglove, RViz, and TurtleBot3 SLAM
Learn Next
- Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry
- Robot Starter Kit Guide: Choose the Right Beginner Robot Parts
- ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan
- From STL to Autonomy: Building an Indoor Self-Driving Robot
- ROS 2 Dataset Guide: Foxglove, RViz, and TurtleBot3 SLAM
- Mobile Robotics Engineer Path
FAQ
Is How to Add Custom Libraries to a ROS 2 C++ Package suitable for beginners?
Yes. The article is written to make the concept easier to understand, while still connecting it to practical robotics work.
What should I learn before this topic?
Start with the prerequisite ideas listed in the article, then connect them to a small project or simulation so the concept becomes concrete.
How does this topic connect to real robots?
It helps you understand how software, sensors, control, simulation, or career decisions show up in practical robot development.
What should I do after reading this article?
Pick one related concept from the Learn Next section and build a small example that uses it.
Can I learn this through Robotisim?
Yes. Robotisim connects these concepts to structured learning paths and project-based robotics practice.
Final Summary
How to Add Custom Libraries to a ROS 2 C++ Package is part of the broader Nav2 and Autonomous Navigation learning path. The key is to understand the concept, connect it to a real robot workflow, and then practice it through a focused project instead of learning it in isolation.
This article supports Mobile Robotics Engineer Path, especially Nav2.
Learn with Robotisim
Build a complete Nav2 robot inside Robotisim.
Explore the academyLearn next

Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry
Understand robot localization using encoder odometry in C++. Learn how robots estimate pose indoors with equations, examples, and real world insights.
Read more
Robot Starter Kit Guide: Choose the Right Beginner Robot Parts
Avoid overspending on the wrong parts. This guide walks you through building your first robot with a smart, affordable robot starter kit and key upgrade paths.
Read more
ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan
Learn how to set up ROS 2 SLAM and map your robot's environment. A beginner friendly guide to launching SLAM with LiDAR, odometry, and ROS 2 navigation stack.
Read more
From STL to Autonomy: Building an Indoor Self-Driving Robot
Learn how to build a ROS 2 autonomous robot from 3D printed STL parts to indoor navigation. A complete DIY guide for robotics and ROS 2 beginners.
Read more