GenEx: Remove unneeded dependencies from target info queries
Only generate a graph dependency between a custom command and a target when the custom command queries for the file path of an artifact of the target. This makes generator expressions such as `TARGET_FILE_DIR` behave the same way as `TARGET_PROPERTY` which never generated a graph dependency.
This commit is contained in:
parent
5294febcaf
commit
f14b390198
@ -102,13 +102,22 @@ The options are:
|
||||
a target later in the command line (i.e. as a command argument rather
|
||||
than as the command to execute).
|
||||
|
||||
Whenever a target is used as a command to execute or is mentioned in a
|
||||
generator expression as a command argument, a target-level dependency
|
||||
will be added automatically so that the mentioned target will be built
|
||||
before any target using this custom command. However this does NOT add
|
||||
a file-level dependency that would cause the custom command to re-run
|
||||
whenever the executable is recompiled. List target names with
|
||||
the ``DEPENDS`` option to add such file-level dependencies.
|
||||
Whenever one of the following target based generator expressions are used as
|
||||
a command to execute or is mentioned in a command argument, a target-level
|
||||
dependency will be added automatically so that the mentioned target will be
|
||||
built before any target using this custom command
|
||||
(see policy :policy:`CMP0112`).
|
||||
|
||||
* ``TARGET_FILE``
|
||||
* ``TARGET_LINKER_FILE``
|
||||
* ``TARGET_SONAME_FILE``
|
||||
* ``TARGET_PDB_FILE``
|
||||
|
||||
This target-level dependency does NOT add a file-level dependency that would
|
||||
cause the custom command to re-run whenever the executable is recompiled.
|
||||
List target names with the ``DEPENDS`` option to add such file-level
|
||||
dependencies.
|
||||
|
||||
|
||||
``COMMENT``
|
||||
Display the given message before the commands are executed at
|
||||
|
@ -81,10 +81,15 @@ The options are:
|
||||
a target later in the command line (i.e. as a command argument rather
|
||||
than as the command to execute).
|
||||
|
||||
Whenever a target is used as a command to execute or is mentioned in a
|
||||
generator expression as a command argument, a target-level dependency
|
||||
will be added automatically so that the mentioned target will be built
|
||||
before this custom target.
|
||||
Whenever one of the following target based generator expressions are used as
|
||||
a command to execute or is mentioned in a command argument, a target-level
|
||||
dependency will be added automatically so that the mentioned target will be
|
||||
built before this custom target (see policy :policy:`CMP0112`).
|
||||
|
||||
* ``TARGET_FILE``
|
||||
* ``TARGET_LINKER_FILE``
|
||||
* ``TARGET_SONAME_FILE``
|
||||
* ``TARGET_PDB_FILE``
|
||||
|
||||
The command and arguments are optional and if not specified an empty
|
||||
target will be created.
|
||||
|
@ -596,6 +596,9 @@ which is just the string ``tgt``.
|
||||
|
||||
``$<TARGET_NAME_IF_EXISTS:tgt>``
|
||||
The target name ``tgt`` if the target exists, an empty string otherwise.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
``$<TARGET_FILE:tgt>``
|
||||
Full path to the ``tgt`` binary file.
|
||||
``$<TARGET_FILE_BASE_NAME:tgt>``
|
||||
@ -633,6 +636,9 @@ which is just the string ``tgt``.
|
||||
The ``tgt`` filename.
|
||||
``$<TARGET_FILE_DIR:tgt>``
|
||||
Directory of the ``tgt`` binary file.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_LINKER_FILE:tgt>``
|
||||
File used when linking to the ``tgt`` target. This will usually
|
||||
be the library that ``tgt`` represents (``.a``, ``.lib``, ``.so``),
|
||||
@ -674,14 +680,26 @@ which is just the string ``tgt``.
|
||||
expression is evaluated on.
|
||||
``$<TARGET_LINKER_FILE_NAME:tgt>``
|
||||
Name of file used to link target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_LINKER_FILE_DIR:tgt>``
|
||||
Directory of file used to link target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_SONAME_FILE:tgt>``
|
||||
File with soname (``.so.3``) where ``tgt`` is the name of a target.
|
||||
``$<TARGET_SONAME_FILE_NAME:tgt>``
|
||||
Name of file with soname (``.so.3``).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_SONAME_FILE_DIR:tgt>``
|
||||
Directory of with soname (``.so.3``).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_PDB_FILE:tgt>``
|
||||
Full path to the linker generated program database file (.pdb)
|
||||
where ``tgt`` is the name of a target.
|
||||
@ -707,17 +725,29 @@ which is just the string ``tgt``.
|
||||
expression is evaluated on.
|
||||
``$<TARGET_PDB_FILE_NAME:tgt>``
|
||||
Name of the linker generated program database file (.pdb).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_PDB_FILE_DIR:tgt>``
|
||||
Directory of the linker generated program database file (.pdb).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_BUNDLE_DIR:tgt>``
|
||||
Full path to the bundle directory (``my.app``, ``my.framework``, or
|
||||
``my.bundle``) where ``tgt`` is the name of a target.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_BUNDLE_CONTENT_DIR:tgt>``
|
||||
Full path to the bundle content directory where ``tgt`` is the name of a
|
||||
target. For the macOS SDK it leads to ``my.app/Contents``, ``my.framework``,
|
||||
or ``my.bundle/Contents``. For all other SDKs (e.g. iOS) it leads to
|
||||
``my.app``, ``my.framework``, or ``my.bundle`` due to the flat bundle
|
||||
structure.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
``$<TARGET_PROPERTY:tgt,prop>``
|
||||
Value of the property ``prop`` on the target ``tgt``.
|
||||
|
||||
|
@ -57,6 +57,7 @@ Policies Introduced by CMake 3.19
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0112: Target file component generator expressions do not add target dependencies. </policy/CMP0112>
|
||||
CMP0111: An imported target with a missing location fails during generation. </policy/CMP0111>
|
||||
CMP0110: add_test() supports arbitrary characters in test names. </policy/CMP0110>
|
||||
CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
|
||||
|
39
Help/policy/CMP0112.rst
Normal file
39
Help/policy/CMP0112.rst
Normal file
@ -0,0 +1,39 @@
|
||||
CMP0112
|
||||
-------
|
||||
|
||||
.. versionadded:: 3.19
|
||||
|
||||
Target file component generator expressions do not add target dependencies.
|
||||
|
||||
The following target-based generator expressions that query for directory or
|
||||
file name components no longer add a dependency on the evaluated target.
|
||||
|
||||
- ``TARGET_FILE_DIR``
|
||||
- ``TARGET_LINKER_FILE_BASE_NAME``
|
||||
- ``TARGET_LINKER_FILE_NAME``
|
||||
- ``TARGET_LINKER_FILE_DIR``
|
||||
- ``TARGET_SONAME_FILE_NAME``
|
||||
- ``TARGET_SONAME_FILE_DIR``
|
||||
- ``TARGET_PDB_FILE_NAME``
|
||||
- ``TARGET_PDB_FILE_DIR``
|
||||
- ``TARGET_BUNDLE_DIR``
|
||||
- ``TARGET_BUNDLE_CONTENT_DIR``
|
||||
|
||||
|
||||
In CMake 3.18 and lower a dependency on the evaluated target of the above
|
||||
generator expressions would be always added. CMake 3.19 and above prefer
|
||||
to not add this dependency. This policy provides compatibility for projects
|
||||
that have not been updated to expect the new behavior.
|
||||
|
||||
The ``OLD`` behavior for this policy is to add a dependency on the evaluated
|
||||
target for the the above generator expressions. The ``NEW`` behavior of
|
||||
this policy is to not add a dependency on the evaluated target for the the
|
||||
above generator expressions.
|
||||
|
||||
This policy was introduced in CMake version 3.19. Unlike many policies,
|
||||
CMake version |release| does *not* warn by default when this policy
|
||||
is not set and simply uses ``OLD`` behavior. See documentation of the
|
||||
:variable:`CMAKE_POLICY_WARNING_CMP0112 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
|
||||
variable to control the warning.
|
||||
|
||||
.. include:: DEPRECATED.txt
|
@ -0,0 +1,17 @@
|
||||
relax-target-generator-expression-dependency-addition
|
||||
-----------------------------------------------------
|
||||
|
||||
* The following target-based generator expressions that query for directory or
|
||||
file name components no longer add a dependency on the evaluated target.
|
||||
See policy :policy:`CMP0112`.
|
||||
|
||||
- ``TARGET_FILE_DIR``
|
||||
- ``TARGET_LINKER_FILE_BASE_NAME``
|
||||
- ``TARGET_LINKER_FILE_NAME``
|
||||
- ``TARGET_LINKER_FILE_DIR``
|
||||
- ``TARGET_SONAME_FILE_NAME``
|
||||
- ``TARGET_SONAME_FILE_DIR``
|
||||
- ``TARGET_PDB_FILE_NAME``
|
||||
- ``TARGET_PDB_FILE_DIR``
|
||||
- ``TARGET_BUNDLE_DIR``
|
||||
- ``TARGET_BUNDLE_CONTENT_DIR``
|
@ -25,6 +25,8 @@ warn by default:
|
||||
policy :policy:`CMP0089`.
|
||||
* ``CMAKE_POLICY_WARNING_CMP0102`` controls the warning for
|
||||
policy :policy:`CMP0102`.
|
||||
* ``CMAKE_POLICY_WARNING_CMP0112`` controls the warning for
|
||||
policy :policy:`CMP0112`.
|
||||
|
||||
This variable should not be set by a project in CMake code. Project
|
||||
developers running CMake may set this variable in their cache to
|
||||
|
@ -1901,6 +1901,70 @@ class ArtifactSonameTag;
|
||||
class ArtifactBundleDirTag;
|
||||
class ArtifactBundleContentDirTag;
|
||||
|
||||
template <typename ArtifactT, typename ComponentT>
|
||||
struct TargetFilesystemArtifactDependency
|
||||
{
|
||||
static void AddDependency(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context)
|
||||
{
|
||||
context->DependTargets.insert(target);
|
||||
context->AllTargets.insert(target);
|
||||
}
|
||||
};
|
||||
|
||||
struct TargetFilesystemArtifactDependencyCMP0112
|
||||
{
|
||||
static void AddDependency(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context)
|
||||
{
|
||||
context->AllTargets.insert(target);
|
||||
cmLocalGenerator* lg = context->LG;
|
||||
switch (target->GetPolicyStatusCMP0112()) {
|
||||
case cmPolicies::WARN:
|
||||
if (lg->GetMakefile()->PolicyOptionalWarningEnabled(
|
||||
"CMAKE_POLICY_WARNING_CMP0112")) {
|
||||
std::string err =
|
||||
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0112),
|
||||
"\nDependency being added to target:\n \"",
|
||||
target->GetName(), "\"\n");
|
||||
lg->GetCMakeInstance()->IssueMessage(MessageType ::AUTHOR_WARNING,
|
||||
err, context->Backtrace);
|
||||
}
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
context->DependTargets.insert(target);
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArtifactT>
|
||||
struct TargetFilesystemArtifactDependency<ArtifactT, ArtifactNameTag>
|
||||
: TargetFilesystemArtifactDependencyCMP0112
|
||||
{
|
||||
};
|
||||
template <typename ArtifactT>
|
||||
struct TargetFilesystemArtifactDependency<ArtifactT, ArtifactDirTag>
|
||||
: TargetFilesystemArtifactDependencyCMP0112
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct TargetFilesystemArtifactDependency<ArtifactBundleDirTag,
|
||||
ArtifactPathTag>
|
||||
: TargetFilesystemArtifactDependencyCMP0112
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct TargetFilesystemArtifactDependency<ArtifactBundleContentDirTag,
|
||||
ArtifactPathTag>
|
||||
: TargetFilesystemArtifactDependencyCMP0112
|
||||
{
|
||||
};
|
||||
|
||||
template <typename ArtifactT>
|
||||
struct TargetFilesystemArtifactResultCreator
|
||||
{
|
||||
@ -2153,8 +2217,10 @@ struct TargetFilesystemArtifact : public TargetArtifactBase
|
||||
if (!target) {
|
||||
return std::string();
|
||||
}
|
||||
context->DependTargets.insert(target);
|
||||
context->AllTargets.insert(target);
|
||||
// Not a dependent target if we are querying for ArtifactDirTag,
|
||||
// ArtifactNameTag, ArtifactBundleDirTag, and ArtifactBundleContentDirTag
|
||||
TargetFilesystemArtifactDependency<ArtifactT, ComponentT>::AddDependency(
|
||||
target, context);
|
||||
|
||||
std::string result =
|
||||
TargetFilesystemArtifactResultCreator<ArtifactT>::Create(target, context,
|
||||
|
@ -330,6 +330,10 @@ class cmMakefile;
|
||||
SELECT(POLICY, CMP0111, \
|
||||
"An imported target with a missing location fails during " \
|
||||
"generation.", \
|
||||
3, 19, 0, cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0112, \
|
||||
"Target file component generator expressions do not add target " \
|
||||
"dependencies.", \
|
||||
3, 19, 0, cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
@ -363,7 +367,8 @@ class cmMakefile;
|
||||
F(CMP0099) \
|
||||
F(CMP0104) \
|
||||
F(CMP0105) \
|
||||
F(CMP0108)
|
||||
F(CMP0108) \
|
||||
F(CMP0112)
|
||||
|
||||
/** \class cmPolicies
|
||||
* \brief Handles changes in CMake behavior and policies
|
||||
|
@ -2,8 +2,10 @@ include(RunCMake)
|
||||
|
||||
run_cmake(TARGET_FILE-recursion)
|
||||
run_cmake(OUTPUT_NAME-recursion)
|
||||
run_cmake(TARGET_FILE_PREFIX)
|
||||
run_cmake(TARGET_FILE_DIR-dependency)
|
||||
run_cmake(TARGET_FILE_DIR-no-dependency)
|
||||
run_cmake(TARGET_FILE_PREFIX-imported-target)
|
||||
run_cmake(TARGET_FILE_PREFIX)
|
||||
run_cmake(TARGET_FILE_PREFIX-non-valid-target)
|
||||
run_cmake(TARGET_LINKER_FILE_PREFIX-non-valid-target)
|
||||
run_cmake(TARGET_FILE_SUFFIX)
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,6 @@
|
||||
.*Policy CMP0112 is not set.*
|
||||
.*Dependency being added to target.*
|
||||
.*exec1.*
|
||||
CMake Error: The inter-target dependency graph.*
|
||||
.*"exec1" of type EXECUTABLE
|
||||
depends on "copyFile" \(strong\)
|
@ -0,0 +1,12 @@
|
||||
set(CMAKE_POLICY_WARNING_CMP0112 TRUE)
|
||||
|
||||
enable_language (C)
|
||||
|
||||
add_executable (exec1 empty.c)
|
||||
|
||||
add_custom_target(copyFile
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/empty.c"
|
||||
"$<TARGET_FILE_DIR:exec1>/$<TARGET_FILE_BASE_NAME:exec1>_e.c"
|
||||
)
|
||||
add_dependencies(exec1 copyFile)
|
@ -0,0 +1,12 @@
|
||||
cmake_policy(SET CMP0112 NEW)
|
||||
|
||||
enable_language (C)
|
||||
|
||||
add_executable (exec1 empty.c)
|
||||
|
||||
add_custom_target(copyFile
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/empty.c"
|
||||
"$<TARGET_FILE_DIR:exec1>/$<TARGET_FILE_BASE_NAME:exec1>_e.c"
|
||||
)
|
||||
add_dependencies(exec1 copyFile)
|
@ -32,6 +32,7 @@
|
||||
\* CMP0104
|
||||
\* CMP0105
|
||||
\* CMP0108
|
||||
\* CMP0112
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
Loading…
Reference in New Issue
Block a user