aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.cpp37
-rw-r--r--src/lib/corelib/language/artifactproperties.cpp4
-rw-r--r--src/lib/corelib/language/artifactproperties.h2
-rw-r--r--src/lib/corelib/language/projectresolver.cpp82
4 files changed, 79 insertions, 46 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/artifactproperties.cpp b/src/lib/corelib/language/artifactproperties.cpp
index 4897c6cff..dd61bf1a2 100644
--- a/src/lib/corelib/language/artifactproperties.cpp
+++ b/src/lib/corelib/language/artifactproperties.cpp
@@ -57,9 +57,9 @@ FileTags ArtifactProperties::extraFileTags() const
return m_extraFileTags;
}
-void ArtifactProperties::setExtraFileTags(const FileTags &extraFileTags)
+void ArtifactProperties::addExtraFileTags(const FileTags &extraFileTags)
{
- m_extraFileTags = extraFileTags;
+ m_extraFileTags.unite(extraFileTags);
}
bool operator==(const ArtifactProperties &ap1, const ArtifactProperties &ap2)
diff --git a/src/lib/corelib/language/artifactproperties.h b/src/lib/corelib/language/artifactproperties.h
index a255950d0..856aa80c7 100644
--- a/src/lib/corelib/language/artifactproperties.h
+++ b/src/lib/corelib/language/artifactproperties.h
@@ -59,7 +59,7 @@ public:
void setPropertyMapInternal(const PropertyMapPtr &pmap) { m_propertyMap = pmap; }
FileTags extraFileTags() const;
- void setExtraFileTags(const FileTags &extraFileTags);
+ void addExtraFileTags(const FileTags &extraFileTags);
template<PersistentPool::OpType opType> void completeSerializationOp(PersistentPool &pool)
{
diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 4af79a5ce..ff74f845a 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -97,7 +97,7 @@ struct ProjectResolver::ProductContext
ResolvedProductPtr product;
QString buildDirectory;
Item *item;
- typedef std::pair<ArtifactPropertiesPtr, CodeLocation> ArtifactPropertiesInfo;
+ typedef std::pair<ArtifactPropertiesPtr, std::vector<CodeLocation>> ArtifactPropertiesInfo;
QHash<QStringList, ArtifactPropertiesInfo> artifactPropertiesPerFilter;
QHash<QString, CodeLocation> sourceArtifactLocations;
GroupConstPtr currentGroup;
@@ -692,19 +692,30 @@ void ProjectResolver::resolveGroup(Item *item, ProjectContext *projectContext)
void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectContext *projectContext,
bool isEnabled)
{
- PropertyMapPtr moduleProperties = m_productContext->currentGroup
- ? m_productContext->currentGroup->properties
- : m_productContext->product->moduleProperties;
- const QVariantMap newModuleProperties
- = resolveAdditionalModuleProperties(item, moduleProperties->value());
- if (!newModuleProperties.empty()) {
- moduleProperties = PropertyMapInternal::create();
- moduleProperties->setValue(newModuleProperties);
- }
-
AccumulatingTimer groupTimer(m_setupParams.logElapsedTime()
? &m_elapsedTimeGroups : nullptr);
+ const auto getGroupPropertyMap = [this, item](const ArtifactProperties *existingProps) {
+ PropertyMapPtr moduleProperties;
+ bool newPropertyMapRequired = false;
+ if (existingProps)
+ moduleProperties = existingProps->propertyMap();
+ if (!moduleProperties) {
+ newPropertyMapRequired = true;
+ moduleProperties = m_productContext->currentGroup
+ ? m_productContext->currentGroup->properties
+ : m_productContext->product->moduleProperties;
+ }
+ const QVariantMap newModuleProperties
+ = resolveAdditionalModuleProperties(item, moduleProperties->value());
+ if (!newModuleProperties.empty()) {
+ if (newPropertyMapRequired)
+ moduleProperties = PropertyMapInternal::create();
+ moduleProperties->setValue(newModuleProperties);
+ }
+ return moduleProperties;
+ };
+
QStringList files = m_evaluator->stringListValue(item, StringConstants::filesProperty());
bool fileTagsSet;
const FileTags fileTags = m_evaluator->fileTagsValue(item, StringConstants::fileTagsProperty(),
@@ -716,28 +727,30 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont
throw ErrorInfo(Tr::tr("Group.files and Group.fileTagsFilters are exclusive."),
item->location());
- ProductContext::ArtifactPropertiesInfo apinfo
- = m_productContext->artifactPropertiesPerFilter.value(fileTagsFilter);
+ if (!isEnabled)
+ return;
+
+ ProductContext::ArtifactPropertiesInfo &apinfo
+ = m_productContext->artifactPropertiesPerFilter[fileTagsFilter];
if (apinfo.first) {
- if (apinfo.second.filePath() == item->location().filePath()) {
+ const auto it = std::find_if(apinfo.second.cbegin(), apinfo.second.cend(),
+ [item](const CodeLocation &loc) {
+ return item->location().filePath() == loc.filePath();
+ });
+ if (it != apinfo.second.cend()) {
ErrorInfo error(Tr::tr("Conflicting fileTagsFilter in Group items."));
- error.append(Tr::tr("First item"), apinfo.second);
+ error.append(Tr::tr("First item"), *it);
error.append(Tr::tr("Second item"), item->location());
throw error;
}
-
- // Discard any Group with the same fileTagsFilter that was defined in a base file.
- removeAll(m_productContext->product->artifactProperties, apinfo.first);
+ } else {
+ apinfo.first = ArtifactProperties::create();
+ apinfo.first->setFileTagsFilter(FileTags::fromStringList(fileTagsFilter));
+ m_productContext->product->artifactProperties.push_back(apinfo.first);
}
- if (!isEnabled)
- return;
- ArtifactPropertiesPtr aprops = ArtifactProperties::create();
- aprops->setFileTagsFilter(FileTags::fromStringList(fileTagsFilter));
- aprops->setExtraFileTags(fileTags);
- aprops->setPropertyMapInternal(moduleProperties);
- m_productContext->product->artifactProperties.push_back(aprops);
- m_productContext->artifactPropertiesPerFilter.insert(fileTagsFilter,
- ProductContext::ArtifactPropertiesInfo(aprops, item->location()));
+ apinfo.second.push_back(item->location());
+ apinfo.first->setPropertyMapInternal(getGroupPropertyMap(apinfo.first.get()));
+ apinfo.first->addExtraFileTags(fileTags);
return;
}
QStringList patterns;
@@ -757,7 +770,7 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont
}
group->location = item->location();
group->enabled = isEnabled;
- group->properties = moduleProperties;
+ group->properties = getGroupPropertyMap(nullptr);
group->fileTags = fileTags;
group->overrideTags = m_evaluator->boolValue(item, StringConstants::overrideTagsProperty());
if (group->overrideTags && fileTagsSet) {
@@ -1161,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());