CMake Capabilities and Functions
CMake Capabilities and Functions
CMake scripts:
- Probe a target system's characteristics by checking for predefined types, header files, libraries, functions; by probing the type, version, and behavior of the c/c++ compiler in use; and running test compiles, links, and executions of sample code.
- Interpret options offered by the person building the application when the CMake script is invoked.
- Create compiler header files such as config.h that expose the characteristics of the target system into compilation units.
- Create build system scripts for various build tools such as GNU Makefiles, Ninja and NMake; and for Integrated Development Environments (IDEs) such as Microsoft Visual Studio or Apple Xcode.
- Create test case scripts
In this regard, CMake does much of what the GNU Autotools suite does, although GNU Autotools will only create build scripts for Make.
CMake Processing Steps
When using CMake, there are three major steps in the process of creating a useable application:
- Configure, where the CMake script uses the target system's characteristics and the user's option specifications to generate scripts for the chosen build tool. The part of CMake that creates scripts for a given build system is known as a "Generator." CMake includes many generators, including Apple Xcode, Makefiles, Ninja, NMake, and Microsoft Visual Studio. The user can specify the generator to be used when invoking a CMake script. At the end of the Configure step, a complete set of scripts exists to compile, link, and otherwise prepare the application for use using the specified build tool. CMake also creates an install target in the build system scripts. If tests were defined in the CMake script, CMake creates a CMake script to run those tests.
- Build, where the build tool uses the generated build scripts and headers to compile, link, and otherwise transform application source files into a set of executable binaries. At the end of the Build step, a complete and (normally) executable application exists in the build directory tree, also known as the build tree.
- Install, where the components required to run the application are copied to appropriate directories for general use. Required components typically include executables, shared libraries, and documentation, although any file may be deemed required for installation. The appropriate directory is often but need not be a system directory; -DCMAKE_INSTALL_PREFIX=<> can be used to specify an installation directory.
This three-step process corresponds to the typical GNU Autotools process:
configure && make && make install
.
How CMake Views an Application
A CMake script creates and uses what it calls targets. A target might be a shared library, a static library, or an executable and is defined during Configure. Targets have attributes. For a library, for example, attributes include the name and location of the library, the location of the public headers needed to use the library, and whether there are different versions for Release and Debug configurations. Targets are defined and described in the CMake script, and CMake uses those target definitions to create script(s) for the build tool, such as Makefile when using GNU Makefiles.
When a target, for example an executable target, references a library target, CMake uses the library target's attributes to ensure the compile steps for the executable include all needed header directories and the link steps reference the correct library name and location. CMake also ensures that the build tool builds the library before linking the executable. CMake knows from the library target attributes whether it is a static or shared library and uses build tool commands appropriate for the type of library. The CMake script writer need not worry about that.
CMake also addresses Windows-specific application elements such as resource compiler files and DLL export lists. These can be included as source files for the targets that require them when building for a Windows target system. CMake will ignore them without comment when the target system is UNIX-like. See the source file Herc61_SlibSource.cmake in the Hercules-390 repository for examples.
If this leads you to conclude that switching from a static library to a shared library should be easy when using CMake, you would be correct. If you are wondering if a CMake script written for shared libraries will deal with the differences between UNIX-like .so files and Windows .DLL files and the corresponding Windows DLL export library, the answer is, "Yes." No additional CMake scripting is needed to deal with the specifics of shared versus static libraries, or the differences in shared library implementation between Windows and UNIX-like target systems.
Benefits of Using CMake to Build Hercules-390
CMake uses the same CMake script to create build scripts for, say, Ninja, GNU Makefiles, or Microsoft Visual Studio. A CMake Script that creates a Microsoft Visual Studio 2015 build environment can create build scripts for Microsoft's older build tool NMake, or an older version of Microsoft Visual Studio, by changing the generator name specified on the CMake command line.
The CMake script does need to code for alternative build tools and targets. For example, the c compiler command line switches for Microsoft Visual Studio C are very different from those used for gcc. CMake provides variables that expose the name of the build tool and the target system to the script so that these differences can be accommodated. An application when built for a Windows system might require a few different source files than when built for a UNIX-like system.
These differences do not overwhelm the script. In the Hercules-390 CMake scripts, about 7,800 lines of code in 22 files, there are 33 tests for a Windows target system and 525 lines of script specific to the Microsoft Visual Studio C compiler. There is one test for the Ninja build tool and 648 lines specific to the GNU C Compiler gcc. The same 648 lines are used for clang when the target system is not Apple mac OS.
During Build, targets are imported, compiled, linked, and/or copied by the build tool as specified in the build tool script created by CMake during Configure. Because CMake is not a build tool, but rather a creator of scripts for existing build tools, the Build step is pretty unremarkable.
Another benefit of CMake: when using the NMake build tool on Windows, the win32.mak script is not required. Microsoft included win32.mak as a component of early versions of the Windows SDK and then removed it from the SDKs and from Visual Studio. Hand-coded NMake build scripts including those developed to build Hercules-390 on Windows often depended on win32.mak. Using these scripts on Visual Studio 2015 forced a user to find an old SDK and copy win32.mak into a current SDK directory.
This web page Copyright © 2017 by Stephen R. Orso.
This work is licensed under the Creative Commons Attribution-
ShareAlike 4.0 International License.
To view a copy of this license,
visit
http://creativecommons.org/licenses/by-sa/4.0/
or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.