diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/corelib/buildgraph/rulesapplicator.cpp | 37 | ||||
-rw-r--r-- | src/lib/corelib/language/artifactproperties.cpp | 4 | ||||
-rw-r--r-- | src/lib/corelib/language/artifactproperties.h | 2 | ||||
-rw-r--r-- | src/lib/corelib/language/projectresolver.cpp | 82 |
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()); |