diff options
author | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2016-05-19 13:32:44 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2016-05-20 12:44:12 +0000 |
commit | 3872137a82d7abe17e9ebc9af4298c324f9a1003 (patch) | |
tree | ac5c66f9dedb1ed51619c953c5edcf0148aed38d | |
parent | fbf6502160988e0376c26d83732329b226465f27 (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.cpp | 28 | ||||
-rw-r--r-- | src/lib/corelib/language/moduleloader.h | 2 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs | 18 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/conditional-export/main.cpp | 5 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 13 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.h | 1 |
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(); |