Difference between revisions of "Programming/Tools/CMake"
Line 211: | Line 211: | ||
.PHONY : cmake_check_build_system | .PHONY : cmake_check_build_system | ||
</pre> | |||
However, this <tt>Makefile</tt> doesn't do anything useful. That is because we haven't written any code in our project. Let's add it. | |||
First, let us modify <tt>.../my_project/CMakeLists.txt</tt>: | |||
<pre> | |||
project(cmake_test_project) | |||
cmake_minimum_required(VERSION 3.0) | |||
message(STATUS "*** Building my_project from ${PROJECT_SOURCE_DIR} ***") | |||
add_subdirectory(${PROJECT_SOURCE_DIR}/src) | |||
</pre> | |||
Make sure that we are under <tt>.../my_project/build</tt> and run | |||
<pre> | |||
$ cmake .. | |||
</pre> | |||
The following error message will appear: | |||
<pre> | |||
-- *** Building my_project from /home/ubuntu/my_project *** | |||
CMake Error at CMakeLists.txt:6 (add_subdirectory): | |||
The source directory | |||
/home/ubuntu/my_project/src | |||
does not contain a CMakeLists.txt file. | |||
-- Configuring incomplete, errors occurred! | |||
See also "/home/ubuntu/my_project/build/CMakeFiles/CMakeOutput.log". | |||
See also "/home/ubuntu/my_project/build/CMakeFiles/CMakeError.log". | |||
</pre> | </pre> |
Revision as of 18:57, 22 December 2020
Overview
CMake is an open-source, cross-platform family of tools designed to build, test, and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. The suite of CMake tools were created by Kitware in response to the need for a powerful, cross-platform build environment for open-source projects such as ITK and VTK.
CMake is part of Kitware's collection of commercially supported open-source platforms for software development.
This tutorial
In this tutorial we demonstrate how to set up and build an (admittedly very simple) project using CMake on an Ubuntu 20.04.1 LTS system. The tutorial should be applicable to other Linux systems, possibly with minor modifications.
Preparation
First, we need to install CMake:
$ sudo apt update ... $ sudo apt install cmake
Since we'll be using CMake with gcc—GNU project C and C++ compiler,— we also need to install gcc:
$ sudo apt install g++
Basic project
We'll start working from the home directory, so we
$ cd
to it. We then create a directory for the project
$ mkdir my_project
cd into it with
$ cd my_project
Now let us create a directory for source files
$ mkdir src
and the file CMakeLists.txt:
$ touch CMakeLists.txt
CMakeLists.txt contains a set of directives and instructions describing the project's source files and targets (executable, library, or both).
project(cmake_test_project) cmake_minimum_required(VERSION 3.0)
While you can build the project from the current directory (.../my_project/), CMake will generate some files that will pollute it. Therefore it is a good idea to
$ mkdir build $ cd build/ $ cmake ..
We should see something like this:
-- The CXX compiler identification is GNU 9.3.0 -- 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 -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/ubuntu/my_project/build
Under .../my_project/build/ you will see a pretty large Makefile containing something like this:
# CMAKE generated file: DO NOT EDIT! # Generated by "Unix Makefiles" Generator, CMake Version 3.16 # Default target executed when no arguments are given to make. default_target: all .PHONY : default_target # Allow only one "make -f Makefile2" at a time, but pass parallelism. .NOTPARALLEL: #============================================================================= # Special targets provided by cmake. # Disable implicit rules so canonical targets will work. .SUFFIXES: # Remove some rules from gmake that .SUFFIXES does not remove. SUFFIXES = .SUFFIXES: .hpux_make_needs_suffix_list # Suppress display of executed commands. $(VERBOSE).SILENT: # A target that is always out of date. cmake_force: .PHONY : cmake_force #============================================================================= # Set environment variables for the build. # The shell in which to execute make rules. SHELL = /bin/sh # The CMake executable. CMAKE_COMMAND = /usr/bin/cmake # The command to remove a file. RM = /usr/bin/cmake -E remove -f # Escaping for special characters. EQUALS = = # The top-level source directory on which CMake was run. CMAKE_SOURCE_DIR = /home/ubuntu/my_project # The top-level build directory on which CMake was run. CMAKE_BINARY_DIR = /home/ubuntu/my_project/build #============================================================================= # Targets provided globally by CMake. # Special rule for the target rebuild_cache rebuild_cache: @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." /usr/bin/cmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) .PHONY : rebuild_cache # Special rule for the target rebuild_cache rebuild_cache/fast: rebuild_cache .PHONY : rebuild_cache/fast # Special rule for the target edit_cache edit_cache: @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No inter active CMake dialog available..." /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. .PHONY : edit_cache # Special rule for the target edit_cache edit_cache/fast: edit_cache .PHONY : edit_cache/fast # The main all target all: cmake_check_build_system $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/my_project/build/C MakeFiles /home/ubuntu/my_project/build/CMakeFiles/progress.marks $(MAKE) -f CMakeFiles/Makefile2 all $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/my_project/build/C MakeFiles 0 .PHONY : all # The main clean target clean: $(MAKE) -f CMakeFiles/Makefile2 clean .PHONY : clean # The main clean target clean/fast: clean .PHONY : clean/fast # Prepare targets for installation. preinstall: all $(MAKE) -f CMakeFiles/Makefile2 preinstall .PHONY : preinstall # Prepare targets for installation. preinstall/fast: $(MAKE) -f CMakeFiles/Makefile2 preinstall .PHONY : preinstall/fast # clear depends depend: $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-bui ld-system CMakeFiles/Makefile.cmake 1 .PHONY : depend # Help Target help: @echo "The following are some of the valid targets for this Makefile:" @echo "... all (the default if no target is provided)" @echo "... clean" @echo "... depend" @echo "... rebuild_cache" @echo "... edit_cache" .PHONY : help #============================================================================= # Special targets to cleanup operation of make. # Special rule to run CMake to check the build system integrity. # No rule that depends on this can have commands that come from listfiles # because they might be regenerated. cmake_check_build_system: $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-bui ld-system CMakeFiles/Makefile.cmake 0 .PHONY : cmake_check_build_system
However, this Makefile doesn't do anything useful. That is because we haven't written any code in our project. Let's add it.
First, let us modify .../my_project/CMakeLists.txt:
project(cmake_test_project) cmake_minimum_required(VERSION 3.0) message(STATUS "*** Building my_project from ${PROJECT_SOURCE_DIR} ***") add_subdirectory(${PROJECT_SOURCE_DIR}/src)
Make sure that we are under .../my_project/build and run
$ cmake ..
The following error message will appear:
-- *** Building my_project from /home/ubuntu/my_project *** CMake Error at CMakeLists.txt:6 (add_subdirectory): The source directory /home/ubuntu/my_project/src does not contain a CMakeLists.txt file. -- Configuring incomplete, errors occurred! See also "/home/ubuntu/my_project/build/CMakeFiles/CMakeOutput.log". See also "/home/ubuntu/my_project/build/CMakeFiles/CMakeError.log".