For each build setting property (such as `COMPILE_DEFINITIONS` or
`INCLUDE_DIRECTORIES`), the value of `$<TARGET_PROPERTY:target,prop>`
includes the values of the corresponding `INTERFACE_*` usage requirement
property from the transitive closure of link libraries of the target.
Previously we computed this by constructing a generator expression
string like `$<TARGET_PROPERTY:lib,INTERFACE_COMPILE_DEFINITIONS>` and
recursively evaluating it with the generator expression engine. Avoid
the string construction and parsing by using the dedicated evaluation
method `cmGeneratorTarget::EvaluateInterfaceProperty`.
Issue: #18964, #18965
In large projects the generation process spends a lot of time evaluating
usage requirements through transitive interface properties on targets.
This can be seen in a contrived example with deep dependencies:
set(prev "")
foreach(i RANGE 1 500)
add_library(a${i} a.c)
target_compile_definitions(a${i} PUBLIC A${i})
target_link_libraries(a${i} PUBLIC ${prev})
set(prev a${i})
endforeach()
For each usage requirement (such as `INTERFACE_COMPILE_DEFINITIONS` or
`INTERFACE_INCLUDE_DIRECTORIES`), the value of the generator expression
`$<TARGET_PROPERTY:target,prop>` includes the values of the same
property from the transitive closure of link libraries of the target.
Previously we computed this by constructing a generator expression
string like `$<TARGET_PROPERTY:lib,INTERFACE_COMPILE_DEFINITIONS>` and
recursively evaluating it with the generator expression engine. Avoid
the string construction and parsing by creating and using a dedicated
evaluation method `cmGeneratorTarget::EvaluateInterfaceProperty` that
looks up the properties directly.
Issue: #18964, #18965
An old workaround for `std::allocator_traits<>::value_type` lints from
IWYU on `std::vector<>` usage breaks IWYU's handling of `<memory>`.
Convert the workaround to use the same approach we already use for a
workaround of `std::__decay_and_strip<>::::__type` lints. Then update
the `<memory>` inclusions to follow the now-correct IWYU lints.
For special properties like `INCLUDE_DIRECTORIES`, the pointer returned
by `cmTarget::GetProperty` is only valid until the next time the same
special property is queried on *any* target. When evaluating a nested
`TARGET_PROPERTY` generator expression we may look up such a property
more than once on different targets. Fix `TargetPropertyNode::Evaluate`
to store the lookup result in locally owned memory earlier.
Fixes: #19286
b53766b205 CUDA: Support compiler id and version generator expressions
b544e34af6 All VersionNode use the same capitalization pattern
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3085
Extend the genex added by commit ca6ba3fee5 (Genex: Add a SHELL_PATH
expression, 2015-09-24, v3.4.0-rc1~37^2) to accept a `;`-list of paths,
convert them all, and generate a list separated by the native shell
`PATH``` separator.
Suppress some cases in `Source/cmGeneratorExpressionNode.cxx` and
`Source/cmUVHandlePtr.h` where a few older compilers require a
user-defined default constructor (with `{}`).
Adds `Fortran_COMPILER_ID` and `Fortran_COMPILER_VERSION` generator
expression support to match equivalent `C_COMPILER_ID`,
`CXX_COMPILER_ID`, `C_COMPILER_VERSION`, and `CXX_COMPILER_VERSION`
support.
This is very helpful in the case where the C/C++ compiler suite is a
different type of compiler from the platform Fortran compiler and
projects use generator expressions to assign compiler flags and
definitions. (e.g. `GNU` C/C++ and `SunPro` Fortran on Linux)
The old behavior of $<IN_LIST:...> is inconsistent with that of
if(IN_LIST), in that it does not find an empty search item even if
the list contains empty items. This change adds a new policy to
correctly handle empty items and make the behavior more consistent
with if(IN_LIST).
Fixes: #18556
While collecting usage requirements from the `INTERFACE_*` properties of
directly linked targets, we internally generate `TARGET_PROPERTY:` and
`TARGET_OBJECTS:` generator expressions to refer to those properties on
those targets. At the point we generate these expressions we already
have a pointer to an exact `cmGeneratorTarget` instance.
Switch from using the target name in these generator expressions to
using an internal unique name generated for each `cmGeneratorTarget`
instance to be referenced. This avoids depending on the user-facing
target name to find the same target we already have.
If two imported targets in different directories have the same name we
should still be able to propagate transitive usage requirements from
both. Fix the DAG checker to work with target pointers instead of
target names since the pointers will not be duplicated even if the names
are.
Fixes: #18345