CMakeLists.txt Tutorial & Example

CMakeLists.txt Tutorial & Example

Written by Bayode Aderinola

02/07/2018

Hello ROS developers! In this post, we will see what CMakeLists.txt is and it’s importance in ROS in just 5 minutes! We’ll see what happens when it’s absent and when it’s improperly modified.

Let’s go!

Step 1: Setup your development environment

I love coding, and I hope you do too. Because of this, we’re going to solve the problem in this section using a pseudo-Python code. Here you go:

def setup_ros_environ(you, ros, docker):
  if you.prefer_not_to_embrace_the_cloud_revolution() or not you.want_something_that_works_for_sure():
    if ros.is_installed() and ros.version <= 'kinetic' and ros.version < 'crystal':
      return "You are good to go; just be ready to spin up a terminal at short notice."
    elif docker.is_installed():
      return "run docker run -it osrf/ros:kinetic-desktop in your terminal to pull a ROS docker image. " 
             "Please note: " 
             "- Docker will “pull” this image if you don’t have it locally already." 
             "- You need to run this command on every terminal you use in this post, before typing any other command!" 
  else: 
    return "Launch a ready-to-go development environment on ROS Development Studio (http://rosds.online) within your browser!" 
           "Click this link to get your copy of a ready-made ROS project: http://www.rosject.io/l/92ac9a3/" 
           "To 'open a terminal', pick the Shell app from the Tools menu. "

“Run” the program above, act on the output and proceed to the next section!

Step 2: See what CMakeLists.txt is by getting your hands dirty – on the Shell and/or IDE

Create a package in your catkin workspace (we won’t add any code here since it’s not needed for the demo). If you are using the ROS Development Studio and copied the ROS project, the package is already there!

user:~/catkin_ws/src$ catkin_create_pkg cmakelists_test rospy
Created file cmakelists_test/CMakeLists.txt
Created file cmakelists_test/package.xml
Created folder cmakelists_test/src
Successfully created files in /home/user/catkin_ws/src/cmakelists_test. Please adjust the values in package.xml.

After creating a package, we ought to compile it. But before that, we’ll tamper with the CMakeLists.txt file and see what happens.

  1. Rename CMakeLists.txt to CMakeList.txt. Similar enough and should work, right? Let’s see.
user:~/catkin_ws/src$ cd cmakelists_test/
user:~/catkin_ws/src/cmakelists_test$ mv CMakeLists.txt CMakeList.txt
user:~/catkin_ws/src/cmakelists_test$ cd ../..
user:~/catkin_ws$ catkin_make
...(output truncated)
-- ~~  traversing 1 packages in topological order:
-- ~~  - cmakelists_test
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'cmakelists_test'
-- ==> add_subdirectory(cmakelists_test)
CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkin_workspace.cmake:116 (add_subdirectory):
  The source directory

    /home/user/catkin_ws/src/cmakelists_test

  does not contain a CMakeLists.txt file.
Call Stack (most recent call first):
  CMakeLists.txt:63 (catkin_workspace)


-- Configuring incomplete, errors occurred!
See also "/home/user/catkin_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/user/catkin_ws/build/CMakeFiles/CMakeError.log".
Invoking "cmake" failed

Didn’t work for sure. Let’s perform another dastardly act:

2. Restore the original name but comment out the ‘project’ directive of the CMakeLists.txt file shown below:

cmake_minimum_required(VERSION 2.8.3)
# project(cmakelists_test)                    --> comment out this line

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
user:~/catkin_ws$ cd src/
user:~/catkin_ws/src$ cd cmakelists_test/
user:~/catkin_ws/src/cmakelists_test$ mv CMakeList.txt CMakeLists.txt
user:~/catkin_ws/src/cmakelists_test$ cd ../..
user:~/catkin_ws$ catkin_make
... (output truncated)
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - cmakelists_test
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'cmakelists_test'
-- ==> add_subdirectory(cmakelists_test)
CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:91 (message):
  catkin_package() PROJECT_NAME is set to 'Project', which is not a valid
  project name.  You must call project() before calling catkin_package().
Call Stack (most recent call first):
  cmakelists_test/CMakeLists.txt:103 (catkin_package)


-- Configuring incomplete, errors occurred!
See also "/home/user/catkin_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/user/catkin_ws/build/CMakeFiles/CMakeError.log".
Makefile:318: recipe for target 'cmake_check_build_system' failed
make: *** [cmake_check_build_system] Error 1
Invoking "make cmake_check_build_system" failed

We aren’t getting away with tampering with CMakeLists.txt, are we? Now, let’s repent and restore the file: remove the comment from the ‘project’ directive, save and run catkin_make again.

cmake_minimum_required(VERSION 2.8.3)
project(cmakelists_test)                    --> uncomment this line

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
user:~/catkin_ws$ catkin_make
... (output truncated)
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - cmakelists_test
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'cmakelists_test'
-- ==> add_subdirectory(cmakelists_test)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/catkin_ws/build
####
#### Running command: "make -j2 -l2" in "/home/user/catkin_ws/build"
####

Moral lesson: CMakeLists.txt can make or mar a project, if not properly modified. Let’s talk more about that in the next section.

Step 3: Master the concept – what is CMakeLists.txt?

According to ROS Wiki (http://wiki.ros.org/catkin/CMakeLists.txt),

The file CMakeLists.txt is the input to the CMake build system for building software packages. Any CMake-compliant package contains one or more CMakeLists.txt file that describe how to build the code and where to install it to.

Well, now you can see why renaming the file isn’t a good idea.  But what about commenting out parts of the file? Also according to ROS Wiki:

Your CMakeLists.txt file MUST follow this format otherwise your packages will not build correctly. The order in the configuration DOES count.

The configuration directives in CMakeLists.txt must follow a particular order; this is why commenting out the ‘project’ directive didn’t work, as the error message also hinted.

Visit http://wiki.ros.org/catkin/CMakeLists.txt to learn more.

We’re done here.

Extra: Video

Prefer “sights and sounds” to “black and white”? We have a video covering this same post, just for you!

Followup and Feedback

If you are a ROS beginner and want to learn ROS basics fast, we recommend you take any of the following courses on Robot Ignite Academy:

ROS Basics In 5 Days (Python)
ROS Basics In 5 Days (C++)

Did you like this video? Whatever the case, please leave a comment in the comments section below, so we can interact and learn from each other.

Thank you!

Check Out These Related Posts

0 Comments

Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pin It on Pinterest

Share This