1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-24 19:59:47 +08:00

Help: Fix find_package search order w.r.t. globs

Add documentation to clarify that `find_package` searches paths in the
specified order and stops at the first match.  Clarify documentation of
`CMAKE_FIND_PACKAGE_SORT_*` to match the actual behavior.

Note that no behavior is actually changed, this merely improves the
documentation to reflect actual behavior rather than seeming to imply
something else.

Also, update the test to verify that what we claim in the updated
documentation is what's actually happening.
This commit is contained in:
Matthew Woehlke
2024-10-23 12:24:44 -04:00
committed by Brad King
parent 6768820826
commit 630e4a12a3
5 changed files with 66 additions and 24 deletions

View File

@@ -503,6 +503,42 @@ The :variable:`CMAKE_IGNORE_PATH`, :variable:`CMAKE_IGNORE_PREFIX_PATH`,
:variable:`CMAKE_SYSTEM_IGNORE_PREFIX_PATH` variables can also cause some
of the above locations to be ignored.
Paths are searched in the order described above. The first viable package
configuration file found is used, even if a newer version of the package
resides later in the list of search paths.
For search paths which contain ``<name>*``, the order among matching paths
is unspecified unless the :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` variable
is set. This variable, along with the
:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable, determines the order
in which CMake considers paths that match a single search path containing
``<name>*``. For example, if the file system contains the package
configuration files
::
<prefix>/example-1.2/example-config.cmake
<prefix>/example-1.10/example-config.cmake
<prefix>/share/example-2.0/example-config.cmake
it is unspecified (when the aforementioned variables are unset) whether
``find_package(example)`` will find ``example-1.2`` or ``example-1.10``
(assuming that both are viable), but ``find_package`` will *not* find
``example-2.0``, because one of the other two will be found first.
To control the order in which ``find_package`` searches directories that match
a glob expression, use :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
For instance, to cause the above example to select ``example-1.10``,
one can set
.. code-block:: cmake
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
before calling ``find_package``.
.. versionadded:: 3.16
Added the ``CMAKE_FIND_USE_<CATEGORY>`` variables to globally disable
various search locations.
@@ -648,22 +684,6 @@ is acceptable the following variables are set:
Number of version components, 0 to 4
and the corresponding package configuration file is loaded.
When multiple package configuration files are available whose version files
claim compatibility with the version requested it is unspecified which
one is chosen: unless the variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`
is set no attempt is made to choose a highest or closest version number.
To control the order in which ``find_package`` checks for compatibility use
the two variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
For instance in order to select the highest version one can set
.. code-block:: cmake
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
before calling ``find_package``.
Package File Interface Variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -3,23 +3,26 @@ CMAKE_FIND_PACKAGE_SORT_ORDER
.. versionadded:: 3.7
The default order for sorting packages found using :command:`find_package`.
It can assume one of the following values:
The default order for sorting directories which match a search path containing
a glob expression found using :command:`find_package`. It can assume one of
the following values:
``NONE``
Default. No attempt is done to sort packages.
Default. No attempt is done to sort directories.
The first valid package found will be selected.
``NAME``
Sort packages lexicographically before selecting one.
Sort directories lexicographically before searching.
``NATURAL``
Sort packages using natural order (see ``strverscmp(3)`` manual),
Sort directories using natural order (see ``strverscmp(3)`` manual),
i.e. such that contiguous digits are compared as whole numbers.
Natural sorting can be employed to return the highest version when multiple
versions of the same library are found by :command:`find_package`. For
example suppose that the following libraries have been found:
versions of the same library are available to be found by
:command:`find_package`. For example suppose that the following libraries
have package configuration files on disk, in a directory of the same name,
with all such directories residing in the same parent directory:
* libX-1.1.0
* libX-1.2.9
@@ -35,4 +38,4 @@ version number ``libX-1.2.10``.
The sort direction can be controlled using the
:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable
(by default decrescent, e.g. lib-B will be tested before lib-A).
(by default descending, e.g. lib-B will be tested before lib-A).

View File

@@ -571,6 +571,14 @@ endif()
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
unset(SortLib_VERSION)
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
FIND_PACKAGE(SortLib 4.0 CONFIG)
IF (NOT "${SortLib_VERSION}" STREQUAL "4.0.0")
message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER gave up too soon! ${SortLib_VERSION}")
endif()
unset(SortLib_VERSION)
unset(CMAKE_FIND_PACKAGE_SORT_ORDER)
unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION)
set(CMAKE_PREFIX_PATH )

View File

@@ -0,0 +1,2 @@
set(SORT_LIB_VERSION 4.0.0)
message("SortLib 4.0.0 config reached")

View File

@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 4.0.0)
if(PACKAGE_FIND_VERSION_MAJOR EQUAL 4)
if(PACKAGE_FIND_VERSION_MINOR EQUAL 0)
set(PACKAGE_VERSION_COMPATIBLE 1)
if(PACKAGE_FIND_VERSION_PATCH EQUAL 0)
set(PACKAGE_VERSION_EXACT 1)
endif()
endif()
endif()