Refactor `cmFindPackageStack` to track additional metadata
about <package> found. This includes two new fields,
`Version` and `Location` which correspond to package version and path.
The remaining package information will be implemented in a later commit
As mentioned in the previous commit, we would like to record additional
information in the find-package stack, but we don't have the information
at the point a stack entry is created. This necessitates making the
stack mutable. However, in order to restrict mutation, do not directly
expose the mutable value, and instead arrange for it to be accessible
only via cmFindPackageStackRAII (renamed and extracted from cmMakefile).
This ensures that mutation can only happen while the stack is being
built.
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
557c44b93e cmStrCat: use character literals where possible
23779057fd cmStrCat: combine neighboring arguments where possible
483d13daf4 ast-grep: add a rule to turn strings into characters
61743471d9 ast-grep: add a rule to find adjacent string literals in cmStrCat calls
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !10790
fdccb8846c cmFindCommonDebugState: adopt event writing logic
716dfd3b1e cmFindCommon: track debug state as an object
c6d097135d cmFindBaseDebugState: factor out a base class
bd5cb1f8e6 cmFindCommon: use `DebugModeEnabled` to query for debug mode
76ea613f4c cmFindBaseDebugState: get the command name directly from the object
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !10713
In commit e90f60f864 (find_package: Don't glob certain macOS paths,
2024-10-23, v4.0.0-rc1~579^2~1) we changed the name matching logic of
`find_package` to check if a possible match is a directory before
checking whether the name is a match. In some situations, this results
in unnecessarily calling `stat` for a very large number of files, which
can be extremely slow on some systems (especially Windows). Fix this by
making the check the last thing we do before accepting a possible match.
Fixes: #26817
Keep track of CPS files we have imported in CMake's state, and use this
(instead of the prior, temporary work-around that used `<name>_CONFIG`)
as a guard for trying to import more than once from the same file. This
has two advantages; first, it is robust against finding the same package
name in different locations in alternating searches, and second, it
allows us to load additional appendices associated with a root package
that has already been loaded.
Fixes: #26731
Do not try to load a CPS file if we've already loaded the same file.
This only works if the current `find_package` call selects the same file
as the previous most recent call, and if the user has not meddled with
the `<name>_CONFIG` variable.
Issue: #26731
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
Modify how CMake handles required components of a CPS transitive
dependency to not pass them as COMPONENTS if a CMake-script package is
found as the resolved dependency. This is necessary as many CMake-script
package description files do not treat component requests as target
requests (which, in CPS-land, they effectively are), but do implement
logic to mark themselves 'not found' if requested components are
missing. As a result, passing in the required targets as required
components is likely to cause the dependency to be spuriously not found
if it is only available via a CMake-script package configuration file.
Fix this by introducing a new 'required targets' concept, and by passing
CPS component requirements as both required targets and optional
components. The latter serves as a hint for packages that might provide
only a subset of themselves. The former is used to post-validate a
CMake-script package, or is folded on-the-fly into required components
when considering CPS packages.
Note that this functionality is not exposed to the user at this time,
and is only used when resolving transitive dependencies for a CPS
package.
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
Update cmPackageInfoReader's version parsing to more fully conform to
the specification and to reject non-conforming version strings. Start
adding framework to support version schemas other than "simple". Fix how
cmFindPackageCommand extracts version parts to not fail if more than
four parts are present.
The logic to extract the version of a CPS file into the location used to
record files that were considered but rejected was happening too late,
resulting in rejected files unnecessarily reporting their version as
"unknown". Fix this by filling the variable sooner.
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.
Run the `clang-format.bash` script to update all our C and C++ code to a
new style defined by `.clang-format`, now with "east const" enforcement.
Use `clang-format` version 18.
* If you reached this commit for a line in `git blame`, re-run the blame
operation starting at the parent of this commit to see older history
for the content.
* See the parent commit for instructions to rebase a change across this
style transition commit.
Issue: #26123
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.
A root path like `/` or `c:/` needs to end in a slash. Revise our
prefix search logic to maintain a trailing slash instead of removing one
just to add it again.
Implement logic (partly adapted from the 2023 proof-of-concept) to
actually parse CPS files and generate imported targets. Implement logic
to locate and load supplemental files. Adjust prefix handling to require
that the CPS file provides sufficient information to translate the
prefix placeholder into a meaningful path. (Note that this corresponds
to a change in the specification.)
Add a helper class to read CPS files. Use this to teach find_package how
to consider and accept .cps files in its search. (Note that no version
testing is performed at this time.) Add a simple test that we can find a
package from a .cps file and correctly extract the version information.
Note that this doesn't actually import anything from CPS yet.
Teach find_package to search CPS search paths, and to look for CPS file
names. Modify the set of file names to also include the file type (CPS
or CMake-script). Modify the search function to allow specifying which
file type(s) to consider.
During full path search, each possible path is searched for only one of
the two possible file types. However, subsequent runs, or when
considering a user-specified path (<name>_DIR), CMake will look for both
file types.
Note that this only adds the new path search logic as described above;
CMake does not yet know how to read CPS files, and there is a high
likelihood that Bad Things will happen if it tries. However, this seemed
like a good place to checkpoint.