aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2018-05-24 14:45:14 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2018-05-28 12:10:19 +0000
commit73f8478c9844aaf1282cc7461075f9c73230af2f (patch)
tree3b27e8b11893d0b52ff52b489a60e84da65b9941 /src/lib/corelib
parent57fd0ab336f0d88c007e4d7f5d09230d9a9e460b (diff)
Allow rules without output artifacts
It is occasionally useful to have a rule whose purpose lies solely in its "side effects", that is, it does not produce any actual files. This patch removes the necessity to declare a dummy artifact in that case. [ChangeLog] Added support for rules without output artifacts Change-Id: I38e76a5ddc78ffa768e8ae1f270ae2f7461c5ee7 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src/lib/corelib')
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.cpp37
-rw-r--r--src/lib/corelib/language/projectresolver.cpp13
2 files changed, 35 insertions, 15 deletions
diff --git a/src/lib/corelib/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp
index 22c89ea54..d04475abb 100644
--- a/src/lib/corelib/buildgraph/rulesapplicator.cpp
+++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp
@@ -65,6 +65,7 @@
#include <tools/qttools.h>
#include <tools/stringconstants.h>
+#include <QtCore/qcryptographichash.h>
#include <QtCore/qdir.h>
#include <QtScript/qscriptvalueiterator.h>
@@ -218,6 +219,10 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p
outputArtifacts.push_back(outputArtifact);
ruleArtifactArtifactMap.push_back({ ruleArtifact.get(), outputArtifact });
}
+ if (m_rule->artifacts.empty()) {
+ outputArtifacts.push_back(createOutputArtifactFromRuleArtifact(nullptr, inputArtifacts,
+ &outputFilePaths));
+ }
}
if (outputArtifacts.empty())
@@ -352,18 +357,34 @@ Artifact *RulesApplicator::createOutputArtifactFromRuleArtifact(
const RuleArtifactConstPtr &ruleArtifact, const ArtifactSet &inputArtifacts,
Set<QString> *outputFilePaths)
{
- QScriptValue scriptValue = engine()->evaluate(ruleArtifact->filePath,
- ruleArtifact->filePathLocation.filePath(),
- ruleArtifact->filePathLocation.line());
- if (Q_UNLIKELY(engine()->hasErrorOrException(scriptValue)))
- throw engine()->lastError(scriptValue, ruleArtifact->filePathLocation);
- QString outputPath = FileInfo::resolvePath(m_product->buildDirectory(), scriptValue.toString());
+ QString outputPath;
+ FileTags fileTags;
+ bool alwaysUpdated;
+ if (ruleArtifact) {
+ QScriptValue scriptValue = engine()->evaluate(ruleArtifact->filePath,
+ ruleArtifact->filePathLocation.filePath(),
+ ruleArtifact->filePathLocation.line());
+ if (Q_UNLIKELY(engine()->hasErrorOrException(scriptValue)))
+ throw engine()->lastError(scriptValue, ruleArtifact->filePathLocation);
+ outputPath = scriptValue.toString();
+ fileTags = ruleArtifact->fileTags;
+ alwaysUpdated = ruleArtifact->alwaysUpdated;
+ } else {
+ outputPath = QStringLiteral("__dummyoutput__");
+ QByteArray hashInput = m_rule->toString().toLatin1();
+ for (const Artifact * const input : inputArtifacts)
+ hashInput += input->filePath().toLatin1();
+ outputPath += QLatin1String(QCryptographicHash::hash(hashInput, QCryptographicHash::Sha1)
+ .toHex().left(16));
+ fileTags = m_rule->outputFileTags;
+ alwaysUpdated = false;
+ }
+ outputPath = FileInfo::resolvePath(m_product->buildDirectory(), outputPath);
if (Q_UNLIKELY(!outputFilePaths->insert(outputPath).second)) {
throw ErrorInfo(Tr::tr("Rule %1 already created '%2'.")
.arg(m_rule->toString(), outputPath));
}
- return createOutputArtifact(outputPath, ruleArtifact->fileTags, ruleArtifact->alwaysUpdated,
- inputArtifacts);
+ return createOutputArtifact(outputPath, fileTags, alwaysUpdated, inputArtifacts);
}
Artifact *RulesApplicator::createOutputArtifact(const QString &filePath, const FileTags &fileTags,
diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 5364184fc..b7535c2eb 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -1174,19 +1174,18 @@ void ProjectResolver::resolveRule(Item *item, ProjectContext *projectContext)
rule->prepareScript.initialize(scriptFunctionValue(item, StringConstants::prepareProperty()));
rule->outputArtifactsScript.initialize(scriptFunctionValue(
item, StringConstants::outputArtifactsProperty()));
+ rule->outputFileTags = m_evaluator->fileTagsValue(
+ item, StringConstants::outputFileTagsProperty());
if (rule->outputArtifactsScript.isValid()) {
if (hasArtifactChildren)
throw ErrorInfo(Tr::tr("The Rule.outputArtifacts script is not allowed in rules "
"that contain Artifact items."),
item->location());
- rule->outputFileTags = m_evaluator->fileTagsValue(
- item, StringConstants::outputFileTagsProperty());
- if (rule->outputFileTags.empty())
- throw ErrorInfo(Tr::tr("Rule.outputFileTags must be specified if "
- "Rule.outputArtifacts is specified."),
- item->location());
}
-
+ if (!hasArtifactChildren && rule->outputFileTags.empty()) {
+ throw ErrorInfo(Tr::tr("A rule needs to have Artifact items or a non-empty "
+ "outputFileTags property."), item->location());
+ }
rule->multiplex = m_evaluator->boolValue(item, StringConstants::multiplexProperty());
rule->alwaysRun = m_evaluator->boolValue(item, StringConstants::alwaysRunProperty());
rule->inputs = m_evaluator->fileTagsValue(item, StringConstants::inputsProperty());