Modify “package.xml” and “CMakeLists.txt” files for using C++ in ROS
You may have noticed in our blogs that we have chosen Python in the process of learning ROS. All the examples that we have seen are implemented using Python. It is because Python is easy to learn and implement, and people without computer science background are more comfortable with Python. Also, ROS has strong support for Python.
However, sometimes you may want to use C++ for ROS development. The reason may be that you are more at ease with C++ or you may need to use any library that does not have Python support. In that case, you should have an idea how to implement and compile C++ files in ROS. Therefore, we will briefly describe what steps do you need to perform while using C++.
Difference between Python and C++
The main difference between Python and C++ is that Python is an interpreted language, while C++ is a compiled language. For this reason, every time when you make a change in C++ code, you will have to recompile it using catkin_make.
You may recall that in Python examples, we have modified package.xml and CMakeLists.txt while defining our own messages. But we did not modify these files, when we used ROS standard messages . However, in case of C++ we will have to modify CMakeLists.txt every time when we add a new node in the package. We may also need to modify package.xml if we have not included “roscpp” dependency while creating package.
Let’s see what steps we need to perform while working with C++ in ROS
Modify package.xml File
The package.xml file is created when we create a package with the command “catkin_create_pkg”. In this file we have to declare all our dependencies.
For using C++, we have to declare both a build and a runtime dependency as follows
<build_depend>roscpp</build_depend> <run_depend>roscpp</run_depend>
However, if we have provided “roscpp” dependency while creating package, the command “catkin_create_pkg” will add dependencies itself in the package.xml file (Same as in case of Python where we provide rospy dependency).
The structure of the command is
catkin_make <Package_Name> roscpp
Now create a package with roscpp dependency
Open a terminal
Run the command
cd ~/catkin_ws/src
(To go to catkin_ws workspace)
Now run the command
catkin_create_pkg roscpp_example roscpp std_msgs
(Here, we added two dependency packages, roscpp and std_msgs, the above command will add dependencies for both in the package.xml file).
You will see the executed commands and the output as shown in figure below
Now go to the package “roscpp_example”, and open the file “package.xml” using gedit command
Run the commands
roscd roscpp_example gedit package.xml
You can see in figure below that the dependencies for roscpp and std_msgs are already added in the file package.xml.
You may have noticed that the package added the execute dependency instead of run dependency as show in the figure.
<exec_depend>roscpp>/exec_depend>
It does the same thing. You don’t have to worry about it.
I repeat that if you have not given “roscpp” dependency in command line while creating the package, then you will have to add it yourself in package.xml file. Same applies for “rospy” and “std_msgs” etc.
Save and close the file.
Modify CMakeLists.txt File
We have already modified CMakeLists.txt file while defining our own messages. However, we will have to modify this file in any case while working with C++.
For example if we create a new file “topic_publisher.cpp”, we have to add it in add_executable, add_dependencies, and target_link_libraries.
We open the file and show the lines that you have to add/modify
Run the command
gedit CMakeLists.txt
1. Go to the line where the line
# add_executable(${PROJECT_NAME}_node src/roscpp_example_node.cpp)
is given. You will see that this line is commented. Uncomment the line and modify it as follows
add_executable(topic_publisher src/topic_publisher.cpp)
2. Also you will see another line
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
Uncomment and modify it as follows
add_dependencies(topic_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
3. Search the line
# target_link_libraries(${PROJECT_NAME}_node # ${catkin_LIBRARIES} # )
Uncomment and modify it as follows
target_link_libraries(topic_publisher ${catkin_LIBRARIES} )
To summarize, you have to add following three lines in CMakeLists.txt file for every new node added in your package.
add_executable(topic_publisher src/topic_publisher.cpp) add_dependencies(topic_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) target_link_libraries(topic_publisher ${catkin_LIBRARIES} )
If you create another file such as “topic_subscriber.cpp”, you will have to add above three lines again for the new file.
We keep the original (commented) lines and added lines in CMakeLists.txt file so that you can view it clearly as shown in figure below
Save and close the file.
Compile the package using catkin_make
Now that you have modified the file, go to the workspace and run “catkin_make” command as we have done previously
cd ~/catkin_ws catkin_make source devel/setup.bash
Run the executable
Finally, you are ready to run the executable file. You can run the file using “rosrun” command.
However, there is again one difference. In case of Python you give the name of the file along with extension i.e. “.py”. But in case of C++ file, you give the file name without extension. Otherwise you will get an error.
For example,
The structure of rosrun command is as follows
rosrun <package name> <File Name>
We execute pyhton file as follows
rosrun ros_basics topic_publisher.py
But in case of C++ file, you will run the command as follows
rosrun roscpp_example topic_publisher
(If you run the command as “rosrun roscpp_example topic_publisher.cpp”, it will give an error)
Now you are able to execute C++ files. However, writing C++ code in our blogs is out of scope presently. We will continue learning ROS using Python. Nevertheless, we may add few example of C++ at any stage later (if demanded).