Quick Introduction to CMake
This chapter is geared towards users who have not used CMake before. If you have used CMake previously feel free to skip this chapter.
About CMake
Let’s start with some basic background on CMake.
What is CMake?
CMake stands for “Cross platform Make” and is a tool to facilitate building
packages on a variety of platforms. The CMake suite of programs contains a
number of programs, but for our present purposes the only one you need to be
aware of is the literal CMake program, cmake
.
Obtaining CMake
CMake’s official website is here and contains links to download and install the CMake package. CMake is also readily available in most package managers. Most modern packages that rely on CMake require at least CMake version 3.0, but you’ll need at least version 3.14 to build CMaize-based projects.
Building CMake
For now follow CMake’s instructions as I’m too lazy to write my own.
Using CMake
Basic CMake Usage
Now that you have the CMake package installed on your system you can run the
cmake
command. Let’s say you just downloaded some package
an_awesome_package
. If you look at the file structure of
an_awesome_package
you should see one or more files called
CMakeLists.txt
. These files are written by the package maintainer and tell
CMake how to build the package. Conventional usage will have you run the
cmake
command in the directory that contains an_awesome_package
’s
top-level CMakeLists.txt
(and this tutorial assumes that this is the case).
Thus in that directory you minimally will need to run:
cmake -H. -B<scratch_dir>
The -H.
tells CMake to start running in the current directory. It is
possible to run CMake from another directory and adjust the path to -H
, but
unless the package maintainer is a CMake guru (or used CMaize) doing so is
likely to break the build; hence, it is good practice to always run in the same
directory as the top-level CMakeLists.txt
and just consider the -H.
as
boilerplate.
The -B<scratch_dir>
tells CMake where it can put autogenerated files as well
as any intermediate object files. You should replace <scratch_dir>
with a
descriptive name such as build-debug
to signal that this is the build
directory for a debug build (assuming of course that you are building a debug
version of the package).
After running the cmake
command a plethora of text output usually ensues
ending with something like:
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/the/build/directory/you/set
[Finished]
This signals that the cmake
command has run successfully. It has not built
your project yet, rather it has generated the files required to build the
project. That said, typically you are home free once the cmake
command has
completed.
Realistic Usage
The usage in the previous section is somewhat idealized. Generally speaking you
will need to provide more information. CMake defines a lot of options and we
have collected them for you on the CMake Option Variables page. Two of
the more important options you should be aware of are CMAKE_INSTALL_PREFIX
and CMAKE_PREFIX_PATH
. While they may sound similar they are used for two
different purposes. CMAKE_INSTALL_PREFIX
tells CMake where to install the
package after it is built. On Unix-like machines, it defaults to something like
/usr/local
resulting in executables being installed to /usr/local/bin
,
header files to /usr/local/include
, etc. CMAKE_PREFIX_PATH
tells
CMake where to look for dependencies.
Now that you know about options, how do we set them? The answer is like this:
cmake -H. -B<scratch_dir> -DOPTION1=VALUE1 -DOPTION2=VALUE2...
That is to say they are appended to the cmake
command in the format
-D<option>=<value>
. Say we wanted to install the package to /foo/bar
the command to do this is:
cmake -H. -B<scratch_dir> -DCMAKE_INSTALL_PREFIX=/foo/bar
Some CMake variables, like CMAKE_PREFIX_PATH
, take lists. Lists are passed
to CMake by placing the contents in double quotes and separating items with
semicolons. For example, to tell CMake to look in /foo
and /bar
for
dependencies the command is:
cmake -H. -B<scratch_dir> -DCMAKE_PREFIX_PATH="/foo;/bar"
It is important to note that packages may also define their own options, in addition to those provided by CMake. Hence you should consult the package’s build documentation for any package specific options that are available.
Building and Installing
With the package configured, all that remains is to actually build it and to
install it. The commands to do this are similar and both are executed in the
same directory as the top-level CMakeLists.txt
. Building is done by:
cmake --build <scratch_dir>
and installing is done by:
cmake --build <scratch_dir> --target install
The install command may need to be run with administrator privileges if the current user does not have sufficient permissions to write to the installation destination.