Cmake_command

Note: This tutorial assumes that you have completed the previous tutorials: Creating a ROS Package.

Description ΒΆ The cmake executable is the command-line interface of the cross-platform buildsystem generator CMake. The above Synopsis lists various actions the tool can perform as described in sections below. To build a software project with CMake, Generate a Project Buildsystem. Get started with CMake Tools on Linux. CMake is an open-source, cross-platform tool that uses compiler and platform independent configuration files to generate native build. This defines a command to generate specified OUTPUT file(s). A target created in the same directory (CMakeLists.txt file) that specifies any output of the custom command as a source file is given a rule to generate the file using the command at build time.

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.
Description: How to use catkin_make to build and install packages from source in a catkin workspace.Not
Keywords: catkin workspace
Cmake_commandTutorial Level: BEGINNER
Next Tutorial:Overlaying catkin packages using workspaces

Contents

  1. Building Packages in a catkin Workspace
    1. With catkin_make
    2. Without catkin_make

Building Packages in a catkin Workspace

First this tutorial will cover the basics of how the catkin_make tool works. Then optionally you can continue the tutorial which demonstrates how to build a catkin workspace without catkin_make, which can be very instructive about what catkin_make is doing.

With catkin_make

Using catkin_make to build a catkin workspace is very simple. You must call it in the top level of your catkin workspace. A typical workflow is:

$ cd ~/catkin_ws/src/beginner_tutorials/src

# Add/Edit source files

$ cd ~/catkin_ws/src/beginner_tutorials

# Update CMakeFiles.txt to reflect any changes to your sources

$ cd ~/catkin_ws

$ catkin_make -DCMAKE_BUILD_TYPE=Release

Note: You might want to select a different CMake build type (e.g. RelWithDebInfo or Debug, see http://cmake.org/cmake/help/v2.8.12/cmake.html#variable:CMAKE_BUILD_TYPE).

This will build any packages in the source space (~/catkin_ws/src) to the build space (~/catkin_ws/build). Any source files, python libraries, scripts or any other static files will remain in the source space. However, any generated files such as libraries, executables, or generated code will be placed in the devel space. Also in the devel space there will be setup.*sh files generated, which when sourced will prefix your environment with this devel space.

If you want you can pass any arguments you would normally pass to make to catkin_make. For instance, you can tell it to make the install target:

This will be equivalent to calling 'cd ~/catkin_ws/build && make install'. Now there should be an install space (~/catkin_ws/install), which contains its own setup.*sh files. Sourcing one of these setup.*sh files will overlay this install space onto your environment.

Note you should use either the install space or the devel space, not both at the same time. The devel space is useful when you are developing on the packages in your workspace, because then you don't have to invoke the install target each time, which is particularly useful when developing on Python or when running tests.

The install space is useful when you are ready to distribute or 'install' the packages in your workspace. For instance, when building ROS from source you can use the 'install' target to install it to the system by passing the CMake argument '-DCMAKE_INSTALL_PREFIX=/opt/ros/groovy' to catkin_make:

If you have a previously compiled workspace and you add a new package inside it, you can tell catkin to add this new package to the already-compiled binaries by adding this parameter:

If you want to see the command lines used to run the compiler and linker, run catkin_make with this option:

Feel free to read more details about the inner workings of catkin_make or continue on to the next tutorial: Overlaying catkin packages using workspaces.

Limitations of catkin_make

All commands being executed as part of CMake and make use the same environment as the invocation. One example is a rostest being run as part of the tests. If the test itself depends on Python code which is e.g. being generated the path containing the generated code is not necessarily on the PYTHONPATH. catkin_make does not provide a mechanism to work around this problem. There are two workarounds for this problem:

  • You need to update the environment manually before running the tests. This can be achieved by the following sequence of commands:
  • The tool catkin_make_isolated which invoked CMake / make for each ROS package separately can handle this use case without a problem. The following command sequence just works:

    • catkin_make_isolated

    • catkin_make_isolated --make-args run_tests

Without catkin_make

Now that you can use catkin_make to build your workspace, the tutorial will delve into how to do it manually.

Preparing to Build

First we need to create a folder as the build space, usually <workspace>/build. This is where temporary build files will be generated by catkin and CMake. Create the build space directory with these commands:

There is only one build space directory per workspace. CMake users may find this unusual, we will have a single build folder for all our catkin projects. This is a key feature of catkin, it will work as if it were one large CMake project.

This folder is important for you, since this folder is where you will invoke build scripts. You can name it differently from build, in particular if you have need for more than one configuration, but 'build' is a good default, and other names should best also be prefixed with 'build_', by convention.

Configuring Packages

The next step in the build process is the configure step. This is where you invoke CMake so that it, and catkin, can configure your packages for building in this environment and on this system. Configuring is a step that needs to be done whenever you add or remove catkin packages from the source space, when you changed the build files for one of your packages, or when you want to change the build system settings.

Now that you have the workspace setup, you can invoke CMake to configure the catkin packages and generate their build scripts. Invoke CMake from the build space:

This will output some CMake lines to the console, but it won't do much else because there are no catkin packages in the source space.

The configuring step is also the point at which you can configure things like the installation prefix or other CMake/catkin settings. For example, you can set a different installation prefix by using the CMake variable CMAKE_INSTALL_PREFIX like so:

This will configure CMake to install things to the ~/catkin_ws/install directory rather than the default /usr/local directory.

Note: You can set the devel space directory to a folder in the workspace with this additional option added to CMake: cmake ./src -DCATKIN_DEVEL_PREFIX=./devel

Note: You can set the install directory to a folder in the workspace with this CMake command: cmake ./src -DCMAKE_INSTALL_PREFIX=./install

Building Packages

The previous step has configured the catkin packages that exist in this workspace's source space and placed generated build scripts into the build space directory, from which you can invoke the build scripts to build the catkin packages. By default Make scripts are created by CMake, so invoke make in the build space directory to build your catkin packages:

After building the catkin packages, the resulting build artifacts are placed into the devel space. The devel space mirrors the layout of an FHS-compliant install space.This will result in some new files in your devel space:

Most of these files in the build space should not be manually modified. The only exception is CMakeCache.txt, which you may change manually or using a standard cmake tool like ccmake (cmake-curses-gui) or cmake-gui (installable on Ubuntu via apt-get).

The devel space contains only artifacts generated by the build step. Any source files, headers or resources located in the source space are provided to the development space using several types redirection. This means that when developing Python, for instance, you can edit Python modules in the source space and then test against those changes in the devel space with out invoking CMake or make again.

CMake users may find this unusual, since a more conventional workflow requires installation before usage. This is a key feature of catkin allowing quicker development cycles. It is up to you whether you want to use this feature.

For more information about the <workspace>/build/develspace folder in general see: catkin/workspaces#Development_.28Devel.29_Space

Installing Packages

Cmake_command

After building the catkin packages in your workspace you can either use them directly via the catkin/workspaces#Development_.28Devel.29_Space or you can install them. Installing the catkin packages can be done by invoking the special install target generated by CMake.

Remember back to the Configuring Packages section of this tutorial, specifically where we mentioned that the installation prefix can be changed by passing the CMAKE_INSTALL_PREFIX to cmake. This installation prefix dictates where the installation step puts files. This location is referred to as the install space. Lets set this to something in the workspace and run the install step:

If make install fails because of missing permissions, then you probably forgot to call cmake with the -DCMAKE_INSTALL_PREFIX option. In this case run cmake again with the option before attempting make install.

Since we still do not have any packages in the src folder, this does not install any catkin packages, but we do get some additional files in our workspace.

During make install files should have been copied into your specificed CMAKE_INSTALL_PREFIX. Most likely there will be a 'bin', 'lib', 'share', and some other folders created there. Additionaly, there will be setup.*sh files which are specific to catkin. These environment setup files are convenience files which when sourced by your shell will extend your environment to include the install space or devel space that they reside in. For a concrete example of why this is useful, consider that you just called make then make install on one of your packages which contained an executable, and that you now want that executable to be in your PATH.

As you can see, the install space has a very similar layout as the devel space.

With non-catkin software you would need to manually extend your PATH variable or install the package to a location already on the PATH like '/usr', but with catkin you can simply extend your environment by sourcing the environment setup files like this:

Which files of your package get installed, static or generated, is determined by CMake commands in your CMakeLists.txt. Generally your executables are put into a 'bin' folder, your libraries in a 'lib', and so on, but the prefix for those folders is set by the CMAKE_INSTALL_PREFIX. The CMAKE_INSTALL_PREFIX defaults to '/usr/local', which is the UNIX convention when building software yourself, but it can be overridden at CMake invocation time. We strongly recommend using a different folder for developers like a folder in the workspace to allow easy uninstall and working with multiple ROS distributions. Do NOT install from source to the default location on a shared computer (like a robot) unless you are the robot administrator and are aware that there is no uninstall command. Catkin calls the space where you install things to the install space.

Cleaning up

You can delete your buildspace and install space whenever you want, and re-create them using the steps above. The main purpose of this is to 'uninstall' packages you have built or make install'ed previously.

Next you should go ahead and learn how to Overlaying catkin packages using workspaces.

The Android NDK supports using CMake tocompile C and C++ code for your application. This page discusses how to useCMake with the NDK via the Android Gradle Plugin's ExternalNativeBuild or wheninvoking CMake directly.

Note: If you are using Android Studio, go to Add C and C++ code to yourproject to learn the basics of adding native sources to your project, creatinga CMake build script, adding your CMake project as a Gradle dependency, andusing newer versions of CMake than those included in the SDK.

The CMake toolchain file

The NDK supports CMake via a toolchain file. Toolchain files are CMake filesthat customize the behavior of the toolchain for cross-compiling. The toolchainfile used for the NDK is located in the NDK at<NDK>/build/cmake/android.toolchain.cmake.

Note: If the Android SDK is installed, then the NDK is installed in the SDKdirectory in ndk/version/ or ndk-bundle/.

Build parameters such as ABI, minSdkVersion, etc. are given on the commandline when invoking cmake. For a list of supported arguments, see theToolchain arguments section.

Warning: CMake has its own built-in NDK support. This workflowis not supported by Android and is often broken with new NDK releases or whenusing older versions of CMake. Use of this workflow is strongly discouraged, andwill not work with Gradle. In the future these two workflows will merge and bothbe supported by Android. See Issue 463 for more information.

Usage

Gradle

Use of the CMake toolchain file is automatic when usingexternalNativeBuild. See Android Studio's Add C and C++ code to yourproject guide for more information.

Command Line

When building with CMake outside of Gradle, the toolchain file itself andits arguments must be passed to CMake. For example:

Toolchain arguments

The following arguments can be passed to the CMake toolchain file. If buildingwith Gradle, add arguments toandroid.defaultConfig.externalNativeBuild.cmake.arguments as described in theExternalNativeBuild docs. If building from the command line, pass arguments toCMake with -D. For example, to force armeabi-v7a to always build with Neonsupport, pass -DANDROID_ARM_NEON=TRUE.

Note: Any required arguments are passed automatically by Gradle and need only bepassed explicitly if building from the command line.

ANDROID_ABI

Note: This is a required argument.

The target ABI. For information on supported ABIs, see Android ABIs.

Gradle

Gradle provides this argument automatically. Do not explicitly set thisargument in your build.gradle file. To control what ABIs Gradle targets,use abiFilters as described in Android ABIs.

Command Line

CMake builds for a single target per build. To target more than one AndroidABI, you must build once per ABI. It is recommended to use different builddirectories for each ABI to avoid collisions between builds.

ValueNotes
armeabi-v7a
armeabi-v7a with NEONSame as -DANDROID_ABI=armeabi-v7a -DANDROID_ARM_NEON=ON.
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

Specifies whether to generate arm or thumb instructions for armeabi-v7a. Has noeffect for other ABIs. For more information, see the Android ABIsdocumentation.

ValueNotes
arm
thumbDefault behavior.

ANDROID_ARM_NEON

Enables or disables NEON for armeabi-v7a. Has no effect for other ABIs. Defaultsto true for API level (minSdkVersion or ANDROID_PLATFORM) 23 or newer, falseotherwise. For more information, see the Neon support documentation.

ValueNotes
TRUEDefault for API level 23 or newer.
FALSEDefault for API level 22 or older.

ANDROID_LD

Selects which linker to use. lld is currently experimental for the NDK and canbe enabled with this argument.

ValueNotes
lldEnables lld.
defaultUse the default linker for the given ABI.

ANDROID_NATIVE_API_LEVEL

Alias for ANDROID_PLATFORM.

ANDROID_PLATFORM

Specifies the minimum API level supported by the application or library. Thisvalue corresponds to the application's minSdkVersion.

Gradle

When using the Android Gradle Plugin, this value is automatically set tomatch the application's minSdkVersion and should not be set manually.

Command Line

When invoking CMake directly, this value defaults to the lowest API levelsupported by the NDK in use. For example, with NDK r20 this value defaultsto API level 16.

Warning: NDK libraries cannot be run on devices with an API level below theANDROID_PLATFORM value with which the code was built.

Multiple formats are accepted for this parameter:

  • android-$API_LEVEL
  • $API_LEVEL
  • android-$API_LETTER

The $API_LETTER format allows you to specify android-N without the need todetermine the number associated with that release. Note that some releasesreceived an API increase without a letter increase. These APIs can be specifiedby appending the -MR1 suffix. For example, API level 25 is android-N-MR1.

ANDROID_STL

Specifies which STL to use for this application. For more information, see C++library support. By default, c++_static will be used.

Cmake_commandCaution: The default behavior is not appropriate for all applications. Be sureto read the C++ library support guide and in particular the section aboutstatic runtimes before choosing an STL.
ValueNotes
c++_sharedThe shared library variant of libc++.
c++_staticThe static library variant of libc++.
noneNo C++ standard library suport.
systemThe system STL

Understand the CMake build command

When debugging CMake build issues, it's helpful to know the specific buildarguments that Gradle uses when cross-compiling for Android.

Cmake Build Command

The Android Gradle Plugin saves the build arguments it uses for executing aCMake build for each ABI and build typepair to the cmake_build_command.txt. These files are found in the followingdirectory:

Note: Older versions of the Android Gradle Plugin placed these files in the.externalNativeBuild directory rather than the .cxx directory.

The following snippet shows an example of the CMake arguments to build adebuggable release of the hello-jni sample targeting the armeabi-v7aarchitecture.

Use prebuilt libraries

For instructions on using prebuilt libraries with CMake, see the add_librarydocumentation regarding IMPORTED targets in the CMake manual.

YASM support in CMake

The NDK provides CMake support for building assembly code written inYASM to run on x86 and x86-64architectures. YASM is an open-source assembler for x86 and x86-64architectures, based on the NASM assembler.

To build assembly code with CMake, make the following changes in your project'sCMakeLists.txt:

  1. Call enable_language with the value set to ASM_NASM.
  2. Depending on whether you are building a shared library or an executablebinary, call add_library or add_executable. Inthe arguments, pass in a list of source files consisting of the .asm filesfor the assembly program in YASM and the .c files for the associated Clibraries or functions.

The following snippet shows how you might configure your CMakeLists.txt tobuild a YASM program as a shared library.

Cmake Commands

For an example of how to build a YASM program as an executable, see the yasmtest in the NDK git repository.

Report problems

Cmake_command Copy

If you run into any issues with the NDK or its CMake toolchain file, report themvia the android-ndk/ndk issue tracker on GitHub.