From e769ba6127e46a51ea8448e184920ae81f6c4837 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 31 Jul 2014 16:01:30 +0200 Subject: do not call createOutputArtifacts for the same filePath more than once Task-number: QBS-645 Change-Id: Ia54f71ed7543617ba0b44f05e868a899a7c42e9b Reviewed-by: Christian Kandeler --- src/lib/corelib/buildgraph/rulesapplicator.cpp | 19 +++++++++++++++++-- src/lib/corelib/buildgraph/rulesapplicator.h | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/lib/corelib/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp index 40301f5ea..f269636c3 100644 --- a/src/lib/corelib/buildgraph/rulesapplicator.cpp +++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp @@ -172,9 +172,13 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p const ArtifactSet oldOutputs = collectOldOutputArtifacts(inputArtifacts); handleRemovedRuleOutputs(m_completeInputSet, oldOutputs - newOutputs, m_logger); } else { + QSet outputFilePaths; foreach (const RuleArtifactConstPtr &ruleArtifact, m_rule->artifacts) { Artifact * const outputArtifact - = createOutputArtifactFromRuleArtifact(ruleArtifact, inputArtifacts); + = createOutputArtifactFromRuleArtifact(ruleArtifact, inputArtifacts, + &outputFilePaths); + if (!outputArtifact) + continue; outputArtifacts << outputArtifact; ruleArtifactArtifactMap << qMakePair(ruleArtifact.data(), outputArtifact); } @@ -254,7 +258,8 @@ ArtifactSet RulesApplicator::collectOldOutputArtifacts(const ArtifactSet &inputA } Artifact *RulesApplicator::createOutputArtifactFromRuleArtifact( - const RuleArtifactConstPtr &ruleArtifact, const ArtifactSet &inputArtifacts) + const RuleArtifactConstPtr &ruleArtifact, const ArtifactSet &inputArtifacts, + QSet *outputFilePaths) { QScriptValue scriptValue = engine()->evaluate(ruleArtifact->filePath); if (Q_UNLIKELY(engine()->hasErrorOrException(scriptValue))) { @@ -262,6 +267,16 @@ Artifact *RulesApplicator::createOutputArtifactFromRuleArtifact( .arg(ruleArtifact->location.toString(), scriptValue.toString())); } QString outputPath = FileInfo::resolvePath(m_product->buildDirectory(), scriptValue.toString()); + if (outputFilePaths->contains(outputPath)) { + // The same output artifact was already created. Let the first one win. + // The GCC dynamicLibraryLinker linker rule relies on this for products that have no version + // set. + // ### This situation should result in an error in qbs 1.4! + if (m_logger.traceEnabled()) + m_logger.qbsTrace() << "[BG] WARNING: this rule has already created " << outputPath; + return 0; + } + outputFilePaths->insert(outputPath); return createOutputArtifact(outputPath, ruleArtifact->fileTags, ruleArtifact->alwaysUpdated, inputArtifacts); } diff --git a/src/lib/corelib/buildgraph/rulesapplicator.h b/src/lib/corelib/buildgraph/rulesapplicator.h index a43cac057..0a668f639 100644 --- a/src/lib/corelib/buildgraph/rulesapplicator.h +++ b/src/lib/corelib/buildgraph/rulesapplicator.h @@ -61,7 +61,7 @@ private: void doApply(const ArtifactSet &inputArtifacts, QScriptValue &prepareScriptContext); ArtifactSet collectOldOutputArtifacts(const ArtifactSet &inputArtifacts) const; Artifact *createOutputArtifactFromRuleArtifact(const RuleArtifactConstPtr &ruleArtifact, - const ArtifactSet &inputArtifacts); + const ArtifactSet &inputArtifacts, QSet *outputFilePaths); Artifact *createOutputArtifact(const QString &filePath, const FileTags &fileTags, bool alwaysUpdated, const ArtifactSet &inputArtifacts); QList runOutputArtifactsScript(const ArtifactSet &inputArtifacts, -- cgit v1.2.3