Browse Source

Merge topic 'fix-path-search-doc'

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

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Acked-by: Matthew Woehlke <[email protected]>
Merge-request: !9930
Brad King 1 year ago
parent
commit
3ef7198e43

+ 36 - 16
Help/command/find_package.rst

@@ -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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

+ 11 - 8
Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst

@@ -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).

+ 8 - 0
Tests/FindPackageTest/CMakeLists.txt

@@ -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 )

+ 2 - 0
Tests/FindPackageTest/lib/SortLib-4.0.0/SortLibConfig.cmake

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

+ 9 - 0
Tests/FindPackageTest/lib/SortLib-4.0.0/SortLibConfigVersion.cmake

@@ -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()