summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Eiband <daniel.eiband@brainlab.com>2019-09-11 10:45:50 (GMT)
committerDaniel Eiband <daniel.eiband@brainlab.com>2019-09-12 14:03:12 (GMT)
commitf6574c9a816ffda7d9ff8c3f2e4ce0485cf28894 (patch)
treea79820bdc7fa07f7bc465b275e458542a263b3e2
parent2edb0b71edd36031f2fcc0b65633c1c16f8e9268 (diff)
downloadCMake-f6574c9a816ffda7d9ff8c3f2e4ce0485cf28894.zip
CMake-f6574c9a816ffda7d9ff8c3f2e4ce0485cf28894.tar.gz
CMake-f6574c9a816ffda7d9ff8c3f2e4ce0485cf28894.tar.bz2
Depend: Hook up automatic target-level dependencies via byproducts
Target-level dependencies to utility targets are added from another target if the other target requires a byproduct of the utility target or if it requires a byproduct of PRE_BUILD, PRE_LINK, or POST_BUILD build events of a target. Issue: #19005
-rw-r--r--Help/command/add_custom_command.rst6
-rw-r--r--Help/command/add_custom_target.rst6
-rw-r--r--Source/cmGeneratorTarget.cxx35
3 files changed, 29 insertions, 18 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index ed321fc..ab2a023 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -68,9 +68,6 @@ The options are:
order-only dependencies to ensure the byproducts will be
available before their dependents build.
- The ``BYPRODUCTS`` option is ignored on non-Ninja generators
- except to mark byproducts ``GENERATED``.
-
``COMMAND``
Specify the command-line(s) to execute at build time.
If more than one ``COMMAND`` is specified they will be executed in order,
@@ -111,6 +108,9 @@ The options are:
an ``OUTPUT`` of another custom command in the same directory
(``CMakeLists.txt`` file) CMake automatically brings the other
custom command into the target in which this command is built.
+ A target-level dependency is added if any dependency is listed as
+ ``BYPRODUCTS`` of a target or any of its build events in the same
+ directory to ensure the byproducts will be available.
If ``DEPENDS`` is not specified the command will run whenever
the ``OUTPUT`` is missing; if the command does not actually
create the ``OUTPUT`` then the rule will always run.
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index 08b9516..e74960c 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -49,9 +49,6 @@ The options are:
order-only dependencies to ensure the byproducts will be
available before their dependents build.
- The ``BYPRODUCTS`` option is ignored on non-Ninja generators
- except to mark byproducts ``GENERATED``.
-
``COMMAND``
Specify the command-line(s) to execute at build time.
If more than one ``COMMAND`` is specified they will be executed in order,
@@ -86,6 +83,9 @@ The options are:
:command:`add_custom_command` command calls in the same directory
(``CMakeLists.txt`` file). They will be brought up to date when
the target is built.
+ A target-level dependency is added if any dependency is a byproduct
+ of a target or any of its build events in the same directory to ensure
+ the byproducts will be available before this target is built.
Use the :command:`add_dependencies` command to add dependencies
on other targets.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index fa04fbb..b019e0b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2599,7 +2599,7 @@ private:
SourceEntry* CurrentEntry;
std::queue<cmSourceFile*> SourceQueue;
std::set<cmSourceFile*> SourcesQueued;
- using NameMapType = std::map<std::string, cmSourceFile*>;
+ using NameMapType = std::map<std::string, cmSourcesWithOutput>;
NameMapType NameMap;
std::vector<std::string> NewSources;
@@ -2705,19 +2705,30 @@ void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
void cmTargetTraceDependencies::FollowName(std::string const& name)
{
- auto i = this->NameMap.find(name);
- if (i == this->NameMap.end()) {
+ // Use lower bound with key comparison to not repeat the search for the
+ // insert position if the name could not be found (which is the common case).
+ auto i = this->NameMap.lower_bound(name);
+ if (i == this->NameMap.end() || i->first != name) {
// Check if we know how to generate this file.
- cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name);
- NameMapType::value_type entry(name, sf);
- i = this->NameMap.insert(entry).first;
- }
- if (cmSourceFile* sf = i->second) {
- // Record the dependency we just followed.
- if (this->CurrentEntry) {
- this->CurrentEntry->Depends.push_back(sf);
+ cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+ i = this->NameMap.emplace_hint(i, name, sources);
+ }
+ if (cmTarget* t = i->second.Target) {
+ // The name is a byproduct of a utility target or a PRE_BUILD, PRE_LINK, or
+ // POST_BUILD command.
+ this->GeneratorTarget->Target->AddUtility(t->GetName());
+ }
+ if (cmSourceFile* sf = i->second.Source) {
+ // For now only follow the dependency if the source file is not a
+ // byproduct. Semantics of byproducts in a non-Ninja context will have to
+ // be defined first.
+ if (!i->second.SourceIsByproduct) {
+ // Record the dependency we just followed.
+ if (this->CurrentEntry) {
+ this->CurrentEntry->Depends.push_back(sf);
+ }
+ this->QueueSource(sf);
}
- this->QueueSource(sf);
}
}