Merge topic 'doc-find-module-development'
fcdf86d0
Help: Rewrite the cmake-developer.7 find module documentation
This commit is contained in:
commit
40a922cce6
|
@ -664,213 +664,408 @@ For example, a ``Modules/Findxxx.cmake`` module may contain:
|
||||||
<code>
|
<code>
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
After the top documentation block, leave a *BLANK* line, and then add a
|
||||||
|
copyright and licence notice block like this one (change only the year
|
||||||
|
range and name)
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2009-2011 Your Name
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt 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 CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
Test the documentation formatting by running
|
||||||
|
``cmake --help-module <module-name>``, and also by enabling the
|
||||||
|
``SPHINX_HTML`` and ``SPHINX_MAN`` options to build the documentation.
|
||||||
|
Edit the comments until generated documentation looks satisfactory. To
|
||||||
|
have a .cmake file in this directory NOT show up in the modules
|
||||||
|
documentation, simply leave out the ``Help/module/<module-name>.rst``
|
||||||
|
file and the ``Help/manual/cmake-modules.7.rst`` toctree entry.
|
||||||
|
|
||||||
|
|
||||||
Find Modules
|
Find Modules
|
||||||
------------
|
------------
|
||||||
|
|
||||||
A "find module" is a ``Modules/Find<package>.cmake`` file to be loaded
|
A "find module" is a ``Modules/Find<package>.cmake`` file to be loaded
|
||||||
by the :command:`find_package` command when invoked for ``<package>``.
|
by the :command:`find_package` command when invoked for ``<package>``.
|
||||||
|
|
||||||
We would like all ``FindXxx.cmake`` files to produce consistent variable
|
The primary task of a find module is to determine whether a package
|
||||||
names. Please use the following consistent variable names for general use.
|
exists on the system, set the ``<package>_FOUND`` variable to reflect
|
||||||
|
this and provide any variables, macros and imported targets required to
|
||||||
|
use the package.
|
||||||
|
|
||||||
Xxx_INCLUDE_DIRS
|
The traditional approach is to use variables for everything, including
|
||||||
The final set of include directories listed in one variable for use by client
|
libraries and executables: see the `Standard Variable Names`_ section
|
||||||
code. This should not be a cache entry.
|
below. This is what most of the existing find modules provided by CMake
|
||||||
|
do.
|
||||||
|
|
||||||
Xxx_LIBRARIES
|
The more modern approach is to behave as much like
|
||||||
The libraries to link against to use Xxx. These should include full paths.
|
``<package>Config.cmake`` files as possible, by providing imported
|
||||||
This should not be a cache entry.
|
targets. As well as matching how ``*Config.cmake`` files work, the
|
||||||
|
libraries, include directories and compile definitions are all set just
|
||||||
|
by using the target in a :command:`target_link_libraries` call. The
|
||||||
|
disadvantage is that ``*Config.cmake`` files of projects that use
|
||||||
|
imported targets from find modules may require more work to make sure
|
||||||
|
those imported targets that are in the link interface are available.
|
||||||
|
|
||||||
Xxx_DEFINITIONS
|
In either case (or even when providing both variables and imported
|
||||||
Definitions to use when compiling code that uses Xxx. This really shouldn't
|
targets), find modules should provide backwards compatibility with old
|
||||||
include options such as (-DHAS_JPEG)that a client source-code file uses to
|
versions that had the same name.
|
||||||
decide whether to #include <jpeg.h>
|
|
||||||
|
|
||||||
Xxx_EXECUTABLE
|
A FindFoo.cmake module will typically be loaded by the command::
|
||||||
Where to find the Xxx tool.
|
|
||||||
|
|
||||||
Xxx_Yyy_EXECUTABLE
|
find_package(Foo [major[.minor[.patch[.tweak]]]]
|
||||||
Where to find the Yyy tool that comes with Xxx.
|
[EXACT] [QUIET] [REQUIRED]
|
||||||
|
[[COMPONENTS] [components...]]
|
||||||
|
[OPTIONAL_COMPONENTS components...]
|
||||||
|
[NO_POLICY_SCOPE])
|
||||||
|
|
||||||
Xxx_LIBRARY_DIRS
|
See the :command:`find_package` documentation for details on what
|
||||||
Optionally, the final set of library directories listed in one variable for
|
variables are set for the find module. Most of these are dealt with by
|
||||||
use by client code. This should not be a cache entry.
|
using :module:`FindPackageHandleStandardArgs`.
|
||||||
|
|
||||||
Xxx_ROOT_DIR
|
Briefly, the module should only locate versions of the package
|
||||||
Where to find the base directory of Xxx.
|
compatible with the requested version, as described by the
|
||||||
|
``Foo_FIND_VERSION`` family of variables. If ``Foo_FIND_QUIETLY`` is
|
||||||
|
set to true, it should avoid printing messages, including anything
|
||||||
|
complaining about the package not being found. If ``Foo_FIND_REQUIRED``
|
||||||
|
is set to true, the module should issue a ``FATAL_ERROR`` if the package
|
||||||
|
cannot be found. If neither are set to true, it should print a
|
||||||
|
non-fatal message if it cannot find the package.
|
||||||
|
|
||||||
Xxx_VERSION_Yy
|
Packages that find multiple semi-independent parts (like bundles of
|
||||||
Expect Version Yy if true. Make sure at most one of these is ever true.
|
libraries) should search for the components listed in
|
||||||
|
``Foo_FIND_COMPONENTS`` if it is set , and only set ``Foo_FOUND`` to
|
||||||
|
true if for each searched-for component ``<c>`` that was not found,
|
||||||
|
``Foo_FIND_REQUIRED_<c>`` is not set to true. The ``HANDLE_COMPONENTS``
|
||||||
|
argument of ``find_package_handle_standard_args()`` can be used to
|
||||||
|
implement this.
|
||||||
|
|
||||||
Xxx_WRAP_Yy
|
If ``Foo_FIND_COMPONENTS`` is not set, which modules are searched for
|
||||||
If False, do not try to use the relevant CMake wrapping command.
|
and required is up to the find module, but should be documented.
|
||||||
|
|
||||||
Xxx_Yy_FOUND
|
For internal implementation, it is a generally accepted convention that
|
||||||
If False, optional Yy part of Xxx sytem is not available.
|
variables starting with underscore are for temporary use only.
|
||||||
|
|
||||||
Xxx_FOUND
|
Like all modules, find modules should be properly documented. To add a
|
||||||
Set to false, or undefined, if we haven't found, or don't want to use Xxx.
|
module to the CMake documentation, follow the steps in the `Module
|
||||||
|
Documentation`_ section above.
|
||||||
|
|
||||||
Xxx_NOT_FOUND_MESSAGE
|
|
||||||
Should be set by config-files in the case that it has set Xxx_FOUND to FALSE.
|
|
||||||
The contained message will be printed by the find_package() command and by
|
|
||||||
find_package_handle_standard_args() to inform the user about the problem.
|
|
||||||
|
|
||||||
Xxx_RUNTIME_LIBRARY_DIRS
|
|
||||||
Optionally, the runtime library search path for use when running an
|
|
||||||
executable linked to shared libraries. The list should be used by user code
|
|
||||||
to create the PATH on windows or LD_LIBRARY_PATH on unix. This should not be
|
|
||||||
a cache entry.
|
|
||||||
|
|
||||||
Xxx_VERSION_STRING
|
Standard Variable Names
|
||||||
A human-readable string containing the version of the package found, if any.
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Xxx_VERSION_MAJOR
|
For a ``FindXxx.cmake`` module that takes the approach of setting
|
||||||
The major version of the package found, if any.
|
variables (either instead of or in addition to creating imported
|
||||||
|
targets), the following variable names should be used to keep things
|
||||||
|
consistent between find modules. Note that all variables start with
|
||||||
|
``Xxx_`` to make sure they do not interfere with other find modules; the
|
||||||
|
same consideration applies to macros, functions and imported targets.
|
||||||
|
|
||||||
Xxx_VERSION_MINOR
|
``Xxx_INCLUDE_DIRS``
|
||||||
The minor version of the package found, if any.
|
The final set of include directories listed in one variable for use by
|
||||||
|
client code. This should not be a cache entry.
|
||||||
|
|
||||||
Xxx_VERSION_PATCH
|
``Xxx_LIBRARIES``
|
||||||
The patch version of the package found, if any.
|
The libraries to link against to use Xxx. These should include full
|
||||||
|
paths. This should not be a cache entry.
|
||||||
|
|
||||||
You do not have to provide all of the above variables. You should provide
|
``Xxx_DEFINITIONS``
|
||||||
Xxx_FOUND under most circumstances. If Xxx is a library, then Xxx_LIBRARIES,
|
Definitions to use when compiling code that uses Xxx. This really
|
||||||
should also be defined, and Xxx_INCLUDE_DIRS should usually be defined (I
|
shouldn't include options such as ``-DHAS_JPEG`` that a client
|
||||||
guess libm.a might be an exception)
|
source-code file uses to decide whether to ``#include <jpeg.h>``
|
||||||
|
|
||||||
|
``Xxx_EXECUTABLE``
|
||||||
|
Where to find the Xxx tool.
|
||||||
|
|
||||||
|
``Xxx_Yyy_EXECUTABLE``
|
||||||
|
Where to find the Yyy tool that comes with Xxx.
|
||||||
|
|
||||||
|
``Xxx_LIBRARY_DIRS``
|
||||||
|
Optionally, the final set of library directories listed in one
|
||||||
|
variable for use by client code. This should not be a cache entry.
|
||||||
|
|
||||||
|
``Xxx_ROOT_DIR``
|
||||||
|
Where to find the base directory of Xxx.
|
||||||
|
|
||||||
|
``Xxx_VERSION_Yy``
|
||||||
|
Expect Version Yy if true. Make sure at most one of these is ever true.
|
||||||
|
|
||||||
|
``Xxx_WRAP_Yy``
|
||||||
|
If False, do not try to use the relevant CMake wrapping command.
|
||||||
|
|
||||||
|
``Xxx_Yy_FOUND``
|
||||||
|
If False, optional Yy part of Xxx sytem is not available.
|
||||||
|
|
||||||
|
``Xxx_FOUND``
|
||||||
|
Set to false, or undefined, if we haven't found, or don't want to use
|
||||||
|
Xxx.
|
||||||
|
|
||||||
|
``Xxx_NOT_FOUND_MESSAGE``
|
||||||
|
Should be set by config-files in the case that it has set
|
||||||
|
``Xxx_FOUND`` to FALSE. The contained message will be printed by the
|
||||||
|
:command:`find_package` command and by
|
||||||
|
``find_package_handle_standard_args()`` to inform the user about the
|
||||||
|
problem.
|
||||||
|
|
||||||
|
``Xxx_RUNTIME_LIBRARY_DIRS``
|
||||||
|
Optionally, the runtime library search path for use when running an
|
||||||
|
executable linked to shared libraries. The list should be used by
|
||||||
|
user code to create the ``PATH`` on windows or ``LD_LIBRARY_PATH`` on
|
||||||
|
UNIX. This should not be a cache entry.
|
||||||
|
|
||||||
|
``Xxx_VERSION``
|
||||||
|
The full version string of the package found, if any. Note that many
|
||||||
|
existing modules provide ``Xxx_VERSION_STRING`` instead.
|
||||||
|
|
||||||
|
``Xxx_VERSION_MAJOR``
|
||||||
|
The major version of the package found, if any.
|
||||||
|
|
||||||
|
``Xxx_VERSION_MINOR``
|
||||||
|
The minor version of the package found, if any.
|
||||||
|
|
||||||
|
``Xxx_VERSION_PATCH``
|
||||||
|
The patch version of the package found, if any.
|
||||||
|
|
||||||
The following names should not usually be used in CMakeLists.txt files, but
|
The following names should not usually be used in CMakeLists.txt files, but
|
||||||
they may be usefully modified in users' CMake Caches to control stuff.
|
are typically cache variables for users to edit and control the
|
||||||
|
behaviour of find modules (like entering the path to a library manually)
|
||||||
|
|
||||||
Xxx_LIBRARY
|
``Xxx_LIBRARY``
|
||||||
Name of Xxx Library. A User may set this and Xxx_INCLUDE_DIR to ignore to
|
The path of the Xxx library (as used with :command:`find_library`, for
|
||||||
force non-use of Xxx.
|
example).
|
||||||
|
|
||||||
Xxx_Yy_LIBRARY
|
``Xxx_Yy_LIBRARY``
|
||||||
Name of Yy library that is part of the Xxx system. It may or may not be
|
The path of the Yy library that is part of the Xxx system. It may or
|
||||||
required to use Xxx.
|
may not be required to use Xxx.
|
||||||
|
|
||||||
Xxx_INCLUDE_DIR
|
``Xxx_INCLUDE_DIR``
|
||||||
Where to find xxx.h, etc. (Xxx_INCLUDE_PATH was considered bad because a path
|
Where to find headers for using the Xxx library.
|
||||||
includes an actual filename.)
|
|
||||||
|
|
||||||
Xxx_Yy_INCLUDE_DIR
|
``Xxx_Yy_INCLUDE_DIR``
|
||||||
Where to find xxx_yy.h, etc.
|
Where to find headers for using the Yy library of the Xxx system.
|
||||||
|
|
||||||
For tidiness's sake, try to keep as many options as possible out of the cache,
|
To prevent users being overwhelmed with settings to configure, try to
|
||||||
leaving at least one option which can be used to disable use of the module, or
|
keep as many options as possible out of the cache, leaving at least one
|
||||||
locate a not-found library (e.g. Xxx_ROOT_DIR). For the same reason, mark
|
option which can be used to disable use of the module, or locate a
|
||||||
|
not-found library (e.g. ``Xxx_ROOT_DIR``). For the same reason, mark
|
||||||
most cache options as advanced.
|
most cache options as advanced.
|
||||||
|
|
||||||
If you need other commands to do special things then it should still begin
|
While these are the standard variable names, you should provide
|
||||||
with ``Xxx_``. This gives a sort of namespace effect and keeps things tidy for the
|
backwards compatibility for any old names that were actually in use.
|
||||||
user. You should put comments describing all the exported settings, plus
|
Make sure you comment them as deprecated, so that no-one starts using
|
||||||
descriptions of any the users can use to control stuff.
|
them.
|
||||||
|
|
||||||
You really should also provide backwards compatibility any old settings that
|
|
||||||
were actually in use. Make sure you comment them as deprecated, so that
|
|
||||||
no-one starts using them.
|
|
||||||
|
|
||||||
To add a module to the CMake documentation, follow the steps in the
|
|
||||||
`Module Documentation`_ section above. Test the documentation formatting
|
|
||||||
by running ``cmake --help-module FindXxx``, and also by enabling the
|
|
||||||
``SPHINX_HTML`` and ``SPHINX_MAN`` options to build the documentation.
|
|
||||||
Edit the comments until generated documentation looks satisfactory.
|
|
||||||
To have a .cmake file in this directory NOT show up in the modules
|
|
||||||
documentation, simply leave out the ``Help/module/<module-name>.rst`` file
|
|
||||||
and the ``Help/manual/cmake-modules.7.rst`` toctree entry.
|
|
||||||
|
|
||||||
After the documentation, leave a *BLANK* line, and then add a
|
A Sample Find Module
|
||||||
copyright and licence notice block like this one::
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
#=============================================================================
|
We will describe how to create a simple find module for a library
|
||||||
# Copyright 2009-2011 Your Name
|
``Foo``.
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
|
||||||
# see accompanying file Copyright.txt 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 CMake, substitute the full
|
|
||||||
# License text for the above reference.)
|
|
||||||
|
|
||||||
The layout of the notice block is strictly enforced by the ``ModuleNotices``
|
The first thing that is needed is documentation. CMake's documentation
|
||||||
test. Only the year range and name may be changed freely.
|
system requires you to start the file with a documentation marker and
|
||||||
|
the name of the module. You should follow this with a simple statement
|
||||||
|
of what the module does.
|
||||||
|
|
||||||
A FindXxx.cmake module will typically be loaded by the command::
|
.. code-block:: cmake
|
||||||
|
|
||||||
FIND_PACKAGE(Xxx [major[.minor[.patch[.tweak]]]] [EXACT]
|
#.rst:
|
||||||
[QUIET] [[REQUIRED|COMPONENTS] [components...]])
|
# FindFoo
|
||||||
|
# -------
|
||||||
|
#
|
||||||
|
# Finds the Foo library
|
||||||
|
#
|
||||||
|
|
||||||
If any version numbers are given to the command it will set the following
|
More description may be required for some packages. If there are
|
||||||
variables before loading the module:
|
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
|
||||||
|
|
||||||
Xxx_FIND_VERSION
|
.. code-block:: cmake
|
||||||
full requested version string
|
|
||||||
|
|
||||||
Xxx_FIND_VERSION_MAJOR
|
# This will define the following variables::
|
||||||
major version if requested, else 0
|
#
|
||||||
|
# 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::Foo - The Foo library
|
||||||
|
|
||||||
Xxx_FIND_VERSION_MINOR
|
If the package provides any macros, they should be listed here, but can
|
||||||
minor version if requested, else 0
|
be documented where they are defined. See the `Module
|
||||||
|
Documentation`_ section above for more details.
|
||||||
|
|
||||||
Xxx_FIND_VERSION_PATCH
|
After the documentation, leave a blank line, and then add a copyright and
|
||||||
patch version if requested, else 0
|
licence notice block
|
||||||
|
|
||||||
Xxx_FIND_VERSION_TWEAK
|
.. code-block:: cmake
|
||||||
tweak version if requested, else 0
|
|
||||||
|
|
||||||
Xxx_FIND_VERSION_COUNT
|
#=============================================================================
|
||||||
number of version components, 0 to 4
|
# Copyright 2009-2011 Your Name
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt 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 CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
Xxx_FIND_VERSION_EXACT
|
If the module is new to CMake, you may want to provide a warning for
|
||||||
true if EXACT option was given
|
projects that do not require a high enough CMake version.
|
||||||
|
|
||||||
If the find module supports versioning it should locate a version of
|
.. code-block:: cmake
|
||||||
the package that is compatible with the version requested. If a
|
|
||||||
compatible version of the package cannot be found the module should
|
|
||||||
not report success. The version of the package found should be stored
|
|
||||||
in "Xxx_VERSION..." version variables documented by the module.
|
|
||||||
|
|
||||||
If the QUIET option is given to the command it will set the variable
|
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.0.0)
|
||||||
Xxx_FIND_QUIETLY to true before loading the FindXxx.cmake module. If
|
message(AUTHOR_WARNING "Your project should require at least CMake 3.0.0 to use FindFoo.cmake")
|
||||||
this variable is set the module should not complain about not being
|
endif()
|
||||||
able to find the package. If the
|
|
||||||
REQUIRED option is given to the command it will set the variable
|
|
||||||
Xxx_FIND_REQUIRED to true before loading the FindXxx.cmake module. If
|
|
||||||
this variable is set the module should issue a FATAL_ERROR if the
|
|
||||||
package cannot be found.
|
|
||||||
If neither the QUIET nor REQUIRED options are given then the
|
|
||||||
FindXxx.cmake module should look for the package and complain without
|
|
||||||
error if the module is not found.
|
|
||||||
|
|
||||||
FIND_PACKAGE() will set the variable CMAKE_FIND_PACKAGE_NAME to
|
Now the actual libraries and so on have to be found. The code here will
|
||||||
contain the actual name of the package.
|
obviously vary from module to module (dealing with that, after all, is the
|
||||||
|
point of find modules), but there tends to be a common pattern for libraries.
|
||||||
|
|
||||||
A package can provide sub-components.
|
First, we try to use ``pkg-config`` to find the library. Note that we
|
||||||
Those components can be listed after the COMPONENTS (or REQUIRED) or
|
cannot rely on this, as it may not be available, but it provides a good
|
||||||
OPTIONAL_COMPONENTS keywords. The set of all listed components will be
|
starting point.
|
||||||
specified in a Xxx_FIND_COMPONENTS variable.
|
|
||||||
For each package-specific component, say Yyy, a variable Xxx_FIND_REQUIRED_Yyy
|
|
||||||
will be set to true if it listed after COMPONENTS and it will be set to false
|
|
||||||
if it was listed after OPTIONAL_COMPONENTS.
|
|
||||||
Using those variables a FindXxx.cmake module and also a XxxConfig.cmake
|
|
||||||
package configuration file can determine whether and which components have
|
|
||||||
been requested, and whether they were requested as required or as optional.
|
|
||||||
For each of the requested components a Xxx_Yyy_FOUND variable should be set
|
|
||||||
accordingly.
|
|
||||||
The per-package Xxx_FOUND variable should be only set to true if all requested
|
|
||||||
required components have been found. A missing optional component should not
|
|
||||||
keep the Xxx_FOUND variable from being set to true.
|
|
||||||
If the package provides Xxx_INCLUDE_DIRS and Xxx_LIBRARIES variables, the
|
|
||||||
include dirs and libraries for all components which were requested and which
|
|
||||||
have been found should be added to those two variables.
|
|
||||||
|
|
||||||
To get this behavior you can use the FIND_PACKAGE_HANDLE_STANDARD_ARGS()
|
.. code-block:: cmake
|
||||||
macro, as an example see FindJPEG.cmake.
|
|
||||||
|
|
||||||
For internal implementation, it's a generally accepted convention that
|
find_package(PkgConfig)
|
||||||
variables starting with underscore are for temporary use only. (variable
|
pkg_check_modules(PC_Foo QUIET Foo)
|
||||||
starting with an underscore are not intended as a reserved prefix).
|
|
||||||
|
This should define some variables starting ``PC_Foo_`` that contain the
|
||||||
|
information from the ``Foo.pc`` file.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
find_path(Foo_INCLUDE_DIR
|
||||||
|
NAMES foo.h
|
||||||
|
PATHS ${PC_Foo_INCLUDE_DIRS}
|
||||||
|
# if you need to put #include <Foo/foo.h> in your code, add:
|
||||||
|
PATH_SUFFIXES Foo
|
||||||
|
)
|
||||||
|
find_library(Foo_LIBRARY
|
||||||
|
NAMES foo
|
||||||
|
PATHS ${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`` (although
|
||||||
|
note that find modules have traditionally used ``Foo_VERSION_STRING``,
|
||||||
|
so you may want to set both). Otherwise, attempt to use the information
|
||||||
|
from ``pkg-config``
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
set(Foo_VERSION ${PC_Foo_VERSION})
|
||||||
|
|
||||||
|
Now we can use :module:`FindPackageHandleStandardArgs` to do most of the
|
||||||
|
rest of the work for us
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
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 :command:`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.
|
||||||
|
|
||||||
|
At this point, we have to provide a way for users of the find module to
|
||||||
|
link to the library or libraries that were found. There are two
|
||||||
|
approaches, as discussed in the `Find Modules`_ section above. The
|
||||||
|
traditional variable approach looks like
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
if(Foo_FOUND)
|
||||||
|
set(Foo_LIBRARIES ${Foo_LIBRARY})
|
||||||
|
set(Foo_INCLUDE_DIRS ${Foo_INCLUDE_DIR})
|
||||||
|
set(Foo_DEFINITIONS ${PC_Foo_CFLAGS_OTHER})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
If more than one library was found, all of them should be included in
|
||||||
|
these variables (see the `Standard Variable Names`_ section for more
|
||||||
|
information).
|
||||||
|
|
||||||
|
When providing imported targets, these should be namespaced (hence the
|
||||||
|
``Foo::`` prefix); CMake will recognize that values passed to
|
||||||
|
:command:`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 (see policy :policy:`CMP0028`).
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
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 "${PC_Foo_CFLAGS_OTHER}"
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
# compatibility variables
|
||||||
|
set(Foo_VERSION_STRING ${Foo_VERSION})
|
||||||
|
|
Loading…
Reference in New Issue