summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2020-08-18 12:25:31 (GMT)
committerBrad King <brad.king@kitware.com>2020-09-01 13:25:19 (GMT)
commitf14b390198222f5d7eca9e5109fabcb0188da762 (patch)
treead67bb4af6f85bf6fb2f4b157881a2f1e1a4a9da
parent5294febcaf378589dba49801321d19f93f67464e (diff)
downloadCMake-f14b390198222f5d7eca9e5109fabcb0188da762.zip
CMake-f14b390198222f5d7eca9e5109fabcb0188da762.tar.gz
CMake-f14b390198222f5d7eca9e5109fabcb0188da762.tar.bz2
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.
-rw-r--r--Help/command/add_custom_command.rst23
-rw-r--r--Help/command/add_custom_target.rst13
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst30
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/policy/CMP0112.rst39
-rw-r--r--Help/release/dev/relax-target-generator-expression-dependency-addition.rst17
-rw-r--r--Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst2
-rw-r--r--Source/cmGeneratorExpressionNode.cxx70
-rw-r--r--Source/cmPolicies.h7
-rw-r--r--Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-stderr.txt6
-rw-r--r--Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency.cmake12
-rw-r--r--Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-no-dependency.cmake12
-rw-r--r--Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt1
15 files changed, 223 insertions, 15 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 9279748..231f9da 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -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
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index 56ab414..2eb0c88 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -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.
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c7f6b27..5b55cac 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -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``.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index ce8969b..cd1d4d3 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -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>
diff --git a/Help/policy/CMP0112.rst b/Help/policy/CMP0112.rst
new file mode 100644
index 0000000..3eab6d2
--- /dev/null
+++ b/Help/policy/CMP0112.rst
@@ -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
diff --git a/Help/release/dev/relax-target-generator-expression-dependency-addition.rst b/Help/release/dev/relax-target-generator-expression-dependency-addition.rst
new file mode 100644
index 0000000..6d30596
--- /dev/null
+++ b/Help/release/dev/relax-target-generator-expression-dependency-addition.rst
@@ -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``
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index de71d0e..d35595a 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -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
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index fdc8f29..d9cdf11 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -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,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 1a12dab..bf6e531 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -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
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
index ccec633..55b0f9b 100644
--- a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
@@ -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)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-stderr.txt
new file mode 100644
index 0000000..0a79032
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency-stderr.txt
@@ -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\)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency.cmake
new file mode 100644
index 0000000..e18ccd9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-dependency.cmake
@@ -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)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-no-dependency.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-no-dependency.cmake
new file mode 100644
index 0000000..e048e10
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_DIR-no-dependency.cmake
@@ -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)
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 2454f25..fe13e81 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -32,6 +32,7 @@
\* CMP0104
\* CMP0105
\* CMP0108
+ \* CMP0112
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)