diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2017-09-01 12:47:02 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2017-09-01 11:43:56 +0000 |
commit | 9077f10d46909259effab143dc3d0e448e19ee8a (patch) | |
tree | 7930d413e9e066a65e0a7b28672e383f307c507d /src | |
parent | 0e2ae4b676e9a26ca42275088f55dc0917902bfb (diff) |
ModuleLoader: Fix adjustment for multiplexed dependenciesv1.9.0
We erroneously gave the responsible function only a local project view
instead of the global one, meaning dependencies could fail across
subprojects.
Change-Id: I18155df39cb981aed36e204ea2a85ed26a7eb6c7
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src')
-rwxr-xr-x | src/lib/corelib/language/moduleloader.cpp | 132 | ||||
-rw-r--r-- | src/lib/corelib/language/moduleloader.h | 4 |
2 files changed, 75 insertions, 61 deletions
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index e861f2dfd..232c91a2c 100755 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -523,6 +523,8 @@ void ModuleLoader::handleTopLevelProject(ModuleLoaderResult *loadResult, Item *p TopLevelProjectContext tlp; tlp.buildDirectory = buildDirectory; handleProject(loadResult, &tlp, projectItem, referencedFilePaths); + collectProductsByName(tlp); + adjustDependenciesForMultiplexing(tlp); for (ProjectContext * const projectContext : qAsConst(tlp.projects)) { m_reader->setExtraSearchPathsStack(projectContext->searchPathsStack); @@ -661,7 +663,6 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, break; } } - adjustDependenciesForMultiplexing(projectContext); m_reader->popExtraSearchPaths(); } @@ -858,76 +859,79 @@ QList<Item *> ModuleLoader::multiplexProductItem(ProductContext *dummyContext, I return additionalProductItems; } -void ModuleLoader::adjustDependenciesForMultiplexing(const ProjectContext &projectContext) +void ModuleLoader::adjustDependenciesForMultiplexing(const TopLevelProjectContext &tlp) { - for (const ProductContext &product : projectContext.products) - m_productsByName.insert({ product.name, &product }); + for (const ProjectContext * const project : tlp.projects) { + for (const ProductContext &product : project->products) + adjustDependenciesForMultiplexing(product); + } +} - const QString multiplexConfigurationIdKey = QStringLiteral("multiplexConfigurationId"); - for (const ProductContext &product : projectContext.products) { - std::vector<Item *> additionalDependsItems; - for (Item *dependsItem : product.item->children()) { - if (dependsItem->type() != ItemType::Depends) - continue; - const QString name = m_evaluator->stringValue(dependsItem, QStringLiteral("name")); - const bool productIsMultiplexed = !product.multiplexConfigurationId.isEmpty(); - if (name == product.name) { - QBS_CHECK(!productIsMultiplexed); // This product must be an aggregator. - continue; - } - const auto productRange = m_productsByName.equal_range(name); - std::vector<const ProductContext *> dependencies; - bool hasNonMultiplexedDependency = false; - for (auto it = productRange.first; it != productRange.second; ++it) { - if (!it->second->multiplexConfigurationId.isEmpty()) { - dependencies.push_back(it->second); - if (productIsMultiplexed) - break; - } else { - hasNonMultiplexedDependency = true; +void ModuleLoader::adjustDependenciesForMultiplexing(const ModuleLoader::ProductContext &product) +{ + static const QString multiplexConfigurationIdKey = QStringLiteral("multiplexConfigurationId"); + std::vector<Item *> additionalDependsItems; + for (Item *dependsItem : product.item->children()) { + if (dependsItem->type() != ItemType::Depends) + continue; + const QString name = m_evaluator->stringValue(dependsItem, QStringLiteral("name")); + const bool productIsMultiplexed = !product.multiplexConfigurationId.isEmpty(); + if (name == product.name) { + QBS_CHECK(!productIsMultiplexed); // This product must be an aggregator. + continue; + } + const auto productRange = m_productsByName.equal_range(name); + std::vector<const ProductContext *> dependencies; + bool hasNonMultiplexedDependency = false; + for (auto it = productRange.first; it != productRange.second; ++it) { + if (!it->second->multiplexConfigurationId.isEmpty()) { + dependencies.push_back(it->second); + if (productIsMultiplexed) break; - } + } else { + hasNonMultiplexedDependency = true; + break; } + } - // These are the allowed cases: - // (1) Normal dependency with no multiplexing whatsoever. - // (2) Both product and dependency are multiplexed. - // (3) The product is not multiplexed, but the dependency is. - // (3a) The dependency has an aggregator. We want to depend on the aggregator. - // (3b) The dependency does not have an aggregator. We want to depend on all the - // multiplexed variants. - // (4) The product is multiplexed, but the dependency is not. This case is implicitly - // handled, because we don't have to adapt any Depends items. - - // (1) and (3a) - if (!productIsMultiplexed && hasNonMultiplexedDependency) - continue; + // These are the allowed cases: + // (1) Normal dependency with no multiplexing whatsoever. + // (2) Both product and dependency are multiplexed. + // (3) The product is not multiplexed, but the dependency is. + // (3a) The dependency has an aggregator. We want to depend on the aggregator. + // (3b) The dependency does not have an aggregator. We want to depend on all the + // multiplexed variants. + // (4) The product is multiplexed, but the dependency is not. This case is implicitly + // handled, because we don't have to adapt any Depends items. - for (std::size_t i = 0; i < dependencies.size(); ++i) { - const QString depMultiplexId = dependencies.at(i)->multiplexConfigurationId; - if (i == 0) { - if (productIsMultiplexed) { // (2) - dependsItem->setProperty(multiplexConfigurationIdKey, - product.item->property(multiplexConfigurationIdKey)); - break; - } - // (3b) + // (1) and (3a) + if (!productIsMultiplexed && hasNonMultiplexedDependency) + continue; + + for (std::size_t i = 0; i < dependencies.size(); ++i) { + const QString depMultiplexId = dependencies.at(i)->multiplexConfigurationId; + if (i == 0) { + if (productIsMultiplexed) { // (2) dependsItem->setProperty(multiplexConfigurationIdKey, - VariantValue::create(depMultiplexId)); - } else { - // (3b) - Item * const newDependsItem = dependsItem->clone(); - newDependsItem->setProperty(multiplexConfigurationIdKey, - VariantValue::create(depMultiplexId)); - dependsItem->setProperty(QStringLiteral("profiles"), - VariantValue::create(QStringLiteral("*"))); - additionalDependsItems.push_back(newDependsItem); + product.item->property(multiplexConfigurationIdKey)); + break; } + // (3b) + dependsItem->setProperty(multiplexConfigurationIdKey, + VariantValue::create(depMultiplexId)); + } else { + // (3b) + Item * const newDependsItem = dependsItem->clone(); + newDependsItem->setProperty(multiplexConfigurationIdKey, + VariantValue::create(depMultiplexId)); + dependsItem->setProperty(QStringLiteral("profiles"), + VariantValue::create(QStringLiteral("*"))); + additionalDependsItems.push_back(newDependsItem); } } - for (Item * const newDependsItem : additionalDependsItems) - Item::addChild(product.item, newDependsItem); } + for (Item * const newDependsItem : additionalDependsItems) + Item::addChild(product.item, newDependsItem); } void ModuleLoader::prepareProduct(ProjectContext *projectContext, Item *productItem) @@ -1611,6 +1615,14 @@ Item *ModuleLoader::loadItemFromFile(const QString &filePath) return item; } +void ModuleLoader::collectProductsByName(const TopLevelProjectContext &topLevelProject) +{ + for (ProjectContext * const project : topLevelProject.projects) { + for (ProductContext &product : project->products) + m_productsByName.insert({ product.name, &product }); + } +} + void ModuleLoader::propagateModulesFromParent(ProductContext *productContext, Item *groupItem, const ModuleDependencies &reverseDepencencies) { diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h index 0e9445f1c..aeea34ad0 100644 --- a/src/lib/corelib/language/moduleloader.h +++ b/src/lib/corelib/language/moduleloader.h @@ -230,7 +230,8 @@ private: static MultiplexTable combine(const MultiplexTable &table, const MultiplexRow &values); MultiplexInfo extractMultiplexInfo(Item *productItem, Item *qbsModuleItem); QList<Item *> multiplexProductItem(ProductContext *dummyContext, Item *productItem); - void adjustDependenciesForMultiplexing(const ProjectContext &projectContext); + void adjustDependenciesForMultiplexing(const TopLevelProjectContext &tlp); + void adjustDependenciesForMultiplexing(const ProductContext &product); void prepareProduct(ProjectContext *projectContext, Item *productItem); void setupProductDependencies(ProductContext *productContext); @@ -320,6 +321,7 @@ private: void handleProductError(const ErrorInfo &error, ProductContext *productContext); QualifiedIdSet gatherModulePropertiesSetInGroup(const Item *group); Item *loadItemFromFile(const QString &filePath); + void collectProductsByName(const TopLevelProjectContext &topLevelProject); ItemPool *m_pool; Logger &m_logger; |