dwww Home | Manual pages | Find package

ECM-DEVELOPER(7)              Extra CMake Modules             ECM-DEVELOPER(7)

NAME
       ecm-developer - ECM Developer Reference

WRITING MODULES
       The  CMake 3 documentation (and cmake-developer(7) in particular) has a
       lot of useful information about  writing  CMake  modules,  including  a
       large  section  devoted to find modules. This guide will only highlight
       things that are particular to the Extra CMake Modules project.

       Most of these are stylistic points. For example, the license header for
       a module in ECM should look like:

          # SPDX-FileCopyrightText: 20XX Your Name <your.email@example.com>
          #
          # SPDX-License-Identifier: BSD-3-Clause

       Documentation  is  written  in reStructuredText format and put inside a
       bracket comment with a .rst: id after the opening bracket:

          #[=======================================================================[.rst:
          The docs
          #]=======================================================================]

       (docs/sphinx/ext/ecm.py has code to extract the rst text from a comment
       with such wrapping)

       Functions  should be used instead of macros unless there is a good rea-
       son not to (and that reason should be noted in a comment),  and  lower-
       case should be used for macros, functions and commands.

       4  spaces  is the generally-recommended indent, although there are sev-
       eral files that use 2 spaces; consistency within a file is more  impor-
       tant than consistency across files.

       If in doubt, look at how other modules in Extra CMake Modules are writ-
       ten, and follow the same pattern.

   Find Modules
       A good template for find module documentation is:

          #[=======================================================================[.rst:
          FindFoo
          -------

          Finds the Foo library.

          This will define the following variables:

          ``Foo_FOUND``
              True if (the requested version of) Foo is available
          ``Foo_VERSION``
              The version of Foo, if it is found
          ``Foo_LIBRARIES``
              This can be passed to target_link_libraries() instead of the ``Foo::Foo``
              target
          ``Foo_INCLUDE_DIRS``
              This should be passed to target_include_directories() if the target is not
              used for linking
          ``Foo_DEFINITIONS``
              This should be passed to target_compile_options() if the target is not
              used for linking

          If ``Foo_FOUND`` is TRUE, it will also define the following imported target:

          ``Foo::Foo``
              The Foo library

          In general we recommend using the imported target, as it is easier to use.
          Bear in mind, however, that if the target is in the link interface of an
          exported library, it must be made available by the package config file.
          #]=======================================================================]

       Note the use of definition lists for the variables.

       Because of the ECMUseFindModules module, projects may easily make local
       copies  of  find  modules,  and may install those copies with their own
       CMake project config files. For this reason, find  modules  should  in-
       clude the full BSD 3-clause license:

          #=============================================================================
          # Copyright 20XX Your Name <your.email@example.com>
          #
          # Redistribution and use in source and binary forms, with or without
          # modification, are permitted provided that the following conditions
          # are met:
          #
          # 1. Redistributions of source code must retain the copyright
          #    notice, this list of conditions and the following disclaimer.
          # 2. Redistributions in binary form must reproduce the copyright
          #    notice, this list of conditions and the following disclaimer in the
          #    documentation and/or other materials provided with the distribution.
          # 3. The name of the author may not be used to endorse or promote products
          #    derived from this software without specific prior written permission.
          #
          # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
          # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
          # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
          # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
          # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
          # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
          # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
          # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
          # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
          #=============================================================================

       Find  modules should always provide imported targets in addition to the
       traditional variables (like Foo_LIBRARIES, etc).

       Unlike find modules shipped with CMake, if the module requires  a  spe-
       cific  CMake version it is not enough to warn when the minimum required
       version is not high enough: you should also produce an error  when  the
       actual  CMake  version  being used is not high enough. This can be done
       with:

          if(CMAKE_VERSION VERSION_LESS 3.16.0)
              message(FATAL_ERROR "CMake 3.16.0 is required by FindFoo.cmake")
          endif()
          if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.16.0)
              message(AUTHOR_WARNING "Your project should require at least CMake 3.16.0 to use FindFoo.cmake")
          endif()

       The  ECMFindModuleHelpers  module  has  several  useful  functions  and
       macros.  For  example, it allows you to replace the above version check
       with:

          ecm_find_package_version_check(Foo)

   Components
       Using ECMFindModuleHelpers, creating a find module for a  library  with
       several inter-dependent components is reasonably straightforward. After
       the documentation, you need to include the module and do the usual ver-
       sion check:

          include(ECMFindModuleHelpers)
          ecm_find_package_version_check(Foo)

       The   important   macros   are   ecm_find_package_parse_components  and
       ecm_find_package_handle_library_components.  These take a list of  com-
       ponents, and query other variables you provide to find out the informa-
       tion they require.  The documentation for ECMFindModuleHelpers provides
       more information, but a simple setup might look like:

          set(Foo_known_components Bar Baz)
          set(Foo_Bar_pkg_config "foo-bar")
          set(Foo_Bar_lib "bar")
          set(Foo_Bar_header "foo/bar.h")
          set(Foo_Bar_pkg_config "foo-baz")
          set(Foo_Baz_lib "baz")
          set(Foo_Baz_header "foo/baz.h")

       If Baz depends on Bar, for example, you can specify this with

          set(Foo_Baz_component_deps "Bar")

       Then call the macros:

          ecm_find_package_parse_components(Foo
              RESULT_VAR Foo_components
              KNOWN_COMPONENTS ${Foo_known_components}
          )
          ecm_find_package_handle_library_components(Foo
              COMPONENTS ${Foo_components}
          )

       Of  course,  if  your components need unusual handling, you may want to
       replace ecm_find_package_handle_library_components with, for example, a
       foreach  loop  over  the components (the body of which should implement
       most of what a normal find module does, including  setting  Foo_<compo-
       nent>_FOUND).

       At  this  point,  you should set Foo_VERSION using whatever information
       you have available (such as from  parsing  header  files).   Note  that
       ecm_find_package_handle_library_components  will  set it to the version
       reported by pkg-config of the first component found, but  this  depends
       on the presence of pkg-config files, and the version of a component may
       not be the same as the version of the whole package.  After that,  fin-
       ish off with

          include(FindPackageHandleStandardArgs)
          find_package_handle_standard_args(Foo
              FOUND_VAR
                  Foo_FOUND
              REQUIRED_VARS
                  Foo_LIBRARIES
              VERSION_VAR
                  Foo_VERSION
              HANDLE_COMPONENTS
          )

          include(FeatureSummary)
          set_package_properties(Foo PROPERTIES
              URL "https://www.foo.example.com/"
              DESCRIPTION "A library for doing useful things")

SUBMITTING MODULES
       Proposed new modules should be submitted using the KDE Review Board in-
       stance, and  be  assigned  to  the  buildsystem  and  extracmakemodules
       groups.  You should be able to point to two separate projects that will
       make use of the module.

       The       mailing       list       can        be        found        at
       https://mail.kde.org/mailman/listinfo/kde-buildsystem.

COPYRIGHT
       KDE Developers

5.103                            Feb 12, 2023                 ECM-DEVELOPER(7)

Generated by dwww version 1.15 on Sat Jun 29 01:59:28 CEST 2024.