Improve how find_package reports the list of candidate package
configuration files that were considered but rejected to include a
reason for rejection. For CPS in particular, this allows the user to
tell if a CPS file was rejected due to a version mismatch, missing
required components, or because the file could not be read.
While we do not try to report more detail for why cmPackageInfoReader
rejected a file, the possible reasons are usually easy enough to
distinguish:
- The file is so malformed that we cannot read a JSON object.
- The schema version is not a version that CMake understands.
- The root object does not contain a string named "name".
- The root object does not contain an object named "components".
- Prefix resolution failed.
Three of these can only result from a file that fails schema validation.
In commit 9d44a77454 (find_*: Explicitly normalize found paths as they
exist on disk, 2024-10-17, v4.0.0-rc1~597^2~1), we removed path
normalization from the internal `cmSearchPath::AddPathInternal` helper.
Most call sites were updated to normalize input paths first, but search
paths derived from `<PackageName>_ROOT` CMake variables are no longer
normalized. Instead we normalize the path to the file found after
searching.
When `find_package` "config" mode considers a candidate CMake package
configuration file, normalize its path before loading the adjacent
package version file so that the latter is loaded by absolute path.
Otherwise `cmMakefile::ReadDependentFile` interprets a relative path
with respect to the current source directory rather than the current
working directory.
Fixes: #27279
This implements a limited exception mechanism for find_package() via
the UNWIND_INCLUDE keyword.
When package discovery via find_package(UNWIND_INCLUDE) fails the
StateSnapshot is updated to an UNWINDING state. In this state further
calls to find_package() and include() are forbidden. While in the
UNWINDING state, the include() command immediately calls
SetReturnInvoked() whenever it is reached.
The UNWINDING state is reset when a parent call to find_package() is
reached.
Fixes: #26897
Historically, find_package() does not guarantee the order in which directories
matching a search path containing a glob expression are processed in - the
"first valid package" will be selected if there are multiple candidates. In such
cases, which package is chosen is completely random and can change, potentially
leading to build failures and reproducibility issues. This is rather unexpected
and confusing for developers.
Now that CMake has bumped its major version, it's a good time to change default
sort order and direction could be changed to natural sorting with a descending
order. That will result in the newest version of a library being picked in case
there are multiple ones available.
Test behavior with `Find` module packages which chain to config modules.
This emulates CMake's shipped modules which support config packages
provided by modern upstreams.
Fix logic to populate required and optional components from CMake
variables when `find_package` is called in a nested context.
This was broken in commit e2a6416622 (find_package: Refactor in support
of recursion, 2024-11-29, v4.0.0-rc1~356^2), which promoted the
component sets from locals (in cmFindPackageCommand::InitialPass) to
member variables. Previously, in a nested context, these sets were
simply not filled, and we relied on the variables indicating component
requirement to already be set. When logic was added to properly fill the
sets (which is needed for CPS), it blindly dumped all components into
the required set, without actually checking whether the context had
marked the components as required or optional.
Fixes: #26824
This adds a `CMAKE_FIND_REQUIRED` variable which causes `find_package`,
`find_path`, `find_file`, `find_library` and `find_program` to be
considered `REQUIRED` by default.
It also introduces an `OPTIONAL` keyword to those commands, allowing
them to ignore the value of this variable.
Issue: #26576
The set of RunCMake/find_package tests is quite large, which makes
development and management less efficient. While this could probably
stand additional refactoring, split out just the CPS tests for now, as
those are currently under active development.
Implement finding components of CPS packages. Specifically, reject any
candidate packages that don't provide all required components, and
ignore appendices that don't provide requested (required or optional)
components. This applies to both top-level searches and also searching
for package dependencies.
Fix find_package to set an error message when trying to find
dependencies of a CPS package fails. This fixes the command previously
reporting "find_package unknown error" for such failures.
Implement finding dependencies of CPS packages. This is done by setting
up additional `cmFindPackageCommand` instances which are used to look
for a parent package's dependencies.
Some error messages (Windows registry related) of the `find_xxx` and
`cmake_host_system_information` commands, reported keywords in quotes,
while most commands did not.
The OLD behaviors of all policies are deprecated, but only by
documentation. Add an explicit deprecation diagnostic for policies
introduced in CMake 3.24 and below to encourage projects to port
away from setting policies to OLD.
find_package()'s debug mode provides information about which
prefixes are searched, but not which roots are prepended to each
prefix. Display this information if debugging is enabled.
Upstream Boost 1.70 and above provide a proper `BoostConfig.cmake`
package configuration file. Packages for all major distros now
provide it in at least one LTS release. Add a policy to pretend
that the `FindBoost` module does not exist so that projects calling
`find_package(Boost)` use the upstream package directly.
Closes: #19402
MSYS2 and similar MinGW/MSYS distributions define development
environments with a `MSYSTEM` environment variable. Each such
environment has a documented installation prefix for its packages,
often provided by a `MSYSTEM_PREFIX` environment variable.
Since commit 84a25fc263 (cmake_host_system_information: Add
MSYSTEM_PREFIX query, 2023-09-08) we can look up this prefix.
Add `$MSYSTEM_PREFIX/local` and `$MSYSTEM_PREFIX` to our system search
prefixes when targeting MinGW under `MSYSTEM` environments. This is
their equivalent to `/usr/local` and `/usr`, which we search by default
on UNIX systems.
Issue: #24216
The `FindPythonInterp` and `FindPythonLibs` modules have been deprecated
since CMake 3.12. Add a policy to pretend they do not exist in order to
encourage projects to port to `FindPython` or `FindPython{2,3}`.
FindCUDA's custom commands invoke `nvcc`, which invokes `cl`. Under VS
this is done without a `/FS` flag, so `.pdb` generation races if we
use `BuildInParallel`. The FindCUDA module has already been removed by
policy CMP0146 after being deprecated since CMake 3.10, so it is
simplest to just disallow this combination of features.
Issue: #24576
The `FindCUDA` module has been deprecated since CMake 3.10.
Add a policy to pretend it doesn't exist in order to encourage
projects to port away from it.
Extend commit eb35d8884b (find_package: Use PackageName_ROOT variables
as search prefixes, 2018-03-15, v3.12.0-rc1~349^2) to also check
upper-case `<PACKAGENAME>_ROOT` variables. Add policy `CMP0144` to
enable the behavior in a compatible way.
Fixes: #24403
For policy-specific tests, use the version before the policy was
introduced. Otherwise, use 3.5 where possible.
Also, remove `cmake_minimum_required()` and `project()` calls from
individual cases where they are handled by `CMakeLists.txt`.
The `PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/(Foo|foo|FOO).*/` search
path is the similar to the one already exists
`PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/`.
Allow FetchContent_MakeAvailable() to try a call to
find_package() first, or redirect a find_package() call to
FetchContent_MakeAvailable(). The user can set variables
to control which of these are allowed or tried by default.
Fixes: #21687