Skip to content

josephgarnier/cmake-modules-collection

Repository files navigation

CMake Modules Collection

A collection of modules for a more practical use of CMake.

Static Badge Static Badge Static Badge Static Badge

This collection of CMake modules provides macros and functions that extend official functionality or wrap it in higher-level abstractions to make writing CMake code faster and easier. Each module is documented and tested using the unit-testing framework CMakeTest.

Features  •  Requirements  •  Module overview  •  Integration  •  Development  •  Resources  •  License

✨ Features

  • Modern CMake code.
  • Well-documented for ease of use.
  • Reliable code thanks to extensive unit testing, written using CMakeTest.
  • A coding and documentation style similar to official CMake modules.

⚓ Requirements

The following dependencies are required to execute the modules and must be installed:

  • CMake v4.0.1+ - can be found here.
  • C++ compiler (any version) - e.g., GCC v15.2+, Clang C++ v19.1.3+ or MSVC. The project is developed with the GCC compiler, and its dependencies are provided pre-compiled with GCC.

These optional dependencies are only required to contribute to this project or to run it in standalone mode:

  • Python 3.12.9+ (for doc generation).
  • Sphinx 8.2.3+ (for doc generation) - can be found here or use requirements.txt in doc/ folder.
  • Sphinx Domain for Modern CMake (for doc generation) - can be found here or use requirements.txt in doc/ folder.
  • doc8 (for doc style checking) - can be found here or use requirements.txt in doc/ folder.
  • For Visual Studio Code users, these extensions are commanded:

The following dependencies are used by the project, but already delivered with it:

💫 Module overview

Module structure

Note: Before proceeding, it is recommended to understand the difference between a function and a macro in CMake.

A module is a text file with the .cmake extension that provides a CMake command for performing various types of data manipulation within a build project.

This collection provides two types of modules, distinguished by a prefix in the filename:

  • The Function-type module, prefixed with Func, provide a single public function responsible for dispatching multiple operations, internally using private macros. Only one public command is exposed per module.
  • The Bundle-type module, prefixed with Bundle, contains a set of functions and macros designed to operate on a common object, in a way that reflects object-oriented programming. Each function defines a separate command, and a module may include multiple commands.

The general format of a module filename is <Func|Bundle><module-name>.cmake, where <module-name> uses PascalCase (also called UpperCamelCase), e.g., StringManip.

In the "public" interface of modules, CMake function() are preferred over macro() due to better encapsulation and its own variable scope.

The public function of a Function-type module follows a signature and call pattern identical to what is found in official CMake modules and commands, such as the string() command:

<command-name>(<operation-name> [<option>|<options>...] [<input-params>...] [<output-params>...])

where :

  • <command-name>: the name of the single command defined by the module, written entirely in lowercase with words separated by _, e.g. print, string_manip.
  • <operation-name>: the name of the operation to be performed by the command, written entirely in uppercase with words separated by _, e.g. SPLIT, EXTRACT_INTERFACE.
  • [<option>|<options>...]: a value, a list of values, or a variable reference passed as an argument to the command, e.g. file_manip(STRIP_PATH "path/to/file"), file_manip(STRIP_PATH MY_FILE_PATH)
  • [<input-params>...]: read-only input parameters in the form:
    • input-param ::= <constant> [<var-ref>|<value>|<values>...]: where a parameter is either a keyword or a pair combining a keyword with a value, a list of values, or a variable reference.
  • [<output-params>...]: write-only output parameters in the form:
    • output-param ::= <constant> [<var-ref>|<value>|<values>...]: where a parameter is either a keyword or a pair combining a keyword with a value, a list of values, or a variable reference.

The structure of this function signature results from the use of the CMake command cmake_parse_arguments to parse the function's arguments. The official command documentation provides further explanations on the concepts mentioned above.

Within the public function of a module, the first parameter <operation-name> acts as a dispatcher, routing the execution flow to the internal macro that implements the requested operation. Therefore, the function’s role is limited to parsing arguments, initializing scoped variables, and calling an internal macro.

Regarding module documentation, just like the code follows a style consistent with official CMake conventions, the documentation also aims to follow the CMake Documentation Guide. It is written in reStructuredText format and placed at the top of the file. The visual style replicates the official one.

Module description

Detailed module documentation is available by opening the doc/build/html/index.html file in a browser or this Website.

Name Type Description Location
Debug Function Operations for helping with debug (more details) cmake/modules/FuncDebug.cmake
Dependency Function Operations to manipule dependencies (more details) cmake/modules/FuncDependency.cmake
Directory Function Operations to manipule directories (more details) cmake/modules/FuncDirectory.cmake
FileManip Function Operations on files (more details) cmake/modules/FuncFileManip.cmake
Print Function Log a message (more details) cmake/modules/FuncPrint.cmake
StringManip Function Operations on strings (more details) cmake/modules/FuncStringManip.cmake
BinTarget Bundle Operations to fully create and configure a binary target (more details) cmake/modules/BundleBinTarget.cmake

🧩 Integration

This procedure explains how to get the collection of modules and configure a C++/CMake project to use them.

Prerequisites:

To integrate the CMake module collection into a development project using CMake and C++., follow these steps:

  1. Download the module collection using one of the following methods:

  2. If the ZIP archive was downloaded, extract its contents to any folder.

  3. Open the project's cmake folder, then copy or move the extracted modules folder into the CMake code directory of the C++/CMake project.

    Example: for a project located at <path-to-my-project>/, copy the folder to <path-to-my-project>/cmake/.

  4. (Optional) Delete the downloaded repository and extracted files if they are no longer needed.

  5. Open the CMakeLists.txt file located at the root of the C++/CMake project.

  6. Append the module path after the project(...) command:

    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/<path-to-cmake>/modules")

    where <path-to-cmake> is the relative path to the directory containing the modules.

    Example: ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules

  7. Include the required modules using the following command:

    include(<module-name>)

💻 Development

Several commands and scripts are available for the development of this project, including: build system generation and cleanup, documentation generation, test execution.

Commands are also written as Visual Studio Code tasks in .vscode/tasks.json and can be launched from the command palette. Many of them can also be run from the Visual Studio Code CMake Tools. Scripts are stored in the project root.

The use of commands and scripts is described below, they must be run from the root project directory:

  • To clean the buildsystem (remove content of build/, doc/ and bin/):

    see details
    # On Linux/MacOS
    ./clean-cmake.sh
    
    # On Windows
    clean-cmake.bat
    • VS Code task: Project: Clean.
  • To generate the buildsystem (call the cmake command):

    see details
    # On Linux/MacOS
    ./run-cmake.sh
    
    # On Windows
    run-cmake.bat
    • VS Code task: Project: Clean.
    • Note: before running it, edit the script to change the default cmake-presets.
  • To clean and generate the buildsystem:

    see details
    # On Linux/MacOS
    ./clean-cmake.sh && echo \"\" && ./run-cmake.sh
    
    # On Windows
    clean-cmake.bat && echo. && run-cmake.bat
    • VS Code task: Project: Clean and Generate.
    • Note: before running it, edit the script to change the default cmake-presets.
  • To execute the clean build phase (call the CMake target 'clean'):

    see details
    # Run the CMake target 'clean'
    cmake --build ./build/<preset-build-folder> --target clean
    • VS Code task: CMake: Clean.
  • To execute the default build phase (call the CMake target 'all'):

    see details
    # Run the CMake target 'all'
    cmake --target all --preset "<build-preset-name>"
    
    # Run the CMake target 'all' in verbose mode
    cmake --target all --verbose --preset "<build-preset-name>"
    • VS Code task: CMake: Build all.
  • To execute the clean and default build phases (call the CMake targets 'clean' then 'all'):

    see details
    # Run the CMake target 'all' after the target 'clean'
    cmake --target all --clean-first --preset "<build-preset-name>"
    
    # Run the CMake target 'all' after the target 'clean' in verbose mode
    cmake --target all --clean-first --verbose --preset "<build-preset-name>"
    • VS Code task: CMake: Clean and Rebuild all.
  • To execute the test build phases (call the CMake command 'ctest'):

    see details
    # Run the CMake command 'ctest'
    ctest --preset "<test-preset-name>"
    
    # Run the CMake command 'ctest' while displaying much more information
    ctest --preset "<test-preset-name>" --extra-verbose --debug
    • VS Code task: CMake: Test.
  • To execute the doc build phases (call the CMake target 'doc'):

    see details
    # Run the CMake target 'doc'
    cmake --build ./build/<preset-build-folder> --target doc
    • VS Code task: CMake: Doc.
    • Note: the 'doc' CMake target is included in 'all' CMake target.
  • To execute a default workflow with default, test, doc build phases:

    see details
    # Run a default CMake workflow
    cmake --workflow --preset "<workflow-preset-name>"
    • VS Code task: CMake: Workflow.
  • Some useful commands for debugging:

    see details
    # List what targets has been generated
    cmake --build ./build/<preset-build-folder> --target help
    
    # List variables in the cache and their descriptions
    cmake -LAH ./build/<preset-build-folder>
    
    # Print all available test labels without running any tests
    ctest --preset "<test-preset-name>" --extra-verbose --debug --print-labels

📚 Resources

General links:

CMake documentation:

Non-exhaustive list of other CMake module collections on GitHub:

©️ License

This work is licensed under the terms of the GNU GPLv3. See the LICENSE.md file for details.

About

A collection of extra macros and functions for CMake.

Topics

Resources

License

Stars

Watchers

Forks

Languages