| Using Dependencies Guide |
| ************************ |
| |
| .. only:: html |
| |
| .. contents:: |
| |
| Introduction |
| ============ |
| |
| For developers wishing to use CMake to consume a third |
| party binary package, there are multiple possibilities |
| regarding how to optimally do so, depending on how |
| CMake-aware the third-party library is. |
| |
| CMake files provided with a software package contain |
| instructions for finding each build dependency. Some |
| build dependencies are optional in that the build may |
| succeed with a different feature set if the dependency |
| is missing, and some dependencies are required. CMake |
| searches well-known locations for each dependency, and |
| the provided software may supply additional hints or |
| locations to CMake to find each dependency. |
| |
| If a required dependency is not found by |
| :manual:`cmake(1)`, the cache is populated with an entry |
| which contains a ``NOTFOUND`` value. This value can be |
| replaced by specifying it on the command line, or in |
| the :manual:`ccmake(1)` or :manual:`cmake-gui(1)` tool. |
| See the :guide:`User Interaction Guide` for |
| more about setting cache entries. |
| |
| Libraries providing Config-file packages |
| ---------------------------------------- |
| |
| The most convenient way for a third-party to provide library |
| binaries for use with CMake is to provide |
| :ref:`Config File Packages`. These packages are text files |
| shipped with the library which instruct CMake how to use the |
| library binaries and associated headers, helper tools and |
| CMake macros provided by the library. |
| |
| The config files can usually be found in a directory whose |
| name matches the pattern ``lib/cmake/<PackageName>``, though |
| they may be in other locations instead. The |
| ``<PackageName>`` corresponds to use in CMake code with the |
| :command:`find_package` command such as |
| ``find_package(PackageName REQUIRED)``. |
| |
| The ``lib/cmake/<PackageName>`` directory will contain a |
| file which is either named ``<PackageName>Config.cmake`` |
| or ``<PackageName>-config.cmake``. This is the entry point |
| to the package for CMake. A separate optional file named |
| ``<PackageName>ConfigVersion.cmake`` may also exist in the |
| directory. This file is used by CMake to determine whether |
| the version of the third party package satisfies uses of the |
| :command:`find_package` command which specify version |
| constraints. It is optional to specify a version when using |
| :command:`find_package`, even if a ``ConfigVersion`` file is |
| present. |
| |
| If the ``Config.cmake`` file is found and the |
| optionally-specified version is satisfied, then the CMake |
| :command:`find_package` command considers the package to be |
| found and the entire library package is assumed to be |
| complete as designed. |
| |
| There may be additional files providing CMake macros or |
| :ref:`imported targets` for you to use. CMake does not |
| enforce any naming convention for these |
| files. They are related to the primary ``Config`` file by |
| use of the CMake :command:`include` command. |
| |
| :guide:`Invoking CMake <User Interaction Guide>` with the |
| intent of using a package of third party binaries requires |
| that cmake :command:`find_package` commands succeed in finding |
| the package. If the location of the package is in a directory |
| known to CMake, the :command:`find_package` call should |
| succeed. The directories known to cmake are platform-specific. |
| For example, packages installed on Linux with a standard |
| system package manager will be found in the ``/usr`` prefix |
| automatically. Packages installed in ``Program Files`` on |
| Windows will similarly be found automatically. |
| |
| Packages which are not found automatically are in locations |
| not predictable to CMake such as ``/opt/mylib`` or |
| ``$HOME/dev/prefix``. This is a normal situation and CMake |
| provides several ways for users to specify where to find |
| such libraries. |
| |
| The :variable:`CMAKE_PREFIX_PATH` variable may be |
| :ref:`set when invoking CMake <Setting Build Variables>`. |
| It is treated as a list of paths to search for |
| :ref:`Config File Packages`. A package installed in |
| ``/opt/somepackage`` will typically install config files |
| such as |
| ``/opt/somepackage/lib/cmake/somePackage/SomePackageConfig.cmake``. |
| In that case, ``/opt/somepackage`` should be added to |
| :variable:`CMAKE_PREFIX_PATH`. |
| |
| The environment variable ``CMAKE_PREFIX_PATH`` may also be |
| populated with prefixes to search for packages. Like the |
| ``PATH`` environment variable, this is a list and needs to use |
| the platform-specific environment variable list item separator |
| (``:`` on Unix and ``;`` on Windows). |
| |
| The :variable:`CMAKE_PREFIX_PATH` variable provides convenience |
| in cases where multiple prefixes need to be specified, or when |
| multiple different package binaries are available in the same |
| prefix. Paths to packages may also be specified by setting |
| variables matching ``<PackageName>_DIR``, such as |
| ``SomePackage_DIR``. Note that this is not a prefix but should |
| be a full path to a directory containing a config-style package |
| file, such as ``/opt/somepackage/lib/cmake/SomePackage/`` in |
| the above example. |
| |
| Imported Targets from Packages |
| ------------------------------ |
| |
| A third-party package which provides config-file packages may |
| also provide :ref:`Imported targets`. These will be |
| specified in files containing configuration-specific file |
| paths relevant to the package, such as debug and release |
| versions of libraries. |
| |
| Often the third-party package documentation will point out the |
| names of imported targets available after a successful |
| ``find_package`` for a library. Those imported target names |
| can be used with the :command:`target_link_libraries` command. |
| |
| A complete example which makes a simple use of a third party |
| library might look like: |
| |
| .. code-block:: cmake |
| |
| cmake_minimum_required(VERSION 3.10) |
| project(MyExeProject VERSION 1.0.0) |
| |
| find_package(SomePackage REQUIRED) |
| add_executable(MyExe main.cpp) |
| target_link_libraries(MyExe PRIVATE SomePrefix::LibName) |
| |
| See :manual:`cmake-buildsystem(7)` for further information |
| about developing a CMake buildsystem. |
| |
| Libraries not Providing Config-file Packages |
| -------------------------------------------- |
| |
| Third-party libraries which do not provide config-file packages |
| can still be found with the :command:`find_package` command, if |
| a ``FindSomePackage.cmake`` file is available. |
| |
| These module-file packages are different to config-file packages |
| in that: |
| |
| #. They should not be provided by the third party, except |
| perhaps in the form of documentation |
| #. The availability of a ``Find<PackageName>.cmake`` file does |
| not indicate the availability of the binaries themselves. |
| #. CMake does not search the :variable:`CMAKE_PREFIX_PATH` for |
| ``Find<PackageName>.cmake`` files. Instead CMake searches |
| for such files in the :variable:`CMAKE_MODULE_PATH` |
| variable. It is common for users to set the |
| :variable:`CMAKE_MODULE_PATH` when running CMake, and it is |
| common for CMake projects to append to |
| :variable:`CMAKE_MODULE_PATH` to allow use of local |
| module-file packages. |
| #. CMake ships ``Find<PackageName>.cmake`` files for some |
| :manual:`third party packages <cmake-modules(7)>` |
| for convenience in cases where the third party does |
| not provide config-file packages directly. These files are |
| a maintenance burden for CMake, so new Find modules are |
| generally not added to CMake anymore. Third-parties should |
| provide config file packages instead of relying on a Find |
| module to be provided by CMake. |
| |
| Module-file packages may also provide :ref:`Imported targets`. |
| A complete example which finds such a package might look |
| like: |
| |
| .. code-block:: cmake |
| |
| cmake_minimum_required(VERSION 3.10) |
| project(MyExeProject VERSION 1.0.0) |
| |
| find_package(PNG REQUIRED) |
| |
| # Add path to a FindSomePackage.cmake file |
| list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") |
| find_package(SomePackage REQUIRED) |
| |
| add_executable(MyExe main.cpp) |
| target_link_libraries(MyExe PRIVATE |
| PNG::PNG |
| SomePrefix::LibName |
| ) |
| |
| The :variable:`<PackageName>_ROOT` variable is also |
| searched as a prefix for :command:`find_package` calls using |
| module-file packages such as ``FindSomePackage``. |