| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- .. cmake-manual-description: CMake Developer Reference
- cmake-developer(7)
- ******************
- .. only:: html
- .. contents::
- Introduction
- ============
- This manual is intended for reference by developers working with
- :manual:`cmake-language(7)` code, whether writing their own modules,
- authoring their own build systems, or working on CMake itself.
- See https://cmake.org/get-involved/ to get involved in development of
- CMake upstream. It includes links to contribution instructions, which
- in turn link to developer guides for CMake itself.
- .. _`Find Modules`:
- Find Modules
- ============
- A "find module" is a ``Find<PackageName>.cmake`` file to be loaded by the
- :command:`find_package` command when invoked for ``<PackageName>``.
- The primary task of a find module is to determine whether a package is
- available, set the ``<PackageName>_FOUND`` variable to reflect this and
- provide any variables, macros and imported targets required to use the
- package. A find module is useful in cases where an upstream library does
- not provide a :ref:`config file package <Config File Packages>`.
- The traditional approach is to use variables for everything, including
- libraries and executables: see the `Standard Variable Names`_ section
- below. This is what most of the existing find modules provided by CMake
- do.
- The more modern approach is to behave as much like
- :ref:`config file packages <Config File Packages>` files as possible, by
- providing :ref:`imported target <Imported targets>`. This has the advantage
- of propagating :ref:`Target Usage Requirements` to consumers.
- In either case (or even when providing both variables and imported
- targets), find modules should provide backwards compatibility with old
- versions that had the same name.
- A FindFoo.cmake module will typically be loaded by the command::
- find_package(Foo [major[.minor[.patch[.tweak]]]]
- [EXACT] [QUIET] [REQUIRED]
- [[COMPONENTS] [components...]]
- [OPTIONAL_COMPONENTS components...]
- [NO_POLICY_SCOPE])
- See the :command:`find_package` documentation for details on what
- variables are set for the find module. Most of these are dealt with by
- using :module:`FindPackageHandleStandardArgs`.
- Briefly, the module should only locate versions of the package
- 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.
- Packages that find multiple semi-independent parts (like bundles of
- 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.
- If ``Foo_FIND_COMPONENTS`` is not set, which modules are searched for
- and required is up to the find module, but should be documented.
- For internal implementation, it is a generally accepted convention that
- variables starting with underscore are for temporary use only.
- .. _`CMake Developer Standard Variable Names`:
- Standard Variable Names
- -----------------------
- For a ``FindXxx.cmake`` module that takes the approach of setting
- 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_``, which (unless otherwise noted) must match exactly the name
- of the ``FindXxx.cmake`` file, including upper/lowercase.
- This prefix on the variable names ensures that they do not conflict with
- variables of other Find modules. The same pattern should also be followed
- for any macros, functions and imported targets defined by the Find module.
- ``Xxx_INCLUDE_DIRS``
- The final set of include directories listed in one variable for use by
- client code. This should not be a cache entry (note that this also means
- this variable should not be used as the result variable of a
- :command:`find_path` command - see ``Xxx_INCLUDE_DIR`` below for that).
- ``Xxx_LIBRARIES``
- The libraries to use with the module. These may be CMake targets, full
- absolute paths to a library binary or the name of a library that the
- linker must find in its search path. This should not be a cache entry
- (note that this also means this variable should not be used as the
- result variable of a :command:`find_library` command - see
- ``Xxx_LIBRARY`` below for that).
- ``Xxx_DEFINITIONS``
- The compile definitions to use when compiling code that uses the module.
- This really shouldn't include options such as ``-DHAS_JPEG`` that a client
- source-code file uses to decide whether to ``#include <jpeg.h>``
- ``Xxx_EXECUTABLE``
- The full absolute path to an executable. In this case, ``Xxx`` might not
- be the name of the module, it might be the name of the tool (usually
- converted to all uppercase), assuming that tool has such a well-known name
- that it is unlikely that another tool with the same name exists. It would
- be appropriate to use this as the result variable of a
- :command:`find_program` command.
- ``Xxx_YYY_EXECUTABLE``
- Similar to ``Xxx_EXECUTABLE`` except here the ``Xxx`` is always the module
- name and ``YYY`` is the tool name (again, usually fully uppercase).
- Prefer this form if the tool name is not very widely known or has the
- potential to clash with another tool. For greater consistency, also
- prefer this form if the module provides more than one executable.
- ``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 the module.
- ``Xxx_VERSION_VV``
- Variables of this form specify whether the ``Xxx`` module being provided
- is version ``VV`` of the module. There should not be more than one
- variable of this form set to true for a given module. For example, a
- module ``Barry`` might have evolved over many years and gone through a
- number of different major versions. Version 3 of the ``Barry`` module
- might set the variable ``Barry_VERSION_3`` to true, whereas an older
- version of the module might set ``Barry_VERSION_2`` to true instead.
- It would be an error for both ``Barry_VERSION_3`` and ``Barry_VERSION_2``
- to both be set to true.
- ``Xxx_WRAP_YY``
- When a variable of this form is set to false, it indicates that the
- relevant wrapping command should not be used. The wrapping command
- depends on the module, it may be implied by the module name or it might
- be specified by the ``YY`` part of the variable.
- ``Xxx_Yy_FOUND``
- For variables of this form, ``Yy`` is the name of a component for the
- module. It should match exactly one of the valid component names that
- may be passed to the :command:`find_package` command for the module.
- If a variable of this form is set to false, it means that the ``Yy``
- component of module ``Xxx`` was not found or is not available.
- Variables of this form would typically be used for optional components
- so that the caller can check whether an optional component is available.
- ``Xxx_FOUND``
- When the :command:`find_package` command returns to the caller, this
- variable will be set to true if the module was deemed to have been found
- successfully.
- ``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
- :command:`find_package_handle_standard_args` to inform the user about the
- problem. Use this instead of calling :command:`message` directly to
- report a reason for failing to find the module or package.
- ``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.
- They are intended for use by Find modules to specify and cache the locations
- of specific files or directories. Users are typically able to set and edit
- these variables to control the behavior of Find modules (like entering the
- path to a library manually):
- ``Xxx_LIBRARY``
- The path of the library. Use this form only when the module provides a
- single library. It is appropriate to use this as the result variable
- in a :command:`find_library` command.
- ``Xxx_Yy_LIBRARY``
- The path of library ``Yy`` provided by the module ``Xxx``. Use this form
- when the module provides more than one library or where other modules may
- also provide a library of the same name. It is also appropriate to use
- this form as the result variable in a :command:`find_library` command.
- ``Xxx_INCLUDE_DIR``
- When the module provides only a single library, this variable can be used
- to specify where to find headers for using the library (or more accurately,
- the path that consumers of the library should add to their header search
- path). It would be appropriate to use this as the result variable in a
- :command:`find_path` command.
- ``Xxx_Yy_INCLUDE_DIR``
- If the module provides more than one library or where other modules may
- also provide a library of the same name, this form is recommended for
- specifying where to find headers for using library ``Yy`` provided by
- the module. Again, it would be appropriate to use this as the result
- variable in a :command:`find_path` command.
- To prevent users being overwhelmed with settings to configure, try to
- keep as many options as possible out of the cache, leaving at least one
- 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. For packages which provide both debug
- and release binaries, it is common to create cache variables with a
- ``_LIBRARY_<CONFIG>`` suffix, such as ``Foo_LIBRARY_RELEASE`` and
- ``Foo_LIBRARY_DEBUG``. The :module:`SelectLibraryConfigurations` module
- can be helpful for such cases.
- While these are the standard variable names, you should provide
- backwards compatibility for any old names that were actually in use.
- Make sure you comment them as deprecated, so that no-one starts using
- them.
- A Sample Find Module
- --------------------
- We will describe how to create a simple find module for a library ``Foo``.
- The top of the module should begin with a license notice, followed by
- a blank line, and then followed by a :ref:`Bracket Comment`. The comment
- should begin with ``.rst:`` to indicate that the rest of its content is
- reStructuredText-format documentation. For example:
- ::
- # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- # file Copyright.txt or https://cmake.org/licensing for details.
- #[=======================================================================[.rst:
- FindFoo
- -------
- Finds the Foo library.
- Imported Targets
- ^^^^^^^^^^^^^^^^
- This module provides the following imported targets, if found:
- ``Foo::Foo``
- The Foo library
- Result Variables
- ^^^^^^^^^^^^^^^^
- 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.
- ``Foo_INCLUDE_DIRS``
- Include directories needed to use Foo.
- ``Foo_LIBRARIES``
- Libraries needed to link to Foo.
- Cache Variables
- ^^^^^^^^^^^^^^^
- The following cache variables may also be set:
- ``Foo_INCLUDE_DIR``
- The directory containing ``foo.h``.
- ``Foo_LIBRARY``
- The path to the Foo library.
- #]=======================================================================]
- The module documentation consists of:
- * An underlined heading specifying the module name.
- * A simple description of what the module finds.
- More description may be required for some packages. If there are
- caveats or other details users of the module should be aware of,
- specify them here.
- * A section listing imported targets provided by the module, if any.
- * A section listing result variables provided by the module.
- * Optionally a section listing cache variables used by the module, if any.
- If the package provides any macros or functions, they should be listed in
- an additional section, but can be documented by additional ``.rst:``
- comment blocks immediately above where those macros or functions are defined.
- The find module implementation may begin below the documentation block.
- Now the actual libraries and so on have to be found. The code here will
- 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.
- 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.
- .. code-block:: cmake
- find_package(PkgConfig)
- pkg_check_modules(PC_Foo QUIET Foo)
- 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}
- 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.
- The type of the :prop_tgt:`IMPORTED` target created in the
- :command:`add_library` command can always be specified as ``UNKNOWN``
- type. This simplifies the code in cases where static or shared variants may
- be found, and CMake will determine the type by inspecting the files.
- If the library is available with multiple configurations, the
- :prop_tgt:`IMPORTED_CONFIGURATIONS` target property should also be
- populated:
- .. code-block:: cmake
- if(Foo_FOUND)
- if (NOT TARGET Foo::Foo)
- add_library(Foo::Foo UNKNOWN IMPORTED)
- endif()
- if (Foo_LIBRARY_RELEASE)
- set_property(TARGET Foo::Foo APPEND PROPERTY
- IMPORTED_CONFIGURATIONS RELEASE
- )
- set_target_properties(Foo::Foo PROPERTIES
- IMPORTED_LOCATION_RELEASE "${Foo_LIBRARY_RELEASE}"
- )
- endif()
- if (Foo_LIBRARY_DEBUG)
- set_property(TARGET Foo::Foo APPEND PROPERTY
- IMPORTED_CONFIGURATIONS DEBUG
- )
- set_target_properties(Foo::Foo PROPERTIES
- IMPORTED_LOCATION_DEBUG "${Foo_LIBRARY_DEBUG}"
- )
- endif()
- set_target_properties(Foo::Foo PROPERTIES
- INTERFACE_COMPILE_OPTIONS "${PC_Foo_CFLAGS_OTHER}"
- INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}"
- )
- endif()
- The ``RELEASE`` variant should be listed first in the property
- so that the variant is chosen if the user uses a configuration which is
- not an exact match for any listed ``IMPORTED_CONFIGURATIONS``.
- 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})
|