Help/dev/source.rst
CMake Source Code Guide
The following is a guide to the CMake source code for developers.
See documentation on CMake Development_ for more information.
.. _CMake Development: README.rst
We use clang-format_ version 18 to define our style for C++ code in
the CMake source tree. See the .clang-format_ configuration file for our
style settings. Use the Utilities/Scripts/clang-format.bash_ script to
format source code. It automatically runs clang-format on the set of
source files for which we enforce style. The script also has options to
format only a subset of files, such as those that are locally modified.
.. _clang-format: https://clang.llvm.org/docs/ClangFormat.html
.. _.clang-format: ../../.clang-format
.. _Utilities/Scripts/clang-format.bash: ../../Utilities/Scripts/clang-format.bash
In addition, we have a few coding conventions that we prefer for new code to follow (which are not enforced by other tooling):
Name local variables using camelCase.
Name class members and free functions using PascalCase.
Reference class members using this->Member.
Use east const style, e.g., int const instead of const int.
Declare variables using a locally-specified type:
.. code-block:: c++
T x = f();
Use auto only if the real type explicitly appears in the initializer:
.. code-block:: c++
auto y = cm::make_unique<T>(); auto z = -> T {...}();
Exceptions:
Iterators: auto i = myMap.find(myKey);
Lambdas: auto f = []() {...};
CMake requires compiling as C++11 in order to support building on older
toolchains. However, to facilitate development, some standard library
features from more recent C++ standards are supported through a compatibility
layer. These features are defined under the namespace cm and headers
are accessible under the cm/ directory. The headers under cm/ can
be used in place of the standard ones when extended features are needed.
For example <cm/memory> can be used in place of <memory>.
The class cm::filesystem::path, from the <cm/filesystem> header, is
fully compatible with the class std::filesystem::path regarding the API but
is a specific implementation (derived from the std::filesystem::path class)
to ensure a behavior independent of the current locale.
Available features are:
From C++14:
<cm/array>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/deque>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/forward_list>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/iomanip>:
cm::quoted
<cm/iterator>:
cm::make_reverse_iterator, cm::cbegin, cm::cend,
cm::rbegin, cm::rend, cm::crbegin, cm::crend
<cm/list>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/map>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/memory>:
cm::make_unique
<cm/set>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/string>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/string_view>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/shared_mutex>:
cm::shared_lock
<cm/type_traits>:
cm::conditional_t, cm::decay_t, cm::enable_if_t,
cm::remove_cv_t, cm::remove_reference_t
<cm/unordered_map>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/unordered_set>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
<cm/vector>:
cm::cbegin, cm::cend, cm::rbegin, cm::rend,
cm::crbegin, cm::crend
From C++17:
<cm/algorithm>:
cm::clamp
<cm/array>:
cm::size, cm::empty, cm::data
<cm/deque>:
cm::size, cm::empty, cm::data
cm/filesystem>:
cm::filesystem::path
<cm/forward_list>:
cm::size, cm::empty, cm::data
<cm/iterator>:
cm::size, cm::empty, cm::data
<cm/list>:
cm::size, cm::empty, cm::data
<cm/map>:
cm::size, cm::empty, cm::data
<cm/optional>:
cm::nullopt_t, cm::nullopt, cm::optional,
cm::make_optional, cm::bad_optional_access
<cm/set>:
cm::size, cm::empty, cm::data
<cm/shared_mutex>:
cm::shared_mutex
<cm/string>:
cm::size, cm::empty, cm::data
<cm/string_view>:
cm::string_view, cm::size, cm::empty, cm::data
<cm/type_traits>:
cm::bool_constant, cm::invoke_result_t, cm::invoke_result,
cm::is_same_v, cm::void_t
<cm/unordered_map>:
cm::size, cm::empty, cm::data
<cm/unordered_set>:
cm::size, cm::empty, cm::data
<cm/utility>:
cm::in_place_t, cm::in_place
<cm/vector>:
cm::size, cm::empty, cm::data
From C++20:
<cm/array>:
cm::ssize
<cm/deque>:
cm::erase, cm::erase_if, cm::ssize
<cm/forward_list>:
cm::ssize
<cm/iterator>:
cm::ssize
<cm/list>:
cm::erase, cm::erase_if, cm::ssize
<cm/map> :
cm::erase_if, cm::ssize
<cm/set> :
cm::erase_if, cm::ssize
<cm/string_view>:
cm::ssize
<cm/string>:
cm::erase, cm::erase_if, cm::ssize
<cm/unordered_map>:
cm::erase_if, cm::ssize
<cm/unordered_set>:
cm::erase_if, cm::ssize
<cm/vector>:
cm::erase, cm::erase_if, cm::ssize
From C++23:
<cm/type_traits>:
cm::is_scoped_enumAdditionally, some useful non-standard extensions to the C++ standard library
are available in headers under the directory cmext/ in namespace cm.
These are:
<cmext/algorithm>:
cm::append:
Append elements to a sequential container.
cm::contains:
Checks if element or key is contained in container.
<cmext/enum_set>
cm::enum_set:
Container to manage set of elements from an enum class definition.<cmext/iterator>:
cm::is_iterator:
Checks if a type is an iterator type.
cm::is_input_iterator:
Checks if a type is an input iterator type.
cm::is_range:
Checks if a type is a range type: functions std::begin() and
std::end() apply.
cm::is_input_range:
Checks if a type is an input range type: functions std::begin() and
std::end() apply and return an input iterator.
<cmext/memory>:
cm::static_reference_cast:
Apply a static_cast to a smart pointer.
cm::dynamic_reference_cast:
Apply a dynamic_cast to a smart pointer.
<cmext/type_traits>:
cm::is_container:
Checks if a type is a container type.
cm::is_associative_container:
Checks if a type is an associative container type.
cm::is_unordered_associative_container:
Checks if a type is an unordered associative container type.
cm::is_sequence_container:
Checks if a type is a sequence container type.
cm::is_unique_ptr:
Checks if a type is a std::unique_ptr type.
cm::remove_member_pointer
Produces the underlying type of a member-pointer type, ie, given T C::*,
returns T.
cm::member_pointer_class
Produces the class associated with a member-pointer type, ie, given
T C::*, returns C.
CMake assumes the compiler supports #pragma once. Use this for all
hand-written header files.
To ensure efficient memory management, i.e. no memory leaks, it is required
to use smart pointers. Any dynamic memory allocation must be handled by a
smart pointer such as std::unique_ptr or std::shared_ptr.
It is allowed to pass raw pointers between objects to enable objects sharing. A raw pointer must not be deleted. Only the object(s) owning the smart pointer are allowed to delete dynamically allocated memory.
To build CMake, some third parties are needed. Under Utilities
directory, are versions of these third parties which can be used as an
alternate to the ones provided by the system.
To enable the selection of the third parties between the system and CMake ones,
in CMake sources, third parties headers must be prefixed by cm3p/
(for example: <cm3p/json/reader.h>). These wrappers are located under
Utilities/cm3p directory.
The CMake source tree is organized as follows.
Auxiliary/:
Shell and editor integration files.
Help/:
Documentation. See the CMake Documentation Guide_.
Help/dev/:
Developer documentation.
Help/release/dev/:
Release note snippets for development since last release.
Licenses/:
License files for third-party libraries in binary distributions.
Modules/:
CMake language modules installed with CMake.
Packaging/:
Files used for packaging CMake itself for distribution.
Source/:
Source code of CMake itself.
Templates/:
Files distributed with CMake as implementation details for generators,
packagers, etc.
Tests/:
The test suite. See Tests/README.rst.
To run the tests, see the CMake Testing Guide.
Utilities/:
Scripts, third-party source code.
Utilities/std/cm:
Support files for various C++ standards.
Utilities/std/cmext:
Extensions to the C++ STL.
Utilities/cm3p:
Public headers for third parties needed to build CMake.
Utilities/Sphinx/:
Sphinx configuration to build CMake user documentation.
Utilities/Release/:
Scripts used to package CMake itself for distribution on cmake.org.
See Utilities/Release/README.rst_.
.. _CMake Documentation Guide: documentation.rst
.. _CMake Testing Guide: testing.rst
.. _Tests/README.rst: ../../Tests/README.rst
.. _Utilities/Release/README.rst: ../../Utilities/Release/README.rst