Merge topic 'doc-find_package-advice'

d007d304ff Help: FetchContent FIND_PACKAGE_ARGS REQUIRED usually inappropriate
6341267780 Help: Note ways CMAKE_..._FIND_PACKAGE_... vars can break projects

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !8951
This commit is contained in:
Brad King
2023-11-15 13:38:35 +00:00
committed by Kitware Robot
3 changed files with 47 additions and 0 deletions
@@ -15,4 +15,14 @@ variables which have been stored in the cache will still be there. In
that case it is recommended to remove the cache variables for this
package from the cache using the cache editor or :option:`cmake -U`.
Note that this variable can lead to inconsistent results within the project.
Consider the case where a dependency is requested via :command:`find_package`
from two different places within the project. If the first call does not
have the ``REQUIRED`` keyword, it will not find the dependency when
``CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`` is set to true for that
dependency. The project will proceed under the assumption that the dependency
isn't available. If the second call elsewhere in the project *does* have the
``REQUIRED`` keyword, it can succeed. Two different parts of the same project
have then seen opposite results for the same dependency.
See also the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable.
@@ -11,4 +11,35 @@ turned into ``REQUIRED`` by setting the variable
This can be used to assert assumptions about build environment and to
ensure the build will fail early if they do not hold.
Note that setting this variable to true breaks some commonly used patterns.
Multiple calls to :command:`find_package` are sometimes used to obtain a
different search order to the default.
For example, projects can force checking a known path for a particular
package first before searching any of the other default search paths:
.. code:: cmake
find_package(something PATHS /some/local/path NO_DEFAULT_PATH)
find_package(something)
In the above, the first call looks for the ``something`` package in a specific
directory. If ``CMAKE_REQUIRE_FIND_PACKAGE_something`` is set to true, then
this first call must succeed, otherwise a fatal error occurs. The second call
never gets a chance to provide a fall-back to using the default search
locations.
A similar pattern is used even by some of CMake's own Find modules to search
for a config package first:
.. code:: cmake
find_package(something CONFIG QUIET)
if(NOT something_FOUND)
# Fall back to searching using typical Find module logic...
endif()
Again, if ``CMAKE_REQUIRE_FIND_PACKAGE_something`` is true, the first call
must succeed. It effectively means a config package must be found for the
dependency, and the Find module logic is never used.
See also the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable.
+6
View File
@@ -195,6 +195,12 @@ Commands
still be called if :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` is
set to ``OPT_IN`` or is not set.
It would not normally be appropriate to specify ``REQUIRED`` as one of
the additional arguments after ``FIND_PACKAGE_ARGS``. Doing so would
mean the :command:`find_package` call must succeed, so none of the other
details specified in the ``FetchContent_Declare()`` call would get a
chance to be used as a fall-back.
Everything after the ``FIND_PACKAGE_ARGS`` keyword is appended to the
:command:`find_package` call, so all other ``<contentOptions>`` must
come before the ``FIND_PACKAGE_ARGS`` keyword. If the