User:Legalize/CMake
Contents |
An Overview of Build Systems
In C++, source files are preprocessed and compiled into translation units which are then linked to produce targets. The preprocessor, compiler, and linker typically exist as one or more executables in the development environment, driven by command-line arguments.
Traditional build systems, such as make, record these commands and their arguments and associate them with groups of files in a dependency graph. The dependency graph records the textual inclusion relationship between source files: a source .cpp file that includes a header .h file has a dependency on the contents of the header file). The dependency graph also includes link dependencies: a target depends on one or more translation units, either directly as local object files, or indirectly through libraries.
Some integrated development environments, such as Visual Studio and Xcode, record the build information in their own file format. Some development environments, such as vim or emacs, may rely entirely on an external build system that is invoked from the development environment.
CMake
CMake differs from other build systems by acting as a meta build system, recording information that is used to generate a build script for another build system: make, Visual Studio, Xcode, etc. An earlier meta build system, imake, was implemented with the C preprocessor and make. CMake is implemented as a standalone executable with no additional dependencies. CMake is designed to be a portable to any operating system supporting C and C++ compilation.
CMake achieves portability between environments for projects by recording information about targets in a generic manner. Information specific to a particular build environment can also be provided, such as a preferred organization of source files for navigation in an IDE. When a project supports multiple operating systems, it is often the case that some source files are processed differently to provide operating system specific code. This can be as simple as selecting a different set of source files for each operating system, or it can be as complex as distributing certain preprocessor symbol definitions across translation units. CMake supports these scenarios by providing commands for common operations and their command-line options. Like autoconf and configure scripts, CMake has mechanisms for probing and testing the target environment.
Execution
Commands to CMake are provided in a CMake lists file, usually named CMakeLists.txt. The commands describe the source files, directories and targets in a project. The user runs CMake and supplies the top-level directory location of the project and desired generator. CMake generates the build script for the project using the specified generator.
Depending on where CMake was told to create the project build script, CMake can be used in tree or out of tree. An in tree build is one where the project build script and outputs of the build are created in the same directories where source files are contained. An out of tree build creates the project build script and outputs of the build are created in a separate directory tree from the source files. For projects that build with multiple variants, or projects that cross compile, it can be more convenient to have an out of tree build for each variant.
The project's lists file is processed by CMake using the following steps:
- Create a global
cmakeobject which processes command-line arguments. - Create the appropriate global generator.
- Create the appropriate local generator for the top-level lists file.
- The local generator holds one
cmMakefileobject representing its parsed lists file.
Hello, CMake!
Here is a simple CMakeLists.txt lists file that creates an executable named hello_world from a single source file hello_world.cpp:
cmake_minimum_required(VERSION 2.8.11) project(hello_world CXX) add_executable(hello_world hello_world.cpp)
A lists file is so-named because it contains a list of CMake commands. Each command has a name, such as cmake_minimum_required or add_executable and an optional list of arguments enclosed in parentheses. If there are no arguments to the command, the parentheses are still required. Commands can accept keyword based arguments, such as VERSION 2.8.11.
The cmake_minimum_required command defines the minimum version of CMake needed to build this project.
The project command names the project and that it is a C++ project. The project name may be used by generators to create build script files, such as a Visual Studio solution or project file.
The add_executable command defines an executable target, hello_world to be built from a list of source files, hello_word.cpp.
CMake knows how to compile C++ source files into object files and how to link object files into a target, so no additional information is necessary. The generators used with CMake include additional logic to regenerate the build script when the lists file changes.