Warning, /frameworks/extra-cmake-modules/docs/manual/ecm-developer.7.rst is written in an unsupported language. File is not indexed.

0001 .. ecm-manual-description: ECM Developer Reference
0002 
0003 ecm-developer(7)
0004 ****************
0005 
0006 .. only:: html or latex
0007 
0008    .. contents::
0009 
0010 
0011 Writing Modules
0012 ===============
0013 
0014 The CMake 3 documentation (and `cmake-developer(7)`_ in particular) has a lot of
0015 useful information about writing CMake modules, including a large section
0016 devoted to find modules. This guide will only highlight things that are
0017 particular to the Extra CMake Modules project.
0018 
0019 Most of these are stylistic points. For example, the license header for a module
0020 in ECM should look like:
0021 
0022 .. code-block:: cmake
0023 
0024   # SPDX-FileCopyrightText: 20XX Your Name <your.email@example.com>
0025   #
0026   # SPDX-License-Identifier: BSD-3-Clause
0027 
0028 Documentation is written in reStructuredText format and put inside a bracket
0029 comment with a ``.rst:`` id after the opening bracket:
0030 
0031 .. code-block:: cmake
0032 
0033   #[=======================================================================[.rst:
0034   The docs
0035   #]=======================================================================]
0036 
0037 (docs/sphinx/ext/ecm.py has code to extract the rst text from a comment with
0038 such wrapping)
0039 
0040 Functions should be used instead of macros unless there is a good reason not to
0041 (and that reason should be noted in a comment), and lowercase should be used for
0042 macros, functions and commands.
0043 
0044 4 spaces is the generally-recommended indent, although there are several files
0045 that use 2 spaces; consistency within a file is more important than consistency
0046 across files.
0047 
0048 If in doubt, look at how other modules in Extra CMake Modules are written, and
0049 follow the same pattern.
0050 
0051 
0052 Find Modules
0053 ------------
0054 
0055 A good template for find module documentation is:
0056 
0057 .. code-block:: cmake
0058 
0059   #[=======================================================================[.rst:
0060   FindFoo
0061   -------
0062 
0063   Finds the Foo library.
0064 
0065   This will define the following variables:
0066 
0067   ``Foo_FOUND``
0068       True if (the requested version of) Foo is available
0069   ``Foo_VERSION``
0070       The version of Foo, if it is found
0071   ``Foo_LIBRARIES``
0072       This can be passed to target_link_libraries() instead of the ``Foo::Foo``
0073       target
0074   ``Foo_INCLUDE_DIRS``
0075       This should be passed to target_include_directories() if the target is not
0076       used for linking
0077   ``Foo_DEFINITIONS``
0078       This should be passed to target_compile_options() if the target is not
0079       used for linking
0080 
0081   If ``Foo_FOUND`` is TRUE, it will also define the following imported target:
0082 
0083   ``Foo::Foo``
0084       The Foo library
0085 
0086   In general we recommend using the imported target, as it is easier to use.
0087   Bear in mind, however, that if the target is in the link interface of an
0088   exported library, it must be made available by the package config file.
0089   #]=======================================================================]
0090 
0091 Note the use of definition lists for the variables.
0092 
0093 Because of the :module:`ECMUseFindModules` module, projects may easily make
0094 local copies of find modules, and may install those copies with their own CMake
0095 project config files. For this reason, find modules should include the full BSD
0096 3-clause license::
0097 
0098   #=============================================================================
0099   # Copyright 20XX Your Name <your.email@example.com>
0100   #
0101   # Redistribution and use in source and binary forms, with or without
0102   # modification, are permitted provided that the following conditions
0103   # are met:
0104   #
0105   # 1. Redistributions of source code must retain the copyright
0106   #    notice, this list of conditions and the following disclaimer.
0107   # 2. Redistributions in binary form must reproduce the copyright
0108   #    notice, this list of conditions and the following disclaimer in the
0109   #    documentation and/or other materials provided with the distribution.
0110   # 3. The name of the author may not be used to endorse or promote products
0111   #    derived from this software without specific prior written permission.
0112   #
0113   # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0114   # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0115   # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0116   # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0117   # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0118   # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0119   # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0120   # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0121   # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0122   # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0123   #=============================================================================
0124 
0125 Find modules should always provide imported targets in addition to the
0126 traditional variables (like ``Foo_LIBRARIES``, etc).
0127 
0128 Unlike find modules shipped with CMake, if the module requires a specific CMake
0129 version it is not enough to warn when the minimum required version is not high
0130 enough: you should also produce an error when the actual CMake version being
0131 used is not high enough. This can be done with:
0132 
0133 .. code-block:: cmake
0134 
0135   if(CMAKE_VERSION VERSION_LESS 3.16.0)
0136       message(FATAL_ERROR "CMake 3.16.0 is required by FindFoo.cmake")
0137   endif()
0138   if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.16.0)
0139       message(AUTHOR_WARNING "Your project should require at least CMake 3.16.0 to use FindFoo.cmake")
0140   endif()
0141 
0142 The :module:`ECMFindModuleHelpers` module has several useful functions and
0143 macros. For example, it allows you to replace the above version check with:
0144 
0145 .. code-block:: cmake
0146 
0147   ecm_find_package_version_check(Foo)
0148 
0149 Components
0150 ~~~~~~~~~~
0151 
0152 Using :module:`ECMFindModuleHelpers`, creating a find module for a library with
0153 several inter-dependent components is reasonably straightforward. After the
0154 documentation, you need to include the module and do the usual version check:
0155 
0156 .. code-block:: cmake
0157 
0158   include(ECMFindModuleHelpers)
0159   ecm_find_package_version_check(Foo)
0160 
0161 The important macros are ``ecm_find_package_parse_components`` and
0162 ``ecm_find_package_handle_library_components``.  These take a list of
0163 components, and query other variables you provide to find out the information
0164 they require.  The documentation for :module:`ECMFindModuleHelpers` provides
0165 more information, but a simple setup might look like:
0166 
0167 .. code-block:: cmake
0168 
0169   set(Foo_known_components Bar Baz)
0170   set(Foo_Bar_pkg_config "foo-bar")
0171   set(Foo_Bar_lib "bar")
0172   set(Foo_Bar_header "foo/bar.h")
0173   set(Foo_Bar_pkg_config "foo-baz")
0174   set(Foo_Baz_lib "baz")
0175   set(Foo_Baz_header "foo/baz.h")
0176 
0177 If ``Baz`` depends on ``Bar``, for example, you can specify this with
0178 
0179 .. code-block:: cmake
0180 
0181   set(Foo_Baz_component_deps "Bar")
0182 
0183 Then call the macros:
0184 
0185 .. code-block:: cmake
0186 
0187   ecm_find_package_parse_components(Foo
0188       RESULT_VAR Foo_components
0189       KNOWN_COMPONENTS ${Foo_known_components}
0190   )
0191   ecm_find_package_handle_library_components(Foo
0192       COMPONENTS ${Foo_components}
0193   )
0194 
0195 Of course, if your components need unusual handling, you may want to replace
0196 ``ecm_find_package_handle_library_components`` with, for example, a ``foreach``
0197 loop over the components (the body of which should implement most of what a
0198 normal find module does, including setting ``Foo_<component>_FOUND``).
0199 
0200 At this point, you should set ``Foo_VERSION`` using whatever information you
0201 have available (such as from parsing header files).  Note that
0202 ``ecm_find_package_handle_library_components`` will set it to the version
0203 reported by pkg-config of the first component found, but this depends on the
0204 presence of pkg-config files, and the version of a component may not be the same
0205 as the version of the whole package.  After that, finish off with
0206 
0207 .. code-block:: cmake
0208 
0209   include(FindPackageHandleStandardArgs)
0210   find_package_handle_standard_args(Foo
0211       FOUND_VAR
0212           Foo_FOUND
0213       REQUIRED_VARS
0214           Foo_LIBRARIES
0215       VERSION_VAR
0216           Foo_VERSION
0217       HANDLE_COMPONENTS
0218   )
0219 
0220   include(FeatureSummary)
0221   set_package_properties(Foo PROPERTIES
0222       URL "https://www.foo.example.com/"
0223       DESCRIPTION "A library for doing useful things")
0224 
0225 
0226 Submitting Modules
0227 ==================
0228 
0229 Proposed new modules should be submitted using the `KDE Review Board instance`_,
0230 and be assigned to the ``buildsystem`` and ``extracmakemodules`` groups.  You
0231 should be able to point to two separate projects that will make use of the
0232 module.
0233 
0234 The mailing list can be found at
0235 https://mail.kde.org/mailman/listinfo/kde-buildsystem\ .
0236 
0237 
0238 .. _KDE Review Board instance: https://git.reviewboard.kde.org/
0239 .. _cmake-developer(7): https://www.cmake.org/cmake/help/git-master/manual/cmake-developer.7.html