Merge topic 'cpack-innosetup-linux'
[kiteware-cmake.git] / Modules / CMakeFindDependencyMacro.cmake
blob2c04abe5075bdc4533c5cb47f97cc2c273f5a2e4
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
5 CMakeFindDependencyMacro
6 ------------------------
8 .. command:: find_dependency
10   The ``find_dependency()`` macro wraps a :command:`find_package` call for
11   a package dependency::
13     find_dependency(<dep> [...])
15   It is designed to be used in a
16   :ref:`Package Configuration File <Config File Packages>`
17   (``<PackageName>Config.cmake``).  ``find_dependency`` forwards the correct
18   parameters for ``QUIET`` and ``REQUIRED`` which were passed to
19   the original :command:`find_package` call.  Any additional arguments
20   specified are forwarded to :command:`find_package`.
22   If the dependency could not be found it sets an informative diagnostic
23   message and calls :command:`return` to end processing of the calling
24   package configuration file and return to the :command:`find_package`
25   command that loaded it.
27   .. note::
29     The call to :command:`return` makes this macro unsuitable to call
30     from :ref:`Find Modules`.
32 Package Dependency Search Optimizations
33 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35 If ``find_dependency`` is called with arguments identical to a previous
36 call in the same directory, perhaps due to diamond-shaped package
37 dependencies, the underlying call to :command:`find_package` is optimized
38 out.  This optimization is important to support large package dependency
39 graphs while avoiding a combinatorial explosion of repeated searches.
40 However, the heuristic cannot account for ambient variables that
41 affect package behavior, such as ``<PackageName>_USE_STATIC_LIBS``,
42 offered by some packages.  Therefore package configuration files should
43 avoid setting such variables before their calls to ``find_dependency``.
45 .. versionchanged:: 3.15
46   Previously, the underlying call to :command:`find_package` was always
47   optimized out if the package had already been found.  CMake 3.15
48   removed the optimization to support cases in which ``find_dependency``
49   call arguments request different components.
51 .. versionchanged:: 3.26
52   The pre-3.15 optimization was restored, but with the above-described
53   heuristic to account for varying ``find_dependency`` call arguments.
55 #]=======================================================================]
57 macro(find_dependency dep)
58   string(SHA256 cmake_fd_call_hash "${dep};${ARGN};${${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED}")
59   if(_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND)
60     unset(cmake_fd_call_hash)
61   else()
62     list(APPEND _CMAKE_${dep}_HASH_STACK ${cmake_fd_call_hash})
63     set(cmake_fd_quiet_arg)
64     if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
65       set(cmake_fd_quiet_arg QUIET)
66     endif()
67     set(cmake_fd_required_arg)
68     if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
69       set(cmake_fd_required_arg REQUIRED)
70     endif()
72     get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY
73       _CMAKE_${dep}_TRANSITIVE_DEPENDENCY
74       )
76     find_package(${dep} ${ARGN}
77       ${cmake_fd_quiet_arg}
78       ${cmake_fd_required_arg}
79       )
80     list(POP_BACK _CMAKE_${dep}_HASH_STACK cmake_fd_call_hash)
81     set("_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND" "${${dep}_FOUND}")
83     if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive)
84       set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE)
85     endif()
87     unset(cmake_fd_alreadyTransitive)
88     unset(cmake_fd_call_hash)
89     unset(cmake_fd_quiet_arg)
90     unset(cmake_fd_required_arg)
91     if (NOT ${dep}_FOUND)
92       set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.")
93       set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False)
94       return()
95     endif()
96   endif()
97 endmacro()