|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.|
Keywords: catkin workspace
Tutorial Level: BEGINNER
Next Tutorial:Overlaying catkin packages using workspaces
- Building Packages in a catkin Workspace
- With catkin_make
- 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.
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:
Surfshark download. catkin_make run_tests
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 --make-args run_tests
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.
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
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
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.
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.
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
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.
Use of the CMake toolchain file is automatic when using
externalNativeBuild. See Android Studio's Add C and C++ code to yourproject guide for more information.
When building with CMake outside of Gradle, the toolchain file itself andits arguments must be passed to CMake. For example:
The following arguments can be passed to the CMake toolchain file. If buildingwith Gradle, add arguments to
android.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
Note: This is a required argument.
The target ABI. For information on supported ABIs, see Android ABIs.
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.
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.
|Same as |
Specifies whether to generate arm or thumb instructions for armeabi-v7a. Has noeffect for other ABIs. For more information, see the Android ABIsdocumentation.
Enables or disables NEON for armeabi-v7a. Has no effect for other ABIs. Defaultsto true for API level (
ANDROID_PLATFORM) 23 or newer, falseotherwise. For more information, see the Neon support documentation.
|TRUE||Default for API level 23 or newer.|
|FALSE||Default for API level 22 or older.|
Selects which linker to use. lld is currently experimental for the NDK and canbe enabled with this argument.
|default||Use the default linker for the given ABI.|
Alias for ANDROID_PLATFORM.
Specifies the minimum API level supported by the application or library. Thisvalue corresponds to the application's
When using the Android Gradle Plugin, this value is automatically set tomatch the application's
minSdkVersion and should not be set manually.
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 the
ANDROID_PLATFORMvalue with which the code was built.
Multiple formats are accepted for this parameter:
$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
Specifies which STL to use for this application. For more information, see C++library support. By default,
c++_static will be used.
|c++_shared||The shared library variant of libc++.|
|c++_static||The static library variant of libc++.|
|none||No C++ standard library suport.|
|system||The 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:
.externalNativeBuilddirectory rather than the
The following snippet shows an example of the CMake arguments to build adebuggable release of the
hello-jni sample targeting the
Use prebuilt libraries
For instructions on using prebuilt libraries with CMake, see the
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's
enable_languagewith the value set to
- Depending on whether you are building a shared library or an executablebinary, call
add_executable. Inthe arguments, pass in a list of source files consisting of the
.asmfilesfor the assembly program in YASM and the
.cfiles 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.
For an example of how to build a YASM program as an executable, see the yasmtest in the NDK git repository.
If you run into any issues with the NDK or its CMake toolchain file, report themvia the android-ndk/ndk issue tracker on GitHub.