Modify the `export(EXPORT)` and `install(PACKAGE_INFO)` commands to
actually enforce that certain arguments must be non-empty. With respect
to `export`, this is mainly targeted at CPS export, but ends up
affecting all flavors of `export(EXPORT)` because that is the level at
which argument parsing is performed.
Also, add unit tests to verify that the new rejection of arguments with
missing or empty values is working, update the existing tests due to
changes in error reporting, and remove no-longer-needed manual
validation of an empty `PACKAGE_INFO` argument.
Modify argument handling in `HandleExportMode` to explicitly allow an
empty `NAMESPACE`. In practice, this was already the case because we
weren't actually checking for the parsing errors that would cause the
`NonEmpty` decoration to reject an empty value, but we want to be able
to do that going forward, and changing the behavior for `NAMESPACE`
would potentially break legitimate uses. (In particular, one of our unit
tests relies on the current behavior.)
Remove literal text "subcommand" from error messages. Most other
commands report errors like "<command> <subcommand> <message>", where
the message does not include the literal text "subcommand". The `export`
command was one of two exceptions to this.
While I'm unsure about why `cmPackageInfoArguments` was originally
written the way it was, in its current form, the way command sub-parsers
work, the parser never considers arguments associated with a sub-parser
if the sub-parser keyword isn't present. This means that the arguments
associated with `cmPackageInfoArguments` are treated as unknown, and the
logic to reject them being set if `PACKAGE_INFO` is not present can
never actually execute. Therefore, remove it, and remove the associated
(and effectively useless) `enable` argument to its `Check` method.
Instead, ensure that the package name is actually specified. The only
case in which the parser will create the `optional` associated with the
sub-parser arguments is if the relevant keyword (i.e. `PACKAGE_INFO`) is
present. However, while the associated value is `NonEmpty`, the way we
are using the parser does not actually enforce this, and it looks like a
correct fix may be a breaking change. Therefore, enforce it manually for
now.
Refactoring in commit 998495cb49 (cmExportCommand: Port to
cmSubcommandTable, 2025-07-15) accidentally removed support for the
`EXPORT_LINK_INTERFACE_LIBRARIES` argument. Restore it with a test.
Fixes: #27302
Previously, the `cmExportCommand` parser did not use `cmSubcommandTable`
to distinguish between its `TARGETS`, `EXPORT`, `SETUP`, and `PACKAGE`
modes. This created a maintenance burden when updating or adding
functionality.
Refactor the parser to use a subcommand for each keyword. This new
structure mirrors the design of `cmInstallCommand` and simplifies future
development.
Modify {export,install}(PACKAGE_INFO) commands to inherit version
information from the current project in situations where it seems
reasonable to do so. Add an option to explicitly request inheritance
from a specific project.
This leverages the recently added project(COMPAT_VERSION).
CPS package metadata involves a fair amount of passing around a
particular set of values, as well as shared argument handling, which is
only going to increase as additional features are added. In order to
reduce code duplication (now and going forward), create a helper class
to handle the shared argument parsing and to serve as a container to
pass metadata values.
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
In order to support generation of Common Package Specifications, the
mechanisms CMake uses to export package information need to be made more
abstract. The prior commits began this refactoring; this continues by
(actually) restructuring the classes used to generate the actual export files.
To minimize churn, this introduces virtual base classes and
diamond inheritance in order to separate logic which is format-agnostic
but depends on the export mode (build-tree versus install-tree) from
logic which is format-specific but mode-agnostic.
This could probably be refactored further to use helper classes instead,
and a future commit may do that, however an initial attempt to do that
was proving even more invasive, such that this approach was deemed more
manageable.
While we're at it, add 'const' in more places where possible.
a820877d03 errors: avoid constructing a stream before getting the last error
5cf7018af6 cmFileCopier: remember error statuses and get their strings
0639a32d3a cmFileTimes: return status codes from APIs
Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !9023
The latter call is no longer post-bootstrap only since 596439b1bb
(cmCustomCommandGenerator: Add option to transform depfile, 2020-10-05)
via !5325. Convert callers to just use `cmCryptoHash` directly and
remove the bootstrap guard.
Previously bindings to `std::vector<std::string>` required at least one
value. Some clients have been filtering `keywordsMissingValue` to
support keywords followed by empty lists. Instead, require clients to
specify whether a keyword's list can be empty as part of the binding
type.
This directory will be used to store build-discovered information about
targets such as the modules provided by the files in the relevant
`FILE_SET` types.
A directory is used because basing the name on a `<FILE_NAME>-*.cmake`
pattern makes it end up being globbed in the configuration-dependent
information mechanism. Since old modules and targets may be around,
unconditionally including them may refer to targets that do not actually
exist.
CMake 3.16 and below allow multiple `export()` calls with the same output
file even without using `APPEND`. The implementation worked by accident
by leaking memory. Refactoring in commit 5444a8095d (cmGlobalGenerator:
modernize memrory managemenbt, 2019-12-29, v3.17.0-rc1~239^2) cleaned up
that memory leak and converted it to a use-after-free instead.
The problem is caused by using the `cmGlobalGenerator::BuildExportSets`
map to own `cmExportBuildFileGenerator` instances. It can own only
one instance per output FILE name at a time, so repeating use of the
same file now frees the old `cmExportBuildFileGenerator` instance
and leaves the pointer in the `cmMakefile::ExportBuildFileGenerators`
vector dangling. Move ownership of the instances into `cmMakefile`'s
vector since its entries are not replaced on a repeat output FILE.
In future work we should introduce a policy to error out on this case.
For now simply fix the use-after-free to restore CMake <= 3.16 behavior.
Fixes: #20469
This patch is generated by a python script that uses regular expressions to
search for string concatenation patterns of the kind
```
std::string str = <ARG0>;
str += <ARG1>;
str += <ARG2>;
...
```
and replaces them with a single `cmStrCat` call
```
std::string str = cmStrCat(<ARG0>, <ARG1>, <ARG2>, ...);
```
If any `<ARGX>` is itself a concatenated string of the kind
```
a + b + c + ...;
```
then `<ARGX>` is split into multiple arguments for the `cmStrCat` call.
If there's a sequence of literals in the `<ARGX>`, then all literals in the
sequence are concatenated and merged into a single literal argument for
the `cmStrCat` call.
Single character strings are converted to single char arguments for
the `cmStrCat` call.
`std::to_string(...)` wrappings are removed from `cmStrCat` arguments,
because it supports numeric types as well as string types.
`arg.substr(x)` arguments to `cmStrCat` are replaced with
`cm::string_view(arg).substr(x)`
Refactoring in commit f5acecaa6f (cmExportCommand: Port to
cmArgumentParser, 2019-03-23, v3.15.0-rc1~270^2~3) broke the `export`
command's support for specifying `TARGETS` with no entries. Fix it and
add a test case.
Fixes: #19415
The user package registry populated by the `export()` command causes
side effects outside the build and source directories. Such effects
should be opt-in rather than op-out. Introduce a policy to change
default behavior of `export(PACKAGE)` to do nothing.