diff options
author | Joerg Bornemann <joerg.bornemann@digia.com> | 2014-07-24 19:12:16 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2014-07-30 14:00:57 +0200 |
commit | fd49db9b33c0f54255d92c0d882a4f18c20a5ef3 (patch) | |
tree | f01a43527e41bfced20f0fc77e2fe1ed3ee73d91 /src/lib/corelib/buildgraph | |
parent | 472a0e505a78fddf5d7ce02b2c6ef8f859926b3e (diff) |
fix calculation of old inputs for dynamic rules
Instead of deducing the old inputs of a rule from the inputs of its
created transformers, we hold a dedicated list of old inputs, because
the former approach doesn't work for dynamic rules.
This fixes a speed regression introduced in 32c4d3d7.
The outputArtifacts script of dynamic rules was always run on
compatible inputs that were not input of transformers, e.g.
C++ sources that don't have a Q_OBJECT macro.
Change-Id: I2d43fa7c91ed9084bd27dc9b948c06152bfce726
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Diffstat (limited to 'src/lib/corelib/buildgraph')
-rw-r--r-- | src/lib/corelib/buildgraph/artifactset.cpp | 6 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/artifactset.h | 3 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/projectbuilddata.cpp | 45 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/rulenode.cpp | 30 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/rulenode.h | 4 |
5 files changed, 61 insertions, 27 deletions
diff --git a/src/lib/corelib/buildgraph/artifactset.cpp b/src/lib/corelib/buildgraph/artifactset.cpp index c44f5e4b9..0010e81fe 100644 --- a/src/lib/corelib/buildgraph/artifactset.cpp +++ b/src/lib/corelib/buildgraph/artifactset.cpp @@ -47,6 +47,12 @@ ArtifactSet::ArtifactSet(const QSet<Artifact *> &other) { } +ArtifactSet &ArtifactSet::unite(const ArtifactSet &other) +{ + QSet::unite(other); + return *this; +} + ArtifactSet ArtifactSet::fromNodeSet(const NodeSet &nodes) { ArtifactSet result; diff --git a/src/lib/corelib/buildgraph/artifactset.h b/src/lib/corelib/buildgraph/artifactset.h index 092e9e8a2..696859649 100644 --- a/src/lib/corelib/buildgraph/artifactset.h +++ b/src/lib/corelib/buildgraph/artifactset.h @@ -44,6 +44,9 @@ public: ArtifactSet(); ArtifactSet(const ArtifactSet &other); ArtifactSet(const QSet<Artifact *> &other); + + ArtifactSet &unite(const ArtifactSet &other); + static ArtifactSet fromNodeSet(const NodeSet &nodes); static ArtifactSet fromNodeList(const QList<Artifact *> &lst); }; diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp index 2a4fc812f..6af68caa3 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.cpp +++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp @@ -261,6 +261,49 @@ void ProjectBuildData::removeArtifactAndExclusiveDependents(Artifact *artifact, removeArtifact(artifact, logger, removeFromDisk, removeFromProduct); } +template <class Func> +void forEachRuleNode(BuildGraphNode *n, const Func &f) +{ + if (n->type() != BuildGraphNode::RuleNodeType) + return; + f(static_cast<RuleNode *>(n)); + foreach (BuildGraphNode *c, n->children) + forEachRuleNode(c, f); +} + +template <class Func> +void forEachRuleNode(const TopLevelProject *project, const Func &f) +{ + foreach (const ResolvedProductPtr &product, project->allProducts()) { + if (!product->buildData) + continue; + foreach (BuildGraphNode *n, product->buildData->roots) + forEachRuleNode(n, f); + } +} + +class RemoveOldInputArtifactFromRuleNode +{ +public: + RemoveOldInputArtifactFromRuleNode(Artifact *artifact, const Logger &logger) + : m_artifact(artifact), m_logger(logger) + { + } + + void operator()(RuleNode *ruleNode) const + { + if (m_logger.traceEnabled()) { + m_logger.qbsTrace() << "[BG] remove old input " << m_artifact->filePath() + << " from rule " << ruleNode->rule()->toString(); + } + ruleNode->removeOldInputArtifact(m_artifact); + } + +private: + Artifact * const m_artifact; + const Logger &m_logger; +}; + void ProjectBuildData::removeArtifact(Artifact *artifact, const Logger &logger, bool removeFromDisk, bool removeFromProduct) { @@ -275,6 +318,8 @@ void ProjectBuildData::removeArtifact(Artifact *artifact, artifact->product->buildData->roots.remove(artifact); removeArtifactFromSet(artifact, artifact->product->buildData->artifactsByFileTag); } + forEachRuleNode(artifact->product->topLevelProject(), + RemoveOldInputArtifactFromRuleNode(artifact, logger)); disconnectArtifact(artifact, logger); if (artifact->transformer) { diff --git a/src/lib/corelib/buildgraph/rulenode.cpp b/src/lib/corelib/buildgraph/rulenode.cpp index 00454d080..3ea324238 100644 --- a/src/lib/corelib/buildgraph/rulenode.cpp +++ b/src/lib/corelib/buildgraph/rulenode.cpp @@ -65,10 +65,9 @@ QString RuleNode::toString() const void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, ApplicationResult *result) { - const ArtifactSet oldInputs = oldInputArtifacts(); ArtifactSet allCompatibleInputs = currentInputArtifacts(); - const ArtifactSet addedInputs = allCompatibleInputs - oldInputs; - const ArtifactSet removedInputs = oldInputs - allCompatibleInputs; + const ArtifactSet addedInputs = allCompatibleInputs - m_oldInputArtifacts; + const ArtifactSet removedInputs = m_oldInputArtifacts - allCompatibleInputs; result->upToDate = changedInputs.isEmpty() && addedInputs.isEmpty() && removedInputs.isEmpty(); ArtifactSet inputs = changedInputs; @@ -108,6 +107,7 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, if (!inputs.isEmpty()) { RulesApplicator applicator(product, logger); result->createdNodes = applicator.applyRuleInEvaluationContext(m_rule, inputs); + m_oldInputArtifacts.unite(inputs); } } @@ -115,34 +115,14 @@ void RuleNode::load(PersistentPool &pool) { BuildGraphNode::load(pool); m_rule = pool.idLoadS<Rule>(); + pool.loadContainer(m_oldInputArtifacts); } void RuleNode::store(PersistentPool &pool) const { BuildGraphNode::store(pool); pool.store(m_rule); -} - -QList<TransformerPtr> RuleNode::createdTransformers() const -{ - QList<TransformerPtr> lst; - foreach (BuildGraphNode *parent, parents) { - if (parent->type() != ArtifactNodeType) - continue; - Artifact *artifact = static_cast<Artifact *>(parent); - if (!artifact->transformer || artifact->transformer->rule != m_rule) - continue; - lst.append(artifact->transformer); - } - return lst; -} - -ArtifactSet RuleNode::oldInputArtifacts() const -{ - ArtifactSet s; - foreach (const TransformerPtr &t, createdTransformers()) - s += t->inputs; - return s; + pool.storeContainer(m_oldInputArtifacts); } ArtifactSet RuleNode::currentInputArtifacts() const diff --git a/src/lib/corelib/buildgraph/rulenode.h b/src/lib/corelib/buildgraph/rulenode.h index 027094211..fcc0076c6 100644 --- a/src/lib/corelib/buildgraph/rulenode.h +++ b/src/lib/corelib/buildgraph/rulenode.h @@ -60,17 +60,17 @@ public: }; void apply(const Logger &logger, const ArtifactSet &changedInputs, ApplicationResult *result); + void removeOldInputArtifact(Artifact *artifact) { m_oldInputArtifacts.remove(artifact); } protected: void load(PersistentPool &pool); void store(PersistentPool &pool) const; private: - QList<TransformerPtr> createdTransformers() const; - ArtifactSet oldInputArtifacts() const; ArtifactSet currentInputArtifacts() const; RuleConstPtr m_rule; + ArtifactSet m_oldInputArtifacts; }; } // namespace Internal |