diff options
Diffstat (limited to 'Help/dev/source.rst')
-rw-r--r-- | Help/dev/source.rst | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/Help/dev/source.rst b/Help/dev/source.rst new file mode 100644 index 0000000..68ca743 --- /dev/null +++ b/Help/dev/source.rst @@ -0,0 +1,335 @@ +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 + +C++ Code Style +============== + +We use `clang-format`_ version **15** 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`: http://clang.llvm.org/docs/ClangFormat.html +.. _`.clang-format`: ../../.clang-format +.. _`Utilities/Scripts/clang-format.bash`: ../../Utilities/Scripts/clang-format.bash + +C++ Subset Permitted +==================== + +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>``. + +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::enable_if_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::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`` + +Additionally, 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_terator``: + 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. + +CMake assumes the compiler supports ``#pragma once``. Use this for all +hand-written header files. + +Dynamic Memory Management +========================= + +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. + +Third Parties +============= + +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. + +Source Tree Layout +================== + +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`_. + +* ``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 +.. _`Tests/README.rst`: ../../Tests/README.rst +.. _`Utilities/Release/README.rst`: ../../Utilities/Release/README.rst |