|Note: This tutorial assumes that you have completed the previous tutorials: creating a ROS package.|
|Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.|
Building a ROS PackageDescription: This tutorial covers the toolchain to build a package.
Tutorial Level: BEGINNER
Next Tutorial: Understanding ROS Nodes
As long as all of the system dependencies of your package are installed, we can now build your new package.
Note: If you installed ROS using apt or some other package manager, you should already have all of your dependencies.
Before continuing remember to source your environment setup file if you have not already. On Ubuntu it would be something like this:
# source /opt/ros/%YOUR_ROS_DISTRO%/setup.bash $ source /opt/ros/kinetic/setup.bash # For Kinetic for instance
# In a catkin workspace $ catkin_make [make_targets] [-DCMAKE_VARIABLES=...]
For people who are unfamiliar with the standard CMake workflow, it breaks down as follows:
Note: If you run the below commands it will not work, as this is just an example of how CMake generally works.
# In a CMake project $ mkdir build $ cd build $ cmake .. $ make $ make install # (optionally)
This process is run for each CMake project. In contrast catkin projects can be built together in workspaces. Building zero to many catkin packages in a workspace follows this work flow:
# In a catkin workspace $ catkin_make $ catkin_make install # (optionally)
The above commands will build any catkin projects found in the src folder. This follows the recommendations set by REP128. If your source code is in a different place, say my_src then you would call catkin_make like this:
Note: If you run the below commands it will not work, as the directory my_src does not exist.
# In a catkin workspace $ catkin_make --source my_src $ catkin_make install --source my_src # (optionally)
Building Your Package
You should already have a catkin workspace and a new catkin package called beginner_tutorials from the previous tutorial, Creating a Package. Go into the catkin workspace if you are not already there and look in the src folder:
$ cd ~/catkin_ws/ $ ls src
You should see a lot of output from cmake and then make, which should be similar to this:
Base path: /home/user/catkin_ws Source space: /home/user/catkin_ws/src Build space: /home/user/catkin_ws/build Devel space: /home/user/catkin_ws/devel Install space: /home/user/catkin_ws/install #### #### Running command: "cmake /home/user/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/user/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/user/catkin_ws/install" in "/home/user/catkin_ws/build" #### -- The C compiler identification is GNU 4.2.1 -- The CXX compiler identification is Clang 4.0.0 -- Checking whether C compiler has -isysroot -- Checking whether C compiler has -isysroot - yes -- Checking whether C compiler supports OSX deployment target flag -- Checking whether C compiler supports OSX deployment target flag - yes -- Check for working C compiler: /usr/bin/gcc -- Check for working C compiler: /usr/bin/gcc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Using CATKIN_DEVEL_PREFIX: /tmp/catkin_ws/devel -- Using CMAKE_PREFIX_PATH: /opt/ros/kinetic -- This workspace overlays: /opt/ros/kinetic -- Found PythonInterp: /usr/bin/python (found version "2.7.1") -- Found PY_em: /usr/lib/python2.7/dist-packages/em.pyc -- Found gtest: gtests will be built -- catkin 0.5.51 -- BUILD_SHARED_LIBS is on -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- ~~ traversing packages in topological order: -- ~~ - beginner_tutorials -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- +++ add_subdirectory(beginner_tutorials) -- Configuring done -- Generating done -- Build files have been written to: /home/user/catkin_ws/build #### #### Running command: "make -j4" in "/home/user/catkin_ws/build" ####
Note that catkin_make first displays what paths it is using for each of the 'spaces'. The spaces are described in the REP128 and by documentation about catkin workspaces on the wiki: catkin/workspaces. The important thing to notice is that because of these default values several folders have been created in your catkin workspace. Take a look with ls:
build devel src
The build folder is the default location of the build space and is where cmake and make are called to configure and build your packages. The devel folder is the default location of the devel space, which is where your executables and libraries go before you install your packages.
Once all the system dependencies are installed, we can build our package that we just created.
rosmake is just like the make command, but it does some special ROS magic. When you type rosmake beginner_tutorials, it builds the beginner_tutorials package, plus every package that it depends on, in the correct order. Since we listed rospy, roscpp, and std_msgs as dependencies when creating our ROS package, these packages (and their dependiencies, and so on) will be built by rosmake as well.
$ rosmake beginner_tutorials
This previous command may take a while to finish. As it is running you should see some output like:
[ rosmake ] No package specified. Building ['beginner_tutorials'] [ rosmake ] Logging to directory [ rosmake ] /home/dbking/.ros/rosmake_output-2009-09-22-03-17-14 [ rosmake ] [ 0 of 18 Completed ] [rosmake-0] >>> genmsg_cpp >>> [ make ] [rosmake-0] <<< genmsg_cpp <<< [PASS] [ 0.39 seconds ] [ rosmake ] [ 1 of 18 Completed ] ... ... ... [ rosmake ] [ 17 of 18 Completed ] [rosmake-0] >>> beginner_tutorials >>> [ make ] [rosmake-0] <<< beginner_tutorials <<< [PASS] [ 0.79 seconds ]
On Fuerte, since dependencies are greatly reduced, this takes almost no time and produces:
[ rosmake ] rosmake starting... [ rosmake ] Packages requested are: ['beginner_tutorials'] [ rosmake ] Logging to directory /home/alex/.ros/rosmake/rosmake_output-20120603-082414 [ rosmake ] Expanded args ['beginner_tutorials'] to: ['beginner_tutorials'] [rosmake-0] Starting >>> std_msgs [ make ] [rosmake-1] Starting >>> roslang [ make ] [rosmake-0] Finished <<< std_msgs ROS_NOBUILD in package std_msgs No Makefile in package std_msgs [rosmake-1] Finished <<< roslang ROS_NOBUILD in package roslang No Makefile in package roslang [rosmake-1] Starting >>> rospy [ make ] [rosmake-2] Starting >>> roscpp [ make ] [rosmake-1] Finished <<< rospy ROS_NOBUILD in package rospy No Makefile in package rospy [rosmake-2] Finished <<< roscpp ROS_NOBUILD in package roscpp No Makefile in package roscpp [rosmake-2] Starting >>> beginner_tutorials [ make ] [rosmake-2] Finished <<< beginner_tutorials [PASS] [ 1.14 seconds ] [ rosmake ] Results: [ rosmake ] Built 5 packages with 0 failures. [ rosmake ] Summary output to directory [ rosmake ] /home/alex/.ros/rosmake/rosmake_output-20120603-082414
rosmake multiple packages
We can also use rosmake to build multiple packages at once.
rosmake [package1] [package2] [package3]
Lets just list some of the commands we've used so far:
- rosdep = ros+dep(endencies) : a tool to install package dependencies
- rosmake = ros+make : makes (compiles) a ROS package
Now that you have built your ROS package let's talk more about ROS Nodes.