CMakeCatchTemplate was originally developed as a teaching aid for UCL’s Research Computing with C++ course, to demonstrate how a complex C++ project might be structured, and provide a starting point for student’s own projects. Subsequently, the project has been expanded upon and is now employed as a template project for a range of C++ projects within the Wellcome/EPSRC Centre for Interventional and Surgical Sciences (WEISS),12 as part of the SNAPPY library.3 By reducing the amount of boilerplate code and providing support for a range of common libraries for scientific computing, the template allows a developer to quickly prototype and release a new library.
In addition to scaffolding to provide the structure for a C++ project, particular features provided are:
In practice, most developers will only require a subset of the available features for a particular project. We envisage a range of project types that might commonly be implemented:
The template is a starting point for developers wishing to avoid some of the overheads associated with setting up a new project, but still requires input from the user to customise to their particular application, and a working knowledge of CMake to get the maximum benefit.
In addition to the combination of functionality listed above, which are not found in any single existing C++ project template,7 particular features which differentiate CMakeCatchTemplate include the ability to generate Python wheels, support for CUDA/OpenMP/MPI, and examples usage for Qt/QML applications. Further, the laborious process of manually renaming/editing files upon first creating a project, as is typically required when using other templates, is removed by the addition of the CMakeCatchTemplateRenamer8 helper script.
Features have been added over time based on feedback/requests from users, who are typically C++ developers aiming to write a small algorithm library for a particular application and get it into the hands of their users, who may not themselves be familiar with C++.
The template provides a ready-made structure for C++ projects (Figures 1 and 2). The user can build on this structure by adding their own code, primarily in Code/Lib.
Simplified file structure showing key project components.
Explanation of key directories/files.
Build options (Figure 3) can be passed to CMake depending on the external libraries required.
Build options.
Deploying cross-platform Python wheels from C++ code can be a difficult process. To help, we have been inspired and assisted by Matthew Brett’s multibuild,9 with the included travis.yml and appveyor.yml used to deploy the example code included with CMakeCatchTemplate to PyPI.10 Users can re-use, or modify these configurations as needed.
We believe that it is preferable to provide tested code that may not be needed by all users, rather than requiring the user to spend time writing potentially complex CMake. However, once a user has established a working build for their particular needs, it is possible to pare down the codebase by removing segments that will no longer be needed.
For example:
Continous Integration (CI) is used to test a range of CMake build options, and provide example use cases.
GitHub workflows are used to build/test some common configurations (Boost, OpenCV, PyBoost, PyBind, Qt) on an Ubuntu VM, which also provide a starting point for users to build their own projects. Workflows are stored in the .github/workflows directory.
A more complex example, of building a project and deploying to PyPI, is tested using Travis (Mac/Linux) and AppVeyor (Windows). Users can find more details in the .travis.yml and appveyor.yml files in the top level directory.
Further examples can be found in projects which have been derived from CMakeCatchTemplate – scikitsurgery-opencvcpp[11 and scikit-surgerypclcpp,12 which each implement new algorithms within the /Code/Lib folders, and unit tests in /Testing. Again, the Travis and AppVeyor configuration files detail an up-to-date build procedure.
The default project structure includes some rudimentary unit tests. Once built, these tests are placed in the MYPROJECT-build/bin folder. The CI examples demonstrate how to run tests. The included tests serve to illustrate the structure/framework that has been implemented. Further unit tests should be added by the user once they have added their own code to the project.
Tested locally on:
Windows - Windows 8/10, VS2013, CMake 3.6.3, Qt 5.4.2
Linux - Centos 7/Ubuntu 16, g++ 4.8.5, CMake 3.5.1, Qt 5.6.2
Mac - OSX 10.10.5, clang 6.0, CMake 3.9.4, Qt 5.6.2
Refer to CI files for details on other test environments used.
C++ 11
None
CMake > 3.5
If Qt is enabled, minimum version is Qt5.
Name: CMakeCatchTemplate
Persistent identifier: https://doi.org/10.5281/zenodo.4954783
Licence: BSD 3-clause
Publisher: Zenodo
Version published: 0.3
Date published: 15/06/2021
Name: CMakeCatchTemplate
Persistent identifier: https://github.com/MattClarkson/CMakeCatchTemplate
Licence: BSD 3-clause
Date published: 16/01/2020
Code repository: GitHub
C++/CMake
This software can be used for rapid prototyping and deployment of novel C++ algorithms amongst research users, and also for teaching environments/student projects where CMake development is beyond the scope of the course material.
While long term support is not explicitly guaranteed for this project, the authors continue to maintain the repository and will reply to any GitHub issues raised, and this is not expected to change. Further to this, the existing CI infrastructure will indicate if the software is still working as expected.
Users wishing to contribute towards the software could include additional libraries, develop new build/CI scripts for different applications, or share projects that they have made using the template.
7https://github.com/TheLartians/ModernCppStarter.
https://github.com/cginternals/cmake-init.
https://github.com/Lectem/cpp-boilerplate.
This work has been funded by Wellcome/EPSRC [203145Z/16/Z].
The authors have no competing interests to declare.