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