This template uses modern tools to organize and test a big C++ project.
- Organized
The organisational power of CMake and Git submodul allows for a improved folder structure. Dozens of headers cluttering the include folder can be a thing of the past. - Multi-platform (Linux, Windows, Darwin)
Supporting multiple operation systems causes issues such as preprocessor directives cluttering up your code. This template uses a way to reduce such preprocessor directives (Cpp-FileSystem-Emulator) using CMake. - Continuous integration (Travis CI, Circle CI)
Testing on ones own machine is an insufficient way testing code meant for multiple platforms. Even Continuous Integration sites, like Circle CI, often only support a limited selection of platforms.
Because of that Travis CI is recommend, which provides images for Linux, OSX and Windows. - Unittests (Catch2)
All modules include unittests using Catch2. The Catch2 source is not included in this repository, but is cloned from the remote repository when the unittests are build.
Much of the template structure and other parts are from ideas gained from guides
and code bits and pieces from https://stackoverflow.com/.
Notable influences are:
- Guides
- It's Time To Do CMake Right by Pablo Arias
- Effective Modern CMake by Manuel Binna
- Travis CI
This template is by no means perfect or even finished and will expand and improve.
Cpp-Mega-Project
├── CMakeLists.txt
├── include
│ ├── project.h
│ ├── Cpp-Template-Sub1
│ │ └── include
│ │ │── project.h
│ │ └── Cpp-Template-Sub1-Sub
│ │ └── ...
│ └── Cpp-FileSystem-Emulator
├── src
│ └── project.cpp
├── libs
├── external
│ ├── CMakeLists.txt
│ └── catch2
│ └── catch.hpp
└── tests
├── CMakeLists.txt
└── test_project.cpp
- include/
- Header location of current module.
- include / Cpp-Template-Sub1
- Submodule of this module.
- Not a third party project and considered part of this build, it is included in the 'include' folder, not the 'external' folder.
- include / Cpp-FileSystem-Emulator
- Submodule of this module.
- Part of this project, but is also its own project and it is debatable if it should be in external or include folder.
- libs
- Location of libraries made by the submodules.
- src
- Source files of current module.
- external
- External projects that are not developed as part of this project.
- tests
- Unittest files of current module.
- catch2
- External project for unittests.
- Catch2 will be downloaded as part of CMake when run on unittests.
- .travis.yml
- Configuration file for Travis CI support.
- .circleci/config.yml
- Configuration file for Circle CI support.
Git submodule is an integral part of this template.
It is possible to use CMake's 'ExternalProject' instead, see 'CMakeLists.txt' in the 'external' folder for an example.
Git submodule has been chosen, as fewer maintenance is expected than from a CMake script.
Use https urls for submodules, the ssh alternative requires a key, which will not exist on the continuous integration platform.
git submodule add https://github.com/p-hofmann/submodule.git include/submodule
git mv include/submodule include/submoduleNew
rm -rf include/submodule
git submodule deinit -f -- include/submodule
rm -rf .git/modules/include/submodule
git rm -f include/submodule
After a project is cloned, the submodules are still empty. Those are cloned int the sub-folders with this command:
git submodule update --init --recursive
git submodule update --remote --recursive --merge
After this, submodules must be added and committed
Working on submodules from a parent project can lead to very bad things happening. A forgotten submodule update can easily lead to a detached head and a lot of headaches. If I could make them read-only except for updates, I would. If working on submodules is wanted, 'git subtree' is worth looking into.
- Continuous Integration
- Use of valgrind in Windows OS setup.
- Make sure normal library is build in addition to Unittests from source.
- Maybe use linked library in unittests instead of source.
- Find or make images of different architectures for each OS.
- CMake
- 'Install library' configuration example.
- Prevention of loading a sub project twice (like done with Catch2).
- Consider a 'CMakeLists.txt' in 'src', dealing only with the current project.
- Git
- Modify template to also work with private git repositories.
- Add example of SSH instead of Https url to repositories
- Look into 'git subtree'