find_package: Also sort Framework matches

Add cmAnyDirectoryListGenerator, which matches any directory but also
sorts matches in the same manner as cmProjectDirectoryListGenerator.
Modify SearchFrameworkPrefix to use this, in combination with a literal
path (cmAppendPathSegmentGenerator), instead of cmFileListGeneratorGlob
(which is removed, as it is no longer used). This improves the
consistency of when sorting is available.

This uses cmDirectoryListGenerator's new ability to match anything, as
mentioned in the previous commit.
This commit is contained in:
Matthew Woehlke
2024-10-24 13:42:42 -04:00
parent e90f60f864
commit 6f3dc1161a
7 changed files with 71 additions and 48 deletions

View File

@@ -507,13 +507,12 @@ 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
For search paths which contain glob expressions (``*``), the order in which
directories matching the glob are searched 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 glob matches. For example, if
the file system contains the package configuration files
::
@@ -543,6 +542,14 @@ before calling ``find_package``.
Added the ``CMAKE_FIND_USE_<CATEGORY>`` variables to globally disable
various search locations.
.. versionchanged:: 3.32
The variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` now also control the order
in which ``find_package`` searches directories matching the glob expression
in the search paths ``<prefix>/<name>.framework/Versions/*/Resources/``
and ``<prefix>/<name>.framework/Versions/*/Resources/CMake``. In previous
versions of CMake, this order was unspecified.
.. include:: FIND_XXX_ROOT.txt
.. include:: FIND_XXX_ORDER.txt

View File

@@ -16,7 +16,6 @@
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
@@ -337,47 +336,18 @@ private:
const cm::string_view Extension;
};
class cmFileListGeneratorGlob
class cmAnyDirectoryListGenerator : public cmProjectDirectoryListGenerator
{
public:
cmFileListGeneratorGlob(cm::string_view pattern)
: Pattern(pattern)
cmAnyDirectoryListGenerator(cmFindPackageCommand::SortOrderType so,
cmFindPackageCommand::SortDirectionType sd)
: cmProjectDirectoryListGenerator(this->EmptyNamesList, so, sd, false)
{
}
std::string GetNextCandidate(const std::string& parent)
{
if (this->Files.empty()) {
// Glob the set of matching files.
std::string expr = cmStrCat(parent, this->Pattern);
cmsys::Glob g;
if (!g.FindFiles(expr)) {
return {};
}
this->Files = g.GetFiles();
this->Current = this->Files.cbegin();
}
// Skip non-directories
for (; this->Current != this->Files.cend() &&
!cmSystemTools::FileIsDirectory(*this->Current);
++this->Current) {
}
return (this->Current != this->Files.cend()) ? *this->Current++
: std::string{};
}
void Reset()
{
this->Files.clear();
this->Current = this->Files.cbegin();
}
private:
cm::string_view Pattern;
std::vector<std::string> Files;
std::vector<std::string>::const_iterator Current;
// NOTE `cmDirectoryListGenerator` needs to hold a reference to this
std::vector<std::string> EmptyNamesList;
};
#if defined(__LCC__)
@@ -2776,7 +2746,8 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
cmMacProjectDirectoryListGenerator{ this->Names, ".framework"_s };
auto rGen = cmAppendPathSegmentGenerator{ "Resources"_s };
auto vGen = cmAppendPathSegmentGenerator{ "Versions"_s };
auto grGen = cmFileListGeneratorGlob{ "/*/Resources"_s };
auto anyGen =
cmAnyDirectoryListGenerator{ this->SortOrder, this->SortDirection };
// <prefix>/Foo.framework/Resources/
if (TryGeneratedPaths(searchFn, prefix, fwGen, rGen)) {
@@ -2789,12 +2760,13 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
}
// <prefix>/Foo.framework/Versions/*/Resources/
if (TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen)) {
if (TryGeneratedPaths(searchFn, prefix, fwGen, vGen, anyGen, rGen)) {
return true;
}
// <prefix>/Foo.framework/Versions/*/Resources/CMake/
return TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen, iCMakeGen);
return TryGeneratedPaths(searchFn, prefix, fwGen, vGen, anyGen, rGen,
iCMakeGen);
}
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)

View File

@@ -550,10 +550,10 @@ endif()
############################################################################
##Test FIND_PACKAGE using sorting
set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
FIND_PACKAGE(SortLib CONFIG)
IF (NOT "${SortLib_VERSION}" STREQUAL "3.1.1")
message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Name Asc! ${SortLib_VERSION}")
@@ -579,6 +579,28 @@ IF (NOT "${SortLib_VERSION}" STREQUAL "4.0.0")
endif()
unset(SortLib_VERSION)
set(SortFramework_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
FIND_PACKAGE(SortFramework CONFIG)
IF (NOT "${SortFramework_VERSION}" STREQUAL "3.1.1")
message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Framework Name Asc! ${SortFramework_VERSION}")
endif()
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
unset(SortFramework_VERSION)
set(SortFramework_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
FIND_PACKAGE(SortFramework CONFIG)
IF (NOT "${SortFramework_VERSION}" STREQUAL "3.10.1")
message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Framework Natural! Dec ${SortFramework_VERSION}")
endif()
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
unset(SortFramework_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_FRAMEWORK_VERSION 3.1.1)
message("SortFramework 3.1.1 config reached")

View File

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

View File

@@ -0,0 +1,2 @@
set(SORT_FRAMEWORK_VERSION 3.10.1)
message("SortFramework 3.10.1 config reached")

View File

@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 3.10.1)
if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3)
if(PACKAGE_FIND_VERSION_MINOR EQUAL 10)
set(PACKAGE_VERSION_COMPATIBLE 1)
if(PACKAGE_FIND_VERSION_PATCH EQUAL 1)
set(PACKAGE_VERSION_EXACT 1)
endif()
endif()
endif()