1ECM-DEVELOPER(7)              Extra CMake Modules             ECM-DEVELOPER(7)
2
3
4

NAME

6       ecm-developer - ECM Developer Reference
7

WRITING MODULES

9       The  CMake 3 documentation (and cmake-developer(7) in particular) has a
10       lot of useful information about  writing  CMake  modules,  including  a
11       large  section  devoted to find modules. This guide will only highlight
12       things that are particular to the Extra CMake Modules project.
13
14       Most of these are stylistic points. For example, the license header for
15       a module in ECM should look like:
16
17          #=============================================================================
18          # Copyright 20XX Your Name <your.email@example.com>
19          #
20          # Redistribution and use in source and binary forms, with or without
21          # modification, are permitted provided that the following conditions
22          # are met:
23          #
24          # 1. Redistributions of source code must retain the copyright
25          #    notice, this list of conditions and the following disclaimer.
26          # 2. Redistributions in binary form must reproduce the copyright
27          #    notice, this list of conditions and the following disclaimer in the
28          #    documentation and/or other materials provided with the distribution.
29          # 3. The name of the author may not be used to endorse or promote products
30          #    derived from this software without specific prior written permission.
31          #
32          # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
33          # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34          # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
35          # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
36          # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37          # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38          # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39          # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40          # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
41          # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43       Functions  should be used instead of macros unless there is a good rea‐
44       son not to (and that reason should be noted in a comment),  and  lower‐
45       case should be used for macros, functions and commands.
46
47       4  spaces  is the generally-recommended indent, although there are sev‐
48       eral files that use 2 spaces; consistency within a file is more  impor‐
49       tant than consistency across files.
50
51       If in doubt, look at how other modules in Extra CMake Modules are writ‐
52       ten, and follow the same pattern.
53
54   Find Modules
55       A good template for find module documentation is:
56
57          #.rst:
58          # FindFoo
59          # -------
60          #
61          # Finds the Foo library.
62          #
63          # This will define the following variables:
64          #
65          # ``Foo_FOUND``
66          #     True if (the requested version of) Foo is available
67          # ``Foo_VERSION``
68          #     The version of Foo, if it is found
69          # ``Foo_LIBRARIES``
70          #     This can be passed to target_link_libraries() instead of the ``Foo::Foo``
71          #     target
72          # ``Foo_INCLUDE_DIRS``
73          #     This should be passed to target_include_directories() if the target is not
74          #     used for linking
75          # ``Foo_DEFINITIONS``
76          #     This should be passed to target_compile_options() if the target is not
77          #     used for linking
78          #
79          # If ``Foo_FOUND`` is TRUE, it will also define the following imported target:
80          #
81          # ``Foo::Foo``
82          #     The Foo library
83          #
84          # In general we recommend using the imported target, as it is easier to use.
85          # Bear in mind, however, that if the target is in the link interface of an
86          # exported library, it must be made available by the package config file.
87
88       Note the use of definition lists for the variables.
89
90       Because of the ECMUseFindModules module, projects may easily make local
91       copies  of  find  modules,  and may install those copies with their own
92       CMake project config  files.  For  this  reason,  find  modules  should
93       include the full BSD 3-clause license:
94
95          #=============================================================================
96          # Copyright 20XX Your Name <your.email@example.com>
97          #
98          # Redistribution and use in source and binary forms, with or without
99          # modification, are permitted provided that the following conditions
100          # are met:
101          #
102          # 1. Redistributions of source code must retain the copyright
103          #    notice, this list of conditions and the following disclaimer.
104          # 2. Redistributions in binary form must reproduce the copyright
105          #    notice, this list of conditions and the following disclaimer in the
106          #    documentation and/or other materials provided with the distribution.
107          # 3. The name of the author may not be used to endorse or promote products
108          #    derived from this software without specific prior written permission.
109          #
110          # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
111          # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
112          # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
113          # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
114          # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
115          # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
116          # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
117          # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118          # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
119          # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120          #=============================================================================
121
122       Find  modules should always provide imported targets in addition to the
123       traditional variables (like Foo_LIBRARIES, etc).
124
125       Unlike find modules shipped with CMake, if the module requires  a  spe‐
126       cific  CMake version it is not enough to warn when the minimum required
127       version is not high enough: you should also produce an error  when  the
128       actual  CMake  version  being used is not high enough. This can be done
129       with:
130
131          if(CMAKE_VERSION VERSION_LESS 2.8.12)
132              message(FATAL_ERROR "CMake 2.8.12 is required by FindFoo.cmake")
133          endif()
134          if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
135              message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindFoo.cmake")
136          endif()
137
138       The  ECMFindModuleHelpers  module  has  several  useful  functions  and
139       macros.  For  example, it allows you to replace the above version check
140       with:
141
142          ecm_find_package_version_check(Foo)
143
144   Components
145       Using ECMFindModuleHelpers, creating a find module for a  library  with
146       several inter-dependent components is reasonably straightforward. After
147       the documentation, you need to include the module and do the usual ver‐
148       sion check:
149
150          include(ECMFindModuleHelpers)
151          ecm_find_package_version_check(Foo)
152
153       The   important   macros   are   ecm_find_package_parse_components  and
154       ecm_find_package_handle_library_components.  These take a list of  com‐
155       ponents, and query other variables you provide to find out the informa‐
156       tion they require.  The documentation for ECMFindModuleHelpers provides
157       more information, but a simple setup might look like:
158
159          set(Foo_known_components Bar Baz)
160          set(Foo_Bar_pkg_config "foo-bar")
161          set(Foo_Bar_lib "bar")
162          set(Foo_Bar_header "foo/bar.h")
163          set(Foo_Bar_pkg_config "foo-baz")
164          set(Foo_Baz_lib "baz")
165          set(Foo_Baz_header "foo/baz.h")
166
167       If Baz depends on Bar, for example, you can specify this with
168
169          set(Foo_Baz_component_deps "Bar")
170
171       Then call the macros:
172
173          ecm_find_package_parse_components(Foo
174              RESULT_VAR Foo_components
175              KNOWN_COMPONENTS ${Foo_known_components}
176          )
177          ecm_find_package_handle_library_components(Foo
178              COMPONENTS ${Foo_components}
179          )
180
181       Of  course,  if  your components need unusual handling, you may want to
182       replace ecm_find_package_handle_library_components with, for example, a
183       foreach  loop  over  the components (the body of which should implement
184       most of what a normal find module does, including  setting  Foo_<compo‐
185       nent>_FOUND).
186
187       At  this  point,  you should set Foo_VERSION using whatever information
188       you have available (such as from  parsing  header  files).   Note  that
189       ecm_find_package_handle_library_components  will  set it to the version
190       reported by pkg-config of the first component found, but  this  depends
191       on the presence of pkg-config files, and the version of a component may
192       not be the same as the version of the whole package.  After that,  fin‐
193       ish off with
194
195          include(FindPackageHandleStandardArgs)
196          find_package_handle_standard_args(Foo
197              FOUND_VAR
198                  Foo_FOUND
199              REQUIRED_VARS
200                  Foo_LIBRARIES
201              VERSION_VAR
202                  Foo_VERSION
203              HANDLE_COMPONENTS
204          )
205
206          include(FeatureSummary)
207          set_package_properties(Foo PROPERTIES
208              URL "https://www.foo.example.com/"
209              DESCRIPTION "A library for doing useful things")
210

SUBMITTING MODULES

212       Proposed  new  modules  should  be submitted using the KDE Review Board
213       instance, and be assigned  to  the  buildsystem  and  extracmakemodules
214       groups.  You should be able to point to two separate projects that will
215       make use of the module.
216
217       The       mailing       list       can        be        found        at
218       https://mail.kde.org/mailman/listinfo/kde-buildsystem.
219
221       KDE Developers
222
223
224
225
2265.68                             Mar 19, 2020                 ECM-DEVELOPER(7)
Impressum