aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@theqtcompany.com>2016-05-19 13:32:44 +0200
committerChristian Kandeler <christian.kandeler@theqtcompany.com>2016-05-20 12:44:12 +0000
commit3872137a82d7abe17e9ebc9af4298c324f9a1003 (patch)
treeac5c66f9dedb1ed51619c953c5edcf0148aed38d
parentfbf6502160988e0376c26d83732329b226465f27 (diff)
Respect the conditions of Export items.
This did not happen before, because module conditions are only evaluated when loading the module file, of which there is none in the case of Export items. Note: The implementation assumes that the condition of an Export item has the semantics "use or ignore this Export item". The other possible meaning would be to use the condition as the condition of the resulting module instance, but that immediately leads to weirdness: What does it mean for the dependency to a product if said product is enabled, but its Export item is not? What about conflicting conditions in the Export items of an inheritance chain -- do they get logically "and"ed? And so on. Change-Id: I08d7d93d30b8a53b42a317cb3391924e4666d169 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r--src/lib/corelib/language/moduleloader.cpp28
-rw-r--r--src/lib/corelib/language/moduleloader.h2
-rw-r--r--tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs18
-rw-r--r--tests/auto/blackbox/testdata/conditional-export/main.cpp5
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp13
-rw-r--r--tests/auto/blackbox/tst_blackbox.h1
6 files changed, 67 insertions, 0 deletions
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp
index 72ac707e6..3d391fd0d 100644
--- a/src/lib/corelib/language/moduleloader.cpp
+++ b/src/lib/corelib/language/moduleloader.cpp
@@ -759,6 +759,32 @@ static void mergeProperty(Item *dst, const QString &name, const ValuePtr &value)
}
}
+bool ModuleLoader::checkExportItemCondition(Item *exportItem, const ProductContext &productContext)
+{
+ class ScopeHandler {
+ public:
+ ScopeHandler(Item *exportItem, const ProductContext &productContext, Item **cachedScopeItem)
+ : m_exportItem(exportItem)
+ {
+ if (!*cachedScopeItem)
+ *cachedScopeItem = Item::create(exportItem->pool());
+ Item * const scope = *cachedScopeItem;
+ QBS_CHECK(productContext.item->file());
+ scope->setFile(productContext.item->file());
+ scope->setScope(productContext.item);
+ productContext.project->scope->copyProperty(QLatin1String("project"), scope);
+ productContext.scope->copyProperty(QLatin1String("product"), scope);
+ QBS_CHECK(!exportItem->scope());
+ exportItem->setScope(scope);
+ }
+ ~ScopeHandler() { m_exportItem->setScope(nullptr); }
+
+ private:
+ Item * const m_exportItem;
+ } scopeHandler(exportItem, productContext, &m_tempScopeItem);
+ return checkItemCondition(exportItem);
+}
+
void ModuleLoader::mergeExportItems(const ProductContext &productContext)
{
QVector<Item *> exportItems;
@@ -786,6 +812,8 @@ void ModuleLoader::mergeExportItems(const ProductContext &productContext)
if (Q_UNLIKELY(filesWithExportItem.contains(exportItem->file())))
throw ErrorInfo(Tr::tr("Multiple Export items in one product are prohibited."),
exportItem->location());
+ if (!checkExportItemCondition(exportItem, productContext))
+ continue;
filesWithExportItem += exportItem->file();
foreach (Item *child, exportItem->children())
Item::addChild(merged, child);
diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h
index 061fd4877..c5526e00f 100644
--- a/src/lib/corelib/language/moduleloader.h
+++ b/src/lib/corelib/language/moduleloader.h
@@ -238,6 +238,7 @@ private:
void copyGroupsFromModuleToProduct(const ProductContext &productContext,
const Item *modulePrototype);
void copyGroupsFromModulesToProduct(const ProductContext &productContext);
+ bool checkExportItemCondition(Item *exportItem, const ProductContext &productContext);
ScriptEngine *m_engine;
ItemPool *m_pool;
@@ -254,6 +255,7 @@ private:
QStack<bool> m_requiredChain;
SetupProjectParameters m_parameters;
Version m_qbsVersion;
+ Item *m_tempScopeItem = nullptr;
};
} // namespace Internal
diff --git a/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs b/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs
new file mode 100644
index 000000000..c7b6ae09d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs
@@ -0,0 +1,18 @@
+import qbs
+
+Project {
+ property bool enableExport: false
+ Product {
+ name: "dep"
+ Export {
+ condition: project.enableExport
+ Depends { name: "cpp" }
+ cpp.defines: ["THE_DEFINE"]
+ }
+ }
+ CppApplication {
+ name: "theProduct"
+ Depends { name: "dep" }
+ files: "main.cpp"
+ }
+}
diff --git a/tests/auto/blackbox/testdata/conditional-export/main.cpp b/tests/auto/blackbox/testdata/conditional-export/main.cpp
new file mode 100644
index 000000000..d1c1982b0
--- /dev/null
+++ b/tests/auto/blackbox/testdata/conditional-export/main.cpp
@@ -0,0 +1,5 @@
+#ifndef THE_DEFINE
+#error "missing define"
+#endif
+
+int main() { }
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 8e843f826..2ea112b8e 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -1129,6 +1129,19 @@ void TestBlackbox::concurrentExecutor()
QVERIFY2(!m_qbsStderr.contains("ASSERT"), m_qbsStderr.constData());
}
+void TestBlackbox::conditionalExport()
+{
+ QDir::setCurrent(testDataDir + "/conditional-export");
+ QbsRunParameters params;
+ params.expectFailure = true;
+ QVERIFY(runQbs(params) != 0);
+ QVERIFY2(m_qbsStderr.contains("missing define"), m_qbsStderr.constData());
+
+ params.expectFailure = false;
+ params.arguments << "project.enableExport:true";
+ QCOMPARE(runQbs(params), 0);
+}
+
void TestBlackbox::conflictingArtifacts()
{
QDir::setCurrent(testDataDir + "/conflicting-artifacts");
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index a89b9e537..c71020a89 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -113,6 +113,7 @@ private slots:
void clean();
void cli();
void concurrentExecutor();
+ void conditionalExport();
void conflictingArtifacts();
void dbusAdaptors();
void dbusInterfaces();