## CMake

CMake seems to me like the best available cross-platform build tool. It can generate Visual Studio solutions on Windows and Make files on POSIX systems. While it's widely used and there exists thorough reference documentation for it, I feel like there aren't many resources for getting started. As a result, I've written up some notes from what I've been able to infer from a variety of project's CMake configurations as well as the scant introductory information I was able to find.

# #General Usage

CMake directives are stored in files named CMakeLists.txt, and there is usually one such file present for each sub-directory in the source tree, each one conventionally containing directives pertinent to the files in that directory. These separate CMake files are then "merged together" using the add_subdirectory directive, which immediately makes the CMake interpreter load and evaluate the CMake file in the provided directory.

Variables can be set using the set directive in the following format:

There are certain built-in CMake variables that can affect the project. A commonly set one is CMAKE_MODULE_PATH which defines where CMake modules should be looked for.

Similarly, user-modifiable options can be created with the option directive which takes a variable to associate the value with, a description string, and a default value (OFF is the default):

Dependencies are generally found using the find_package directive. These are backed by CMake modules---either built-in or found in the CMAKE_MODULE_PATH---and handle the logic of searching for the libraries and headers of the particular package in various common locations.

If the search was successful, these modules typically set a variable of the form PACKAGENAME_FOUND which can be tested. Further, they also set variables such as PACKAGENAME_LIBRARIES and PACKAGENAME_INCLUDE_DIRS, which are sometimes singular and sometimes plural.

In pertinent CMake files, these variables set by the find_package module are then used to resolve any dependencies in the code. For example, required headers can be added to the set of directories searched by the compiler using the include_directories directive:

Similarly, a target can be linked with a library with the target_link_libraries directive:

Targets are essentially products of the build process: oftentimes this is either an executable or a library, static or shared. An executable can be created using the add_executable directive:

In the above, file.cpp refers to the file containing the main entry point. Likewise, a library can be created using the add_library directive:

# #Visual Studio

CMake works fine with Visual Studio but there are a few things to consider. The property for the working directory in the Debugging section should most likely be set to \$(OutDir). Likewise, the start-up project must be set manually as it's set to ALL_BUILD by default. ALL_BUILD is a project that builds all projects and correctly triggers any scripts. ZERO_CHECK is a project that runs and, if any CMake files have been changed, asks to reload Visual Studio.

Furthermore, if you're making a Windows application, you should add the WIN32 parameter to add_executable to instruct the compiler to use the WinMain entry-point and WINDOWS subsystem:

# #Resources

September 1, 2013