aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2018-03-06 18:17:04 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2018-03-09 08:54:18 +0000
commitabfc4c1b37d18515c8da0678a665886d7cb69af5 (patch)
treeb171d79fbd3980010683778761ab60ddf3ac881a /src
parent4bbcab71534cedb0076d5a1b5899ee8530a01f81 (diff)
Fix exports from multiplexed products
While we did set up the dependencies between multiplexed products correctly, the *module* (i.e. Export item) that we pulled in was always the same one and corresponded to the wrong product variant in most cases. Change-Id: If42cf7e946689259c7433d81fd35d8798919eb15 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/lib/corelib/language/moduleloader.cpp79
-rw-r--r--src/lib/corelib/language/moduleloader.h10
2 files changed, 58 insertions, 31 deletions
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp
index f81e8d44f..1726bd902 100644
--- a/src/lib/corelib/language/moduleloader.cpp
+++ b/src/lib/corelib/language/moduleloader.cpp
@@ -1148,10 +1148,15 @@ void ModuleLoader::handleProduct(ModuleLoader::ProductContext *productContext)
}
if (!checkItemCondition(item)) {
- Item * const productModule = productContext->project->topLevelProject
- ->productModules.value(productContext->name).exportItem;
- if (productModule && productModule->isPresentModule())
- createNonPresentModule(productContext->name, QLatin1String("disabled"), productModule);
+ const auto &exportsData = productContext->project->topLevelProject->productModules;
+ for (auto it = exportsData.find(productContext->name);
+ it != exportsData.end() && it.key() == productContext->name; ++it) {
+ if (it.value().multiplexId == productContext->multiplexConfigurationId) {
+ createNonPresentModule(productContext->name, QLatin1String("disabled"),
+ it.value().exportItem);
+ break;
+ }
+ }
}
checkDependencyParameterDeclarations(productContext);
@@ -1618,8 +1623,7 @@ void ModuleLoader::mergeExportItems(const ProductContext &productContext)
const ValuePtr nameValue = VariantValue::create(productContext.name);
merged->setProperty(nameKey, nameValue);
Set<FileContextConstPtr> filesWithExportItem;
- ProductModuleInfo &pmi
- = productContext.project->topLevelProject->productModules[productContext.name];
+ ProductModuleInfo pmi;
for (Item * const exportItem : qAsConst(exportItems)) {
checkCancelation();
if (Q_UNLIKELY(filesWithExportItem.contains(exportItem->file())))
@@ -1661,6 +1665,8 @@ void ModuleLoader::mergeExportItems(const ProductContext &productContext)
Item::addChild(productContext.item, merged);
merged->setupForBuiltinType(m_logger);
pmi.exportItem = merged;
+ pmi.multiplexId = productContext.multiplexConfigurationId;
+ productContext.project->topLevelProject->productModules.insert(productContext.name, pmi);
}
Item *ModuleLoader::loadItemFromFile(const QString &filePath)
@@ -2224,14 +2230,27 @@ void ModuleLoader::resolveDependsItem(DependsContext *dependsContext, Item *pare
}
QVariantMap defaultParameters;
+ QStringList multiplexConfigurationIds = m_evaluator->stringListValue(
+ dependsItem,
+ StringConstants::multiplexConfigurationIdsProperty());
+ if (multiplexConfigurationIds.empty())
+ multiplexConfigurationIds << QString();
Item *moduleItem = loadModule(dependsContext->product, dependsContext->exportingProductItem,
parentItem, dependsItem->location(), dependsItem->id(),
- moduleName, isRequired, &result.isProduct,
- &defaultParameters);
+ moduleName, multiplexConfigurationIds.first(), isRequired,
+ &result.isProduct, &defaultParameters);
if (!moduleItem) {
+ const QString productName = ResolvedProduct::fullDisplayName(
+ dependsContext->product->name,
+ dependsContext->product->multiplexConfigurationId);
+ if (!multiplexConfigurationIds.first().isEmpty()) {
+ const QString depName = ResolvedProduct::fullDisplayName(
+ moduleName.toString(), multiplexConfigurationIds.first());
+ throw ErrorInfo(Tr::tr("Dependency from product '%1' to product '%2' not "
+ "fulfilled.").arg(productName, depName));
+ }
ErrorInfo e(Tr::tr("Dependency '%1' not found for product '%2'.")
- .arg(moduleName.toString(), dependsContext->product->name),
- dependsItem->location());
+ .arg(moduleName.toString(), productName), dependsItem->location());
if (moduleName.size() == 2 && moduleName.front() == QStringLiteral("Qt")) {
e.append(Tr::tr("Please create a Qt profile using the qbs-setup-qt tool "
"if you haven't already done so."));
@@ -2263,11 +2282,6 @@ void ModuleLoader::resolveDependsItem(DependsContext *dependsContext, Item *pare
else
profiles.push_back(QString());
}
- QStringList multiplexConfigurationIds = m_evaluator->stringListValue(
- dependsItem,
- StringConstants::multiplexConfigurationIdsProperty());
- if (multiplexConfigurationIds.empty())
- multiplexConfigurationIds << QString();
for (const QString &profile : qAsConst(profiles)) {
for (const QString &multiplexId : multiplexConfigurationIds) {
ModuleLoaderResult::ProductInfo::Dependency dependency;
@@ -2415,10 +2429,18 @@ Item *ModuleLoader::moduleInstanceItem(Item *containerItem, const QualifiedId &m
return instance;
}
-ModuleLoader::ProductModuleInfo *ModuleLoader::productModule(ProductContext *productContext,
- const QString &name)
+ModuleLoader::ProductModuleInfo *ModuleLoader::productModule(
+ ProductContext *productContext, const QString &name, const QString &multiplexId)
{
- return &productContext->project->topLevelProject->productModules[name];
+ auto &exportsData = productContext->project->topLevelProject->productModules;
+ const auto firstIt = exportsData.find(name);
+ for (auto it = firstIt; it != exportsData.end() && it.key() == name; ++it) {
+ if (it.value().multiplexId == multiplexId)
+ return &it.value();
+ }
+ if (multiplexId.isEmpty() && firstIt != exportsData.end())
+ return &firstIt.value();
+ return nullptr;
}
ModuleLoader::ProductContext *ModuleLoader::product(ProjectContext *projectContext,
@@ -2522,8 +2544,8 @@ private:
Item *ModuleLoader::loadModule(ProductContext *productContext, Item *exportingProductItem,
Item *item, const CodeLocation &dependsItemLocation,
const QString &moduleId, const QualifiedId &moduleName,
- bool isRequired, bool *isProductDependency,
- QVariantMap *defaultParameters)
+ const QString &multiplexId, bool isRequired,
+ bool *isProductDependency, QVariantMap *defaultParameters)
{
qCDebug(lcModuleLoader) << "loadModule name:" << moduleName.toString() << "id:" << moduleId;
@@ -2559,15 +2581,16 @@ Item *ModuleLoader::loadModule(ProductContext *productContext, Item *exportingPr
}
}
- *isProductDependency = true;
- ProductModuleInfo *pmi = productModule(productContext, moduleName.toString());
- Item *modulePrototype = pmi->exportItem;
- if (modulePrototype) {
+ Item *modulePrototype = nullptr;
+ ProductModuleInfo * const pmi = productModule(productContext, moduleName.toString(),
+ multiplexId);
+ if (pmi) {
+ *isProductDependency = true;
m_dependsChain.back().isProduct = true;
+ modulePrototype = pmi->exportItem;
if (defaultParameters)
*defaultParameters = pmi->defaultParameters;
} else {
- pmi = nullptr;
*isProductDependency = false;
modulePrototype = searchAndLoadModuleFile(productContext, dependsItemLocation,
moduleName, isRequired, moduleInstance);
@@ -2820,7 +2843,8 @@ Item::Module ModuleLoader::loadBaseModule(ProductContext *productContext, Item *
Item::Module baseModuleDesc;
baseModuleDesc.name = baseModuleName;
baseModuleDesc.item = loadModule(productContext, nullptr, item, CodeLocation(), QString(),
- baseModuleName, true, &baseModuleDesc.isProduct, nullptr);
+ baseModuleName, QString(), true, &baseModuleDesc.isProduct,
+ nullptr);
if (productContext->item) {
const Item * const qbsInstanceItem
= moduleInstanceItem(productContext->item, baseModuleName);
@@ -3350,7 +3374,8 @@ void ModuleLoader::addTransitiveDependencies(ProductContext *ctx)
} else {
Item::Module dep;
dep.item = loadModule(ctx, nullptr, ctx->item, ctx->item->location(), QString(),
- module.name, module.required, &dep.isProduct, &dep.parameters);
+ module.name, QString(), module.required, &dep.isProduct,
+ &dep.parameters);
if (!dep.item) {
throw ErrorInfo(Tr::tr("Module '%1' not found when setting up transitive "
"dependencies for product '%2'.").arg(module.name.toString(),
diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h
index 8eafb54da..7573acb3e 100644
--- a/src/lib/corelib/language/moduleloader.h
+++ b/src/lib/corelib/language/moduleloader.h
@@ -188,6 +188,7 @@ private:
struct ProductModuleInfo
{
Item *exportItem = nullptr;
+ QString multiplexId;
QVariantMap defaultParameters;
};
@@ -199,7 +200,7 @@ private:
~TopLevelProjectContext() { qDeleteAll(projects); }
std::vector<ProjectContext *> projects;
- QHash<QString, ProductModuleInfo> productModules;
+ QMultiHash<QString, ProductModuleInfo> productModules;
QList<ProbeConstPtr> probes;
QString buildDirectory;
};
@@ -276,13 +277,14 @@ private:
void resolveParameterDeclarations(const Item *module);
QVariantMap extractParameters(Item *dependsItem) const;
Item *moduleInstanceItem(Item *containerItem, const QualifiedId &moduleName);
- static ProductModuleInfo *productModule(ProductContext *productContext, const QString &name);
+ static ProductModuleInfo *productModule(ProductContext *productContext, const QString &name,
+ const QString &multiplexId);
static ProductContext *product(ProjectContext *projectContext, const QString &name);
static ProductContext *product(TopLevelProjectContext *tlpContext, const QString &name);
Item *loadModule(ProductContext *productContext, Item *exportingProductItem, Item *item,
const CodeLocation &dependsItemLocation, const QString &moduleId,
- const QualifiedId &moduleName, bool isRequired, bool *isProductDependency,
- QVariantMap *defaultParameters);
+ const QualifiedId &moduleName, const QString &multiplexId, bool isRequired,
+ bool *isProductDependency, QVariantMap *defaultParameters);
Item *searchAndLoadModuleFile(ProductContext *productContext,
const CodeLocation &dependsItemLocation, const QualifiedId &moduleName,
bool isRequired, Item *moduleInstance);