https://github.com/cginternals/cmake-init
Template for reliable, cross-platform C++ project setup using cmake.
https://github.com/cginternals/cmake-init
c-plus-plus c-plus-plus-11 cmake template
Last synced: about 2 months ago
JSON representation
Template for reliable, cross-platform C++ project setup using cmake.
- Host: GitHub
- URL: https://github.com/cginternals/cmake-init
- Owner: cginternals
- License: mit
- Created: 2014-01-16T15:19:15.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2025-04-11T16:23:07.000Z (3 months ago)
- Last Synced: 2025-04-12T08:16:04.787Z (3 months ago)
- Topics: c-plus-plus, c-plus-plus-11, cmake, template
- Language: CMake
- Homepage:
- Size: 2.38 MB
- Stars: 920
- Watchers: 39
- Forks: 117
- Open Issues: 23
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Authors: AUTHORS
Awesome Lists containing this project
README
The C++ CMake Project Template
[](https://travis-ci.org/cginternals/cmake-init)
[](https://ci.appveyor.com/project/scheibel/cmake-init/branch/master)
[](https://github.com/Aaronepower/tokei)
[](https://github.com/cginternals/cmake-init/wiki/Setup-Guide)*cmake-init* is a sophisticated copy & paste template for modern C and C++ projects.
The main goals include support of all use cases around software development (programming, testing, Q&A, deployment, documentation) while being modular, flexible, and idiomatic. *cmake-init* is therefore a collection of cmake best-practices.The main target platforms are typical desktop, laptop, and server platforms. Currently supported are:
* Windows
* macOS
* GNU/LinuxHowever, other UNIX versions may work as well if they are supported by CMake.
The cmake-init template assumes you want to setup a project using
* CMake (3.20 or above)
* C/C++ compiler# Contents
* [Usage](#usage)
* [Adaption Guide](#adaption-guide)
* [Non-Goals](#non-goals)
* [Module Documentation](#module-documentation)
* [Core Modules](#core-modules)
* [CMake Initialization](#cmake-initialization)
* [CMake Backward Compatibility](#cmake-backward-compatability)
* [Project Meta Information](#project-meta-information)
* [Project Meta Information Code Generation](#project-meta-information-code-generation)
* [Project Build Options](#project-build-options)
* [Maintainer Modules](#maintainer-modules)
* [cmake-init Template Check](#cmake-init-template-check)
* [Development Modules](#development-modules)
* [Version Control System Integration](#version-control-system-integration)
* [Build Targets](#build-targets)
* [Documentation](#documentation)
* [Tests](#tests)
* [Linter](#linter)
* [Continuous Integration](#continuous-integration)
* [Deployment](#deployment)
* [Packaging](#packaging)
* [Run-time Assets](#run-time-assets)# Usage
The intended use of the template is a copy of the current version with a subsequent replacement of project names and customization of modules to your needs. This is documented within the [adaption guide](#adaption-guide).
Another approach is the initialization of a new CMake project where the required features are adopted from cmake-init. We propose the former workflow.Concluding, a new project should contain the core modules and, as needed, add the maintainer and development modules as required. All modules are designed in a way that they can be excluded. The process of integration or removal of a module/feature is documented with each module.
## Adaption Guide
The file [ADAPT.md](https://github.com/cginternals/cmake-init/blob/master/ADAPT.md) contains a task checklist for new projects. Your start with a copy of cmake-init and process each item from the checklist, adjusting the template to your needs.
## Update
After some time working on a project, cmake-init may be updated and you want to integrate the changes.
For an overview of changes we suggest to use the [cmake-init Template Check](#cmake-init-template-check) module.
Alternatively, you can update the required modules selectively.# Non-Goals
In order to be usable in a deterministic, idiomatic fashion, cmake-init avoids the following approaches and features:
## Super-Build
Due to the current semantics of targets and CMake internals, combining multiple
cmake-init projects into one super-build project is not officially supported.
There are limited and restricting workarounds.
Actual solution: treat each project separately and use explicit dependency management.## High Abstraction
We use low abstractions to not build a language upon CMake a user has to learn.
## File Glob
Explicit source specification prevents erroneous cases when adding and removing
sources from the project tree.# Module Documentation
## Core Modules
### CMake Initialization
As with most CMake projects, cmake-init initializes the CMake environment. This includes the minimum required CMake version,
```cmake
# CMake version
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
```required policies,
```cmake
# Set policies
set_policy(CMP0054 NEW) # ENABLE CMP0054: Only interpret if() arguments as variables or keywords when unquoted.
set_policy(CMP0042 NEW) # ENABLE CMP0042: MACOSX_RPATH is enabled by default.
set_policy(CMP0063 NEW) # ENABLE CMP0063: Honor visibility properties for all target types.
```adaption of the cmake module path,
```cmake
# Include cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
```and an include of default modules that are typically required for each project.
```cpp
include(GenerateExportHeader)
include(WriteCompilerDetectionHeader)
```### Project Meta Information
The declaration of project-wide information--that are used, e.g., within documentation, testing, and deployment--, is combined within the project meta information section in the main `CMakeLists.txt`.
```cmake
#
# Project description and (meta) information
## Meta information about the project
set(META_PROJECT_NAME "template")
set(META_PROJECT_DESCRIPTION "CMake Project Template")
set(META_AUTHOR_ORGANIZATION "CG Internals GmbH")
set(META_AUTHOR_DOMAIN "https://github.com/cginternals/cmake-init/")
set(META_AUTHOR_MAINTAINER "[email protected]")
set(META_VERSION_MAJOR "2")
set(META_VERSION_MINOR "0")
set(META_VERSION_PATCH "0")
set(META_VERSION_REVISION "")
set(META_VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
set(META_NAME_VERSION "${META_PROJECT_NAME} v${META_VERSION} (${META_VERSION_REVISION})")
set(META_CMAKE_INIT_SHA "")string(MAKE_C_IDENTIFIER ${META_PROJECT_NAME} META_PROJECT_ID)
string(TOUPPER ${META_PROJECT_ID} META_PROJECT_ID)
```*cmake-init* supports the projects name, description, organization, domain, and maintainer email as well as detailed version information. For the version, we suggest to use [semantic versioning](https://semver.org/).
Depending on your version control system, you may want to integrate the current revision of the software as well: see [Version Control System Integration](#version-control-system-integration). If you use the [cmake-init Template Check](#cmake-init-template-check) module, the cmake-init SHA is declared within this section, too.Last, *cmake-init* derives a project ID that complies with the naming schemes of C to be used within auto-generated and derived source code content (e.g., macro identifiers).
### Project Meta Information Code Generation
The result of this module is the generation of a C header file that propagates the project meta information to your C and C++ projects.
For this, the CMake file configuration feature is used on the `version.h.in` header template.```c
#define @META_PROJECT_ID@_PROJECT_NAME "@META_PROJECT_NAME@"
#define @META_PROJECT_ID@_PROJECT_DESCRIPTION "@META_PROJECT_DESCRIPTION@"#define @META_PROJECT_ID@_AUTHOR_ORGANIZATION "@META_AUTHOR_ORGANIZATION@"
#define @META_PROJECT_ID@_AUTHOR_DOMAIN "@META_AUTHOR_DOMAIN@"
#define @META_PROJECT_ID@_AUTHOR_MAINTAINER "@META_AUTHOR_MAINTAINER@"#define @META_PROJECT_ID@_VERSION_MAJOR "@META_VERSION_MAJOR@"
#define @META_PROJECT_ID@_VERSION_MINOR "@META_VERSION_MINOR@"
#define @META_PROJECT_ID@_VERSION_PATCH "@META_VERSION_PATCH@"
#define @META_PROJECT_ID@_VERSION_REVISION "@META_VERSION_REVISION@"#define @META_PROJECT_ID@_VERSION "@META_VERSION@"
#define @META_PROJECT_ID@_NAME_VERSION "@META_NAME_VERSION@"
```The template file is configured with the project meta information and the result is stored within the build directory. Beware that this header is stored in a path derived from your project name. You should adopt this as required.
```cmake
# Generate version-header
configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/${META_PROJECT_NAME}/${META_PROJECT_NAME}-version.h)
```We suggest to deploy this header disregarding its internal or even public use.
```cmake
#
# Deployment
## Deploy generated headers
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/${META_PROJECT_NAME} DESTINATION include COMPONENT dev)
```### Project Build Options
## Maintainer Modules
### cmake-init Template Check
This module allows to check the actuality of the used cmake-init template for own projects.
This module is usable when the following is integrated into the `CMakeLists.txt`.```cmake
# Add cmake-init template check cmake targets
add_check_template_target( )
```Here, the `` contains the git hash of the used cmake-init template.
Further, the files `cmake/HealthCheck.cmake` and `cmake/CheckTemplate.cmake` are required.The hash is usually configured using
```cmake
# Meta information about the project
set(META_CMAKE_INIT_SHA "")
set(META_CMAKE_INIT_BRANCH "")# Add cmake-init template check cmake targets
add_check_template_target( )
```Correctly configures, this module adds a cmake build target named `check-template` that compares the passed `` with the current master commit hash of this repository and provides a link for a diff view.
## Development Modules
### Version Control System Integration
```cmake
# Get git revision
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
string(SUBSTRING "${GIT_SHA1}" 0 12 GIT_REV)
if(NOT GIT_SHA1)
set(GIT_REV "0")
endif()
```### Build Targets
### Documentation
### Tests
Tests are available using the Google testing frameworks `googletest` and `googlemock`.
cmake-init assumes an external installment of both frameworks.
Typically, package managers of each system provides a sufficient installment.
For example, on Ubuntu you can install the `libgmock-dev` package.
On macOS using Homebrew, this package is named `googletest### Linter
### Continuous Integration
### Deployment
### Packaging
### Run-time Assets