diff options
| author | Alex Merry <alex.merry@kde.org> | 2014-04-20 15:08:35 +0100 | 
|---|---|---|
| committer | Alex Merry <alex.merry@kde.org> | 2014-04-20 15:08:35 +0100 | 
| commit | 3c4876ee11c9c8f024ed9ad39f18d88d59773423 (patch) | |
| tree | 3525dd381fdea50f195164b5aba333ef184ff689 | |
| parent | 038802898de36647fa02cfcaab95472b3cb45c9b (diff) | |
| download | extra-cmake-modules-3c4876ee11c9c8f024ed9ad39f18d88d59773423.tar.gz extra-cmake-modules-3c4876ee11c9c8f024ed9ad39f18d88d59773423.tar.bz2 | |
Improve the manuals
This adds an ecm-developer manual that replaces writing-find-modules.md
(a lot of which was upstreamed to CMake's own documentation). It also
adds introductory text to the ecm-*-modules manuals.
| -rw-r--r-- | README.rst | 31 | ||||
| -rw-r--r-- | docs/manual/ecm-developer.7.rst | 231 | ||||
| -rw-r--r-- | docs/manual/ecm-find-modules.7.rst | 46 | ||||
| -rw-r--r-- | docs/manual/ecm-kde-modules.7.rst | 29 | ||||
| -rw-r--r-- | docs/manual/ecm-modules.7.rst | 31 | ||||
| -rw-r--r-- | docs/writing-find-modules.md | 301 | 
6 files changed, 350 insertions, 319 deletions
| @@ -27,8 +27,9 @@ To use ECM, add the following to your ``CMakeLists.txt``:    set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})  (note that you may want to append ``${ECM_MODULE_PATH}`` to -``CMAKE_MODULE_PATH`` instead).  You can then just include the modules you -require, or use ``find_package()`` as needed.  For example: +``CMAKE_MODULE_PATH`` rather than discarding the existing value).  You can then +just include the modules you require, or use ``find_package()`` as needed.  For +example:  .. code-block:: cmake @@ -68,15 +69,11 @@ The ``${ECM_MODULE_DIR}``, ``${ECM_FIND_MODULE_DIR}`` and  ``${ECM_MODULE_PATH}`` if you only need some of this functionality. -Submitting Modules -================== +Development +=========== -Proposed new modules should be submitted using the -`KDE Review Board instance`_, and be assigned to the ``buildsystem``, -``extracmakemodules`` and ``kdeframeworks`` groups.  You should be able to point to -two separate projects that will make use of the module. - -.. _KDE Review Board instance: https://git.reviewboard.kde.org/ +The :manual:`ecm-developer(7)` manual contains more information about +developing for Extra CMake Modules.  License @@ -87,12 +84,10 @@ All code is licensed under the `BSD 3-Clause license`_.  .. _BSD 3-Clause license: http://opensource.org/licenses/BSD-3-Clause -.. only:: html - -  Links -  ===== +Links +===== -  * `Home page <https://projects.kde.org/projects/kdesupport/extra-cmake-modules>`_ -  * `Mailing list <https://mail.kde.org/mailman/listinfo/kde-buildsystem>`_ -  * IRC channel: #kde-devel on Freenode -  * `Git repository <https://projects.kde.org/projects/kdesupport/extra-cmake-modules/repository>`_ +* Home page: https://projects.kde.org/projects/kdesupport/extra-cmake-modules +* Mailing list: https://mail.kde.org/mailman/listinfo/kde-buildsystem +* IRC channel: #kde-devel on Freenode +* Git repository: https://projects.kde.org/projects/kdesupport/extra-cmake-modules/repository diff --git a/docs/manual/ecm-developer.7.rst b/docs/manual/ecm-developer.7.rst new file mode 100644 index 00000000..3ed3f786 --- /dev/null +++ b/docs/manual/ecm-developer.7.rst @@ -0,0 +1,231 @@ +.. ecm-manual-description: ECM Developer Reference + +ecm-developer(7) +**************** + +.. only:: html or latex + +   .. contents:: + + +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:: + +  #============================================================================= +  # Copyright 20XX Your Name <your.email@example.com> +  # +  # Distributed under the OSI-approved BSD License (the "License"); +  # see accompanying file COPYING-CMAKE-SCRIPTS for details. +  # +  # This software is distributed WITHOUT ANY WARRANTY; without even the +  # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +  # See the License for more information. +  #============================================================================= +  # (To distribute this file outside of extra-cmake-modules, substitute the full +  #  License text for the above reference.) + +Functions should be used instead of macros unless there is a good reason not to +(and that reason should be noted in a comment), and lowercase should be used for +macros, functions and commands. + +4 spaces is the generally-recommended indent, although there are several files +that use 2 spaces; consistency within a file is more important than consistency +across files. + +If in doubt, look at how other modules in Extra CMake Modules are written, 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 :module:`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 include 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 specific 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: + +.. code-block:: cmake + +  if(CMAKE_VERSION VERSION_LESS 2.8.12) +      message(FATAL_ERROR "CMake 2.8.12 is required by FindFoo.cmake") +  endif() +  if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12) +      message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindFoo.cmake") +  endif() + +The :module:`ECMFindModuleHelpers` module has several useful functions and +macros. For example, it allows you to replace the above version check with: + +.. code-block:: cmake + +  ecm_find_package_version_check(Foo) + +Components +~~~~~~~~~~ + +Using :module:`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 version check: + +.. code-block:: cmake + +  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 +components, and query other variables you provide to find out the information +they require.  The documentation for :module:`ECMFindModuleHelpers` provides +more information, but a simple setup might look like: + +.. code-block:: cmake + +  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 + +.. code-block:: cmake + +  set(Foo_Baz_component_deps "Bar") + +Then call the macros: + +.. code-block:: cmake + +  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_<component>_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, finish off with + +.. code-block:: cmake + +  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 "http://www.foo.example.com/" +      DESCRIPTION "A library for doing useful things") + + +Submitting Modules +================== + +Proposed new modules should be submitted using the `KDE Review Board instance`_, +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\ . + + +.. _KDE Review Board instance: https://git.reviewboard.kde.org/ +.. _cmake-developer(7): http://www.cmake.org/cmake/help/git-master/manual/cmake-developer.7.html diff --git a/docs/manual/ecm-find-modules.7.rst b/docs/manual/ecm-find-modules.7.rst index 4e3fc984..0f09c22a 100644 --- a/docs/manual/ecm-find-modules.7.rst +++ b/docs/manual/ecm-find-modules.7.rst @@ -7,6 +7,45 @@ ecm-find-modules(7)     .. contents:: +Introduction +============ + +Find modules are used by the CMake ``find_package`` command to search for +packages that do not provide their own CMake package config files. CMake +provides an extensive set of find modules, and Extra CMake Modules (ECM) adds +to that. + +To use ECM's find modules, you need to tell CMake to find the ECM package, and +then add either ``${ECM_MODULE_PATH}`` or ``${ECM_FIND_MODULE_DIR}`` to the +``CMAKE_MODULE_PATH`` variable: + +.. code-block:: cmake + +  find_package(ECM REQUIRED NO_MODULE) +  set(CMAKE_MODULE_PATH ${ECM_FIND_MODULE_DIR}) + +Using ``${ECM_MODULE_PATH}`` will also make the modules intended for direct use +by CMake scripts available (see :manual:`ecm-modules(7)` and +:manual:`ecm-kde-modules(7)`). + +You can also make local copies of find modules using the +``ecm_use_find_modules`` function from :module:`ECMUseFindModules`, which is +automatically included when ECM is found: + +.. code-block:: cmake + +  find_package(ECM REQUIRED NO_MODULE) +  ecm_use_find_modules( +      DIR "${CMAKE_BINARY_DIR}/cmake" +      MODULES FindEGL.cmake +  ) +  set(CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}/cmake") + +This allows selective use of ECM's find modules, and the NO_OVERRIDE argument +can be used to ensure that if CMake ships its own version of that find module, +it will be used instead. + +  All Find Modules  ================ @@ -16,3 +55,10 @@ All Find Modules     /find-module/* +.. only:: man + +  See Also +  ======== + +  :manual:`ecm(7)`, :manual:`ecm-modules(7)`, :manual:`ecm-kde-modules(7)` + diff --git a/docs/manual/ecm-kde-modules.7.rst b/docs/manual/ecm-kde-modules.7.rst index b3dffd77..184458f9 100644 --- a/docs/manual/ecm-kde-modules.7.rst +++ b/docs/manual/ecm-kde-modules.7.rst @@ -7,6 +7,28 @@ ecm-kde-modules(7)     .. contents:: +Introduction +============ + +Extra CMake Modules (ECM) provides several modules that provide default settings +(like installation directories, compiler flags and other CMake options) aimed at +software produced by the KDE modules; these are documented here. ECM also +provides modules with more general functionality, documented in +:manual:`ecm-modules(7)`, and ones that extend the functionality of the +``find_package`` command, documented in :manual:`ecm-find-modules(7)`. + +To use these modules, you need to tell CMake to find the ECM package, and +then add either ``${ECM_MODULE_PATH}`` or ``${ECM_KDE_MODULE_DIR}`` to the +``CMAKE_MODULE_PATH`` variable: + +.. code-block:: cmake + +  find_package(ECM REQUIRED NO_MODULE) +  set(CMAKE_MODULE_PATH ${ECM_MODULE_DIR}) + +Using ``${ECM_MODULE_PATH}`` will also make the other types of modules +available. +  All KDE Modules  =============== @@ -16,3 +38,10 @@ All KDE Modules     /kde-module/* +.. only:: man + +  See Also +  ======== + +  :manual:`ecm(7)`, :manual:`ecm-modules(7)`, :manual:`ecm-find-modules(7)` + diff --git a/docs/manual/ecm-modules.7.rst b/docs/manual/ecm-modules.7.rst index 70b09f5e..16fd8612 100644 --- a/docs/manual/ecm-modules.7.rst +++ b/docs/manual/ecm-modules.7.rst @@ -7,6 +7,30 @@ ecm-modules(7)     .. contents:: +Introduction +============ + +Extra CMake Modules (ECM) provides various modules that provide useful functions +for CMake scripts. ECM actually provides three types of modules: those that +extend the functionality of the ``find_package`` command are documented in +:manual:`ecm-find-modules(7)`; those that provide standard settings for software +produced by the KDE community are documented in :manual:`ecm-kde-modules(7)`. +The rest provide macros and functions for general use by CMake scripts and are +documented here. + +To use these modules, you need to tell CMake to find the ECM package, and +then add either ``${ECM_MODULE_PATH}`` or ``${ECM_MODULE_DIR}`` to the +``CMAKE_MODULE_PATH`` variable: + +.. code-block:: cmake + +  find_package(ECM REQUIRED NO_MODULE) +  set(CMAKE_MODULE_PATH ${ECM_MODULE_DIR}) + +Using ``${ECM_MODULE_PATH}`` will also make the find modules and KDE modules +available. + +  All Modules  =========== @@ -16,3 +40,10 @@ All Modules     /module/* +.. only:: man + +  See Also +  ======== + +  :manual:`ecm(7)`, :manual:`ecm-find-modules(7)`, :manual:`ecm-kde-modules(7)` + diff --git a/docs/writing-find-modules.md b/docs/writing-find-modules.md deleted file mode 100644 index 2130a43a..00000000 --- a/docs/writing-find-modules.md +++ /dev/null @@ -1,301 +0,0 @@ -Writing Find Modules           {#writing-find-modules} -==================== - -The `find_package` macro from CMake has two ways of finding packages.  If the -package Foo provides a `FooConfig.cmake` file in an appropriate place, CMake -will use that to determine all the necessary information to build against the -package.  Otherwise, if there is a `FindFoo.cmake` file somewhere in -`CMAKE_MODULE_PATH`, that will be used to find whether the package exists and -determine the appropriate information about it if it does.  See -[the CMake documentation][cmake:packages] for more information. - -The primary task of a `FindFoo.cmake` file is to determine whether the requested -package exists on the system, and set the `Foo_FOUND` variable to reflect this. -If Foo is a library, it typically sets variables such as `Foo_LIBRARIES`, -`Foo_INCLUDE_DIRS` and `Foo_DEFINITIONS` to provide the necessary information to -build and link against that library.  The `FindFoo.cmake` files in -extra-cmake-modules usually provide imported targets to make using the libraries -even simpler.  The files may also provide additional variables and useful CMake -macros. - -We will describe a typical CMake module for finding a library. - -[cmake:packages]: http://www.cmake.org/cmake/help/git-master/manual/cmake-packages.7.html - - -Documentation -------------- - -The first thing that is needed is documentation.  Start the file with a simple -statement of what the module does.  In the simplest case, this is just - -    # Find the Foo library - -but more description may be required for some packages.  If there are caveats or -other details users of the module should be aware of, you can add further -paragraphs below this.  Then you need to document what variables and imported -targets are set by the module, such as - -    # This will define the following variables: -    # -    #     Foo_FOUND         - True if the system has the Foo library -    #     Foo_VERSION       - The version of the Foo library which was found -    # -    # and the following imported targets: -    # -    #     Foo::Bar -    # -    # The following compatibility variables will also be defined, although -    # the imported targets should be used instead: -    # -    #     Foo_LIBRARIES      - Link to these to use the Foo library -    #     Foo_INCLUDES_DIRS  - Include directory for the Foo library -    #     Foo_DEFINITIONS    - Compiler flags required to link against the Foo library -    #     Foo_VERSION_STRING - The version of the Foo library which was found - -Don't forget to add copyright and license notices.  Any module distributed with -extra-cmake-modules must use the BSD 2-clause or 3-clause license: - -    # Copyright 2014 Your Name <your@email> -    # -    # 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. - - -Version Requirements --------------------- - -The modules provided by extra-cmake-modules typically assume a minimum CMake -version.  This is particularly relevant with imported targets, which are not -supported in old CMake versions.  You can (and should) enforce this in the -following way: - - -    if(CMAKE_VERSION VERSION_LESS 2.8.12) -        message(FATAL_ERROR "CMake 2.8.12 is required by FindFoo.cmake") -    endif() -    if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12) -        message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindFoo.cmake") -    endif() - -This provides developers and users with helpful error messages, rather than the -projects failing for mysterious reasons with old CMake versions. - - -Finding the Package -------------------- - -Now the actual libraries and so on have to be found.  The code here will -obviously vary from module to module (that, after all, is the point of the Find -modules), but there tends to be a common pattern for libraries. - -First, we try to use `pkg-config` to find the library.  Note that we cannot rely -on this, as it may not be available, but it provides a good starting point. - -    find_package(PkgConfig) -    pkg_check_modules(PC_Foo QUIET Foo) - -This should define some variables starting `PC_Foo_` that contain the -information from the `.pc` file.  We can use this to set `Foo_DEFINITIONS`: - -    set(Foo_DEFINITIONS ${PC_Foo_CFLAGS_OTHER}) - -Now we need to find the libraries and include files; we use the information from -`pkg-config` to provide hints to CMake about where to look: - -    find_path(Foo_INCLUDE_DIR -        NAMES -            foo.h -        PATHS -            ${PC_Foo_INCLUDEDIR} -            ${PC_Foo_INCLUDE_DIRS} -        PATH_SUFFIXES -            Foo # if you need to put #include <Foo/foo.h> in your code -    ) -    find_library(Foo_LIBRARY -        NAMES -            foo -        PATHS -            ${PC_Foo_LIBDIR} -            ${PC_Foo_LIBRARY_DIRS} -    ) - -If you have a good way of getting the version (from a header file, for example), -you can use that information to set `Foo_VERSION`.  Otherwise, attempt to -use the information from `pkg-config`: - -    set(Foo_VERSION ${PC_Foo_VERSION}) - - -Finishing Up ------------- - -Now we can use `FindPackageHandleStandardArgs` to do most of the rest of the -work for us. - -    include(FindPackageHandleStandardArgs) -    find_package_handle_standard_args(Foo -        FOUND_VAR Foo_FOUND -        REQUIRED_VARS -            Foo_LIBRARY -            Foo_INCLUDE_DIR -        VERSION_VAR Foo_VERSION -    ) - -This will check that the `REQUIRED_VARS` contain values (that do not end in -`-NOTFOUND`) and set `Foo_FOUND` appropriately.  It will also cache those -values.  If `Foo_VERSION` is set, and a required version was passed to -`find_package`, it will check the requested version against the one in -`Foo_VERSION`.  It will also print messages as appropriate; note that if -the package was found, it will print the contents of the first required variable -to indicate where it was found. - -We add an imported target for the library.  Note that we do this after calling -`find_package_handle_standard_args` so that we can use the `Foo_FOUND` variable. -Imported targets should be namespaced (hence the `Foo::` prefix); CMake will -recognize that values passed to `target_link_libraries` that contain `::` in -their name are supposed to be imported targets (rather than just library names), -and will produce appropriate diagnostic messages if that target does not exist. - -    if(Foo_FOUND AND NOT TARGET Foo::Foo) -        add_library(Foo::Foo UNKNOWN IMPORTED) -        set_target_properties(Foo::Foo PROPERTIES -            IMPORTED_LOCATION "${Foo_LIBRARY}" -            INTERFACE_COMPILE_OPTIONS "${Foo_DEFINITIONS}" -            INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}" -        ) -    endif() - -One thing to note about this is that the `INTERFACE_INCLUDE_DIRECTORIES` and -similar properties should only contain information about the target itself, and -not any of its dependencies.  Instead, those dependencies should also be -targets, and CMake should be told that they are dependencies of this target. -CMake will then combine all the necessary information automatically. - -We should also provide some information about the package, such as where to -download it. - -    include(FeatureSummary) -    set_package_properties(Foo PROPERTIES -        URL "http://www.foo.example.com/" -        DESCRIPTION "A library for doing useful things") - -Most of the cache variables should be hidden in the `ccmake` interface unless -the user explicitly asks to edit them: - -    mark_as_advanced( -        Foo_INCLUDE_DIR -        Foo_LIBRARY -    ) - -If this module replaces an older version, you should set compatibility variables -to cause the least disruption possible. - -    # compatibility variables -    set(Foo_LIBRARIES ${Foo_LIBRARY}) -    set(Foo_INCLUDE_DIRS ${Foo_INCLUDE_DIR}) -    set(Foo_VERSION_STRING ${Foo_VERSION}) - -Note that we do not wish to pass `Foo_LIBRARIES` to `find_library`, or -`Foo_INCLUDE_DIRS` to `find_path`, as the variables passed to those commands -will be stored in the cache for the user to override. - - -Components ----------- - -If your find module has multiple components, such as a package that provides -multiple libraries, the ECMFindModulesHelpers module can do a lot of the work -for you.  First, you need to include the module, and perform the version check. -ECMFindModuleHelpers provides its own version check macro, which specifies the -minimum required CMake version for the other macros in that module. - -    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 components, -and query other variables you provide to find out the information 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_<component>_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, finish 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 "http://www.foo.example.com/" -        DESCRIPTION "A library for doing useful things") - - -Other Macros ------------- - -Some Find modules will wish to provide useful macros related to the package. -For example, the FindSharedMimeInfo module provides an `update_xdg_mimetypes` -macro.  The main thing to note is that you should probably make this a function, -rather than a macro, to avoid polluting the global namespace with temporary -variables. - | 
