diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-06-29 10:44:52 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-06-29 10:44:52 +0200 |
commit | 5821d32afc9eb44359ce6934d8c6d25afd7088d9 (patch) | |
tree | a535076493e87cab9b3c3dce495baa562ebee18a | |
parent | 07bf66a03e775aeb9f46f46204e6633398b650a5 (diff) | |
parent | 872e4b883d7732c46e1e5d32b60ce698862e5da6 (diff) | |
download | qbs-5821d32afc9eb44359ce6934d8c6d25afd7088d9.tar.gz |
Merge 1.12 into master
Change-Id: Ieaf617a09ed16cf0c81ea7621d4d0ba23741fbfa
-rw-r--r-- | share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs | 7 | ||||
-rw-r--r-- | share/qbs/modules/Exporter/qbs/qbsexporter.qbs | 4 | ||||
-rw-r--r-- | share/qbs/modules/cpp/UnixGCC.qbs | 4 | ||||
-rw-r--r-- | share/qbs/modules/cpp/gcc.js | 11 | ||||
-rw-r--r-- | src/app/qbs-setup-android/android-setup.cpp | 8 | ||||
-rw-r--r-- | src/lib/corelib/jsextensions/moduleproperties.cpp | 14 | ||||
-rw-r--r-- | src/lib/corelib/language/evaluatorscriptclass.cpp | 12 | ||||
-rw-r--r-- | src/lib/corelib/language/moduleloader.cpp | 31 | ||||
-rw-r--r-- | src/lib/qtprofilesetup/templates/qml.qbs | 8 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 26 | ||||
-rw-r--r-- | tests/auto/language/testdata/dotted-names/dotted-names.qbs | 24 | ||||
-rw-r--r-- | tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs | 5 | ||||
-rw-r--r-- | tests/auto/language/testdata/erroneous/original-in-export-item2.qbs | 14 | ||||
-rw-r--r-- | tests/auto/language/testdata/erroneous/original-in-export-item3.qbs | 17 | ||||
-rw-r--r-- | tests/auto/language/tst_language.cpp | 51 | ||||
-rw-r--r-- | tests/auto/language/tst_language.h | 2 | ||||
-rw-r--r-- | tests/benchmarker/benchmarker-main.cpp | 13 |
17 files changed, 213 insertions, 38 deletions
diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs index 7037a58cd..8cc55f885 100644 --- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs +++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs @@ -31,11 +31,8 @@ Module { requiresInputs: false // Make sure all relevant library artifacts have been created by the time we run. - inputsFromDependencies: autoDetect - ? ["Exporter.pkgconfig.pc", "staticlibrary", "dynamiclibrary"] - : [] - inputs: { - if (!product.Exporter.pkgconfig.autoDetect) + auxiliaryInputs: { + if (!autoDetect) return undefined; if (product.type.contains("staticlibrary")) return ["staticlibrary"]; diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs index 093512c6d..861483ef0 100644 --- a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs +++ b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs @@ -48,7 +48,9 @@ Module { requiresInputs: false // Make sure we only run when all other artifacts are already present. - inputs: product.type.filter(function(t) { return t !== "Exporter.qbs.module"; }) + // TODO: This also matches target artifacts in dependencies. Should not hurt, + // but might be a hint that we should have auxiliaryInputsFromDependencies. + auxiliaryInputs: product.type.filter(function(t) { return t !== "Exporter.qbs.module"; }) Artifact { filePath: product.Exporter.qbs.fileName diff --git a/share/qbs/modules/cpp/UnixGCC.qbs b/share/qbs/modules/cpp/UnixGCC.qbs index 90df34c24..e5b99cd98 100644 --- a/share/qbs/modules/cpp/UnixGCC.qbs +++ b/share/qbs/modules/cpp/UnixGCC.qbs @@ -28,6 +28,8 @@ ** ****************************************************************************/ +import qbs.File + GenericGCC { condition: qbs.toolchain && qbs.toolchain.contains("gcc") && qbs.targetOS && qbs.targetOS.contains("unix") @@ -40,7 +42,7 @@ GenericGCC { dynamicLibrarySuffix: ".so" debugInfoSuffix: ".debug" imageFormat: "elf" - systemRunPaths: ["/lib", "/usr/lib"] + systemRunPaths: ["/lib", "/usr/lib"].filter(function(p) { return File.exists(p); }) rpathOrigin: "$ORIGIN" useRPathLink: true rpathLinkFlag: "-rpath-link=" diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index 896ae48fa..95e3d198c 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -254,6 +254,9 @@ function linkerFlags(project, product, inputs, output, linkerPath) { var weakFrameworks = product.cpp.weakFrameworks; var rpaths = (product.cpp.useRPaths !== false) ? product.cpp.rpaths : undefined; var systemRunPaths = product.cpp.systemRunPaths || []; + var canonicalSystemRunPaths = systemRunPaths.map(function(p) { + return File.canonicalFilePath(p); + }); var i, args = additionalCompilerAndLinkerFlags(product); var escapableLinkerFlags = []; @@ -337,8 +340,12 @@ function linkerFlags(project, product, inputs, output, linkerPath) { return rpath; } + function isNotSystemRunPath(p) { + return !systemRunPaths.contains(p) + && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)); + }; for (i in rpaths) { - if (systemRunPaths.indexOf(rpaths[i]) === -1) + if (isNotSystemRunPath(rpaths[i])) escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i])); } @@ -382,6 +389,8 @@ function linkerFlags(project, product, inputs, output, linkerPath) { allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths); if (distributionLibraryPaths) allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths); + if (systemRunPaths.length > 0) + allLibraryPaths = allLibraryPaths.filter(isNotSystemRunPath); args = args.concat(allLibraryPaths.map(function(path) { return '-L' + path })); var linkerScripts = inputs.linkerscript diff --git a/src/app/qbs-setup-android/android-setup.cpp b/src/app/qbs-setup-android/android-setup.cpp index a2c3768c2..eb5ba92dd 100644 --- a/src/app/qbs-setup-android/android-setup.cpp +++ b/src/app/qbs-setup-android/android-setup.cpp @@ -197,8 +197,12 @@ static void setupNdk(qbs::Settings *settings, const QString &profileName, const mainProfile.setValue(qls("qbs.toolchain"), QStringList() << qls("gcc")); const QStringList archs = expectedArchs(); const QtInfoPerArch infoPerArch = getQtAndroidInfo(qtSdkDirPath); - mainProfile.setValue(qls("qbs.architectures"), infoPerArch.empty() - ? archs : QStringList(infoPerArch.keys())); + const QStringList archsForProfile = infoPerArch.empty() + ? archs : QStringList(infoPerArch.keys()); + if (archsForProfile.size() == 1) + mainProfile.setValue(qls("qbs.architecture"), archsForProfile.front()); + else + mainProfile.setValue(qls("qbs.architectures"), archsForProfile); QStringList searchPaths; QString platform; for (const QString &arch : archs) { diff --git a/src/lib/corelib/jsextensions/moduleproperties.cpp b/src/lib/corelib/jsextensions/moduleproperties.cpp index 7d0a3e0b6..d80a4bc5f 100644 --- a/src/lib/corelib/jsextensions/moduleproperties.cpp +++ b/src/lib/corelib/jsextensions/moduleproperties.cpp @@ -82,12 +82,6 @@ static QScriptValue getModuleProperty(const ResolvedProduct *product, const Arti value = engine->retrieveFromPropertyCache(moduleName, propertyName, properties); if (!value.isValid()) { value = properties->moduleProperty(moduleName, propertyName, isPresent); - const Property p(product->uniqueName(), moduleName, propertyName, value, - Property::PropertyInModule); - if (artifact) - engine->addPropertyRequestedFromArtifact(artifact, p); - else - engine->addPropertyRequestedInScript(p); // Cache the variant value. We must not cache the QScriptValue here, because it's a // reference and the user might change the actual object. @@ -96,6 +90,14 @@ static QScriptValue getModuleProperty(const ResolvedProduct *product, const Arti } else if (isPresent) { *isPresent = true; } + + const Property p(product->uniqueName(), moduleName, propertyName, value, + Property::PropertyInModule); + if (artifact) + engine->addPropertyRequestedFromArtifact(artifact, p); + else + engine->addPropertyRequestedInScript(p); + return engine->toScriptValue(value); } diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index 18d7fd83f..6db308a7f 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -184,6 +184,18 @@ private: result.second = false; return result; } + + // TODO: Provide a dedicated item type for not-yet-instantiated things that + // look like module instances in the AST visitor. + if (item->type() == ItemType::ModuleInstance + && !item->hasProperty(StringConstants::presentProperty())) { + const QString errorMessage = Tr::tr("Trying to assign property '%1' " + "on something that is not a module.").arg(propertyName->toString()); + extraScope = engine->currentContext()->throwError(errorMessage); + result.second = false; + return result; + } + while (item->type() == ItemType::ModuleInstance) item = item->prototype(); if (item->type() != ItemType::Module && item->type() != ItemType::Export) { diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index 41781cb7d..1cc894232 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -366,7 +366,7 @@ class PropertyDeclarationCheck : public ValueHandler { const Set<Item *> &m_disabledItems; Set<Item *> m_handledItems; - Item *m_parentItem; + std::vector<Item *> m_parentItems; Item *m_currentModuleInstance = nullptr; QualifiedId m_currentModuleName; QString m_currentName; @@ -376,7 +376,6 @@ public: PropertyDeclarationCheck(const Set<Item *> &disabledItems, const SetupProjectParameters ¶ms, Logger &logger) : m_disabledItems(disabledItems) - , m_parentItem(nullptr) , m_params(params) , m_logger(logger) { @@ -406,13 +405,13 @@ private: bool checkItemValue(ItemValue *value) { // TODO: Remove once QBS-1030 is fixed. - if (m_parentItem->type() == ItemType::Artifact) + if (parentItem()->type() == ItemType::Artifact) return false; - if (m_parentItem->type() == ItemType::Properties) + if (parentItem()->type() == ItemType::Properties) return false; - if (m_parentItem->isOfTypeOrhasParentOfType(ItemType::Export)) { + if (parentItem()->isOfTypeOrhasParentOfType(ItemType::Export)) { // Export item prototypes do not have instantiated modules. // The module instances are where the Export is used. QBS_ASSERT(m_currentModuleInstance, return false); @@ -430,14 +429,15 @@ private: if (!itemIsModuleInstance && value->item()->type() != ItemType::ModulePrefix - && m_parentItem->file() - && (!m_parentItem->file()->idScope() - || !m_parentItem->file()->idScope()->hasProperty(m_currentName)) + && (!parentItem()->file() || !parentItem()->file()->idScope() + || !parentItem()->file()->idScope()->hasProperty(m_currentName)) && !value->createdByPropertiesBlock()) { + CodeLocation location = value->location(); + for (int i = int(m_parentItems.size() - 1); !location.isValid() && i >= 0; --i) + location = m_parentItems.at(i)->location(); const ErrorInfo error(Tr::tr("Item '%1' is not declared. " - "Did you forget to add a Depends item?").arg(m_currentName), - value->location().isValid() ? value->location() - : m_parentItem->location()); + "Did you forget to add a Depends item?") + .arg(m_currentModuleName.toString()), location); handlePropertyError(error, m_params, m_logger); return false; } @@ -458,8 +458,7 @@ private: return; } - Item *oldParentItem = m_parentItem; - m_parentItem = item; + m_parentItems.push_back(item); for (Item::PropertyMap::const_iterator it = item->properties().constBegin(); it != item->properties().constEnd(); ++it) { const PropertyDeclaration decl = item->propertyDeclaration(it.key()); @@ -490,13 +489,13 @@ private: } m_currentName = it.key(); const QualifiedId oldModuleName = m_currentModuleName; - if (m_parentItem->type() != ItemType::ModulePrefix) + if (parentItem()->type() != ItemType::ModulePrefix) m_currentModuleName.clear(); m_currentModuleName.push_back(m_currentName); it.value()->apply(this); m_currentModuleName = oldModuleName; } - m_parentItem = oldParentItem; + m_parentItems.pop_back(); for (Item * const child : item->children()) { switch (child->type()) { case ItemType::Export: @@ -526,6 +525,8 @@ private: } void handle(VariantValue *) override { /* only created internally - no need to check */ } + + Item *parentItem() const { return m_parentItems.back(); } }; void ModuleLoader::handleTopLevelProject(ModuleLoaderResult *loadResult, Item *projectItem, diff --git a/src/lib/qtprofilesetup/templates/qml.qbs b/src/lib/qtprofilesetup/templates/qml.qbs index 854b30006..8c518c9f1 100644 --- a/src/lib/qtprofilesetup/templates/qml.qbs +++ b/src/lib/qtprofilesetup/templates/qml.qbs @@ -14,9 +14,13 @@ QtModule { Depends { name: "Qt.qmlcache"; condition: generateCacheFiles; required: false } readonly property bool cachingEnabled: generateCacheFiles && Qt.qmlcache.present property string qmlCacheGenPath - Qt.qmlcache.qmlCacheGenPath: qmlCacheGenPath || original + Properties { + condition: cachingEnabled + Qt.qmlcache.qmlCacheGenPath: qmlCacheGenPath || original + Qt.qmlcache.installDir: cacheFilesInstallDir || original + } + property string cacheFilesInstallDir - Qt.qmlcache.installDir: cacheFilesInstallDir || original readonly property string pluginListFilePathDebug: product.buildDirectory + "/plugins.list.d" readonly property string pluginListFilePathRelease: product.buildDirectory + "/plugins.list" diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 186f3280a..ad4b5c47d 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -3383,6 +3383,8 @@ void TestBlackbox::exportsPkgconfig() { QDir::setCurrent(testDataDir + "/exports-pkgconfig"); QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("Creating TheFirstLib.pc"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("Creating TheSecondLib.pc"), m_qbsStdout.constData()); QFile sourcePcFile(HostOsInfo::isWindowsHost() ? "TheFirstLib_windows.pc" : "TheFirstLib.pc"); QString generatedPcFilePath = relativeProductBuildDir("TheFirstLib") + "/TheFirstLib.pc"; QFile generatedPcFile(generatedPcFilePath); @@ -3393,6 +3395,12 @@ void TestBlackbox::exportsPkgconfig() generatedPcFile.close(); TEXT_FILE_COMPARE(relativeProductBuildDir("TheSecondLib") + "/TheSecondLib.pc", "TheSecondLib.pc"); + WAIT_FOR_NEW_TIMESTAMP(); + touch("firstlib.cpp"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("linking"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("Creating TheFirstLib.pc"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("Creating TheSecondLib.pc"), m_qbsStdout.constData()); } void TestBlackbox::exportsQbs() @@ -3445,6 +3453,24 @@ void TestBlackbox::exportsQbs() QCOMPARE(runQbs(QStringList({"-p", "MyTool"})), 0); QVERIFY2(!m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData()); + // Rebuilding the target binary should not cause recreating the module file. + WAIT_FOR_NEW_TIMESTAMP(); + touch("mylib.cpp"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.count("linking") >= 2, m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("Creating MyLib"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData()); + + // Changing a setting that influences the name of a target artifact should cause + // recreating the module file. + const QbsRunParameters resolveParams("resolve", QStringList{"-f", "exports-qbs.qbs", + "modules.cpp.dynamicLibrarySuffix:.blubb"}); + QCOMPARE(runQbs(resolveParams), 0); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.count("linking") >= 2, m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.count("Creating MyLib") == 2, m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData()); + // Change tracking for accesses to product.exports (positive). WAIT_FOR_NEW_TIMESTAMP(); REPLACE_IN_FILE("tool.qbs", "product.toolTags", "[]"); diff --git a/tests/auto/language/testdata/dotted-names/dotted-names.qbs b/tests/auto/language/testdata/dotted-names/dotted-names.qbs new file mode 100644 index 000000000..cf5658384 --- /dev/null +++ b/tests/auto/language/testdata/dotted-names/dotted-names.qbs @@ -0,0 +1,24 @@ +import qbs + +Project { + name: "theProject" + property bool includeDottedProduct + property bool includeDottedModule + + Project { + condition: project.includeDottedProduct + Product { + name: "a.b" + Export { property string c: "default" } + } + } + + Product { + name: "p" + Depends { name: "a.b"; condition: project.includeDottedProduct } + Depends { name: "x.y"; condition: project.includeDottedModule } + a.b.c: "p" + x.y.z: "p" + } +} + diff --git a/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs b/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs new file mode 100644 index 000000000..71cfac9cb --- /dev/null +++ b/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs @@ -0,0 +1,5 @@ +import qbs + +Module { + property string z: "default" +} diff --git a/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs b/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs new file mode 100644 index 000000000..d932d4aee --- /dev/null +++ b/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs @@ -0,0 +1,14 @@ +import qbs + +Project { + Product { + name: "a" + Export { + x.y.z: original + } + } + Product { + name: "b" + Depends { name: "a" } + } +} diff --git a/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs b/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs new file mode 100644 index 000000000..d7bcb322e --- /dev/null +++ b/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs @@ -0,0 +1,17 @@ +import qbs + +Project { + Product { + name: "a" + Export { + Properties { + condition: true + x.y.z: original + } + } + } + Product { + name: "b" + Depends { name: "a" } + } +} diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index c17526ad8..fce799a0f 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -581,6 +581,50 @@ void TestLanguage::disabledSubProject() QCOMPARE(exceptionCaught, false); } +void TestLanguage::dottedNames_data() +{ + QTest::addColumn<bool>("useProduct"); + QTest::addColumn<bool>("useModule"); + QTest::addColumn<bool>("expectSuccess"); + QTest::addColumn<QString>("expectedErrorMessage"); + QTest::newRow("missing product dependency") << false << true << false + << QString("Item 'a.b' is not declared. Did you forget to add a Depends item"); + QTest::newRow("missing module dependency") << true << false << false + << QString("Item 'x.y' is not declared. Did you forget to add a Depends item"); + QTest::newRow("missing both dependencies") << false << false << false << QString(); + QTest::newRow("ok") << true << true << true << QString(); +} + +void TestLanguage::dottedNames() +{ + QFETCH(bool, expectSuccess); + try { + SetupProjectParameters params = defaultParameters; + params.setProjectFilePath(testProject("dotted-names/dotted-names.qbs")); + QFETCH(bool, useProduct); + QFETCH(bool, useModule); + const QVariantMap overridden{ + std::make_pair("projects.theProject.includeDottedProduct", useProduct), + std::make_pair("projects.theProject.includeDottedModule", useModule) + }; + params.setOverriddenValues(overridden); + TopLevelProjectPtr project = loader->loadProject(params); + QVERIFY(expectSuccess); + QVERIFY(!!project); + QHash<QString, ResolvedProductPtr> products = productsFromProject(project); + QCOMPARE(products.size(), useProduct ? 2 : 1); + const ResolvedProductPtr product = products.value("p"); + QVERIFY(!!product); + QCOMPARE(product->moduleProperties->moduleProperty("a.b", "c").toString(), QString("p")); + QCOMPARE(product->moduleProperties->moduleProperty("x.y", "z").toString(), QString("p")); + } catch (const ErrorInfo &e) { + QVERIFY(!expectSuccess); + QFETCH(QString, expectedErrorMessage); + if (!expectedErrorMessage.isEmpty()) + QVERIFY2(e.toString().contains(expectedErrorMessage), qPrintable(e.toString())); + } +} + void TestLanguage::emptyJsFile() { bool exceptionCaught = false; @@ -839,6 +883,12 @@ void TestLanguage::erroneousFiles_data() QTest::newRow("original-in-export-item") << "original-in-export-item.qbs:7:32.*The special value 'original' cannot be used " "on the right-hand side of a property declaration."; + QTest::newRow("original-in-export-item2") + << "original-in-export-item2.qbs:6:9.*Item 'x.y' is not declared. Did you forget " + "to add a Depends item"; + QTest::newRow("original-in-export-item3") + << "original-in-export-item3.qbs:6:9.*Item 'x.y' is not declared. Did you forget " + "to add a Depends item"; QTest::newRow("mismatching-multiplex-dependency") << "mismatching-multiplex-dependency.qbs:7:5.*Dependency from product " "'b \\{\"architecture\":\"mips\"\\}' to product 'a \\{\"architecture\":\"mips\"\\}'" @@ -868,6 +918,7 @@ void TestLanguage::erroneousFiles() return; } QEXPECT_FAIL("undeclared_property_in_Properties_item", "Too expensive to check", Continue); + QEXPECT_FAIL("original-in-export-item3", "Too expensive to check", Continue); QVERIFY(!"No error thrown on invalid input."); } diff --git a/tests/auto/language/tst_language.h b/tests/auto/language/tst_language.h index aab04ca29..18027ab45 100644 --- a/tests/auto/language/tst_language.h +++ b/tests/auto/language/tst_language.h @@ -91,6 +91,8 @@ private slots: void dependencyOnAllProfiles(); void derivedSubProject(); void disabledSubProject(); + void dottedNames_data(); + void dottedNames(); void emptyJsFile(); void enumerateProjectProperties(); void environmentVariable(); diff --git a/tests/benchmarker/benchmarker-main.cpp b/tests/benchmarker/benchmarker-main.cpp index e9d483f96..51eb85dcf 100644 --- a/tests/benchmarker/benchmarker-main.cpp +++ b/tests/benchmarker/benchmarker-main.cpp @@ -104,12 +104,12 @@ static void printResults(Activities activities, const BenchmarkResults &results, int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + CommandLineParser clParser; + clParser.parse(); + Benchmarker benchmarker(clParser.activies(), clParser.oldCommit(), clParser.newCommit(), + clParser.testProjectFilePath(), clParser.qbsRepoDirPath()); try { - QCoreApplication app(argc, argv); - CommandLineParser clParser; - clParser.parse(); - Benchmarker benchmarker(clParser.activies(), clParser.oldCommit(), clParser.newCommit(), - clParser.testProjectFilePath(), clParser.qbsRepoDirPath()); benchmarker.benchmark(); printResults(clParser.activies(), benchmarker.results(), clParser.regressionThreshold()); if (hasRegression) { @@ -118,7 +118,10 @@ int main(int argc, char *argv[]) "under " << qPrintable(benchmarker.rawDataBaseDir()) << '.' << std::endl; } } catch (const Exception &e) { + benchmarker.keepRawData(); std::cerr << qPrintable(e.description()) << std::endl; + std::cerr << "Build data available under " << qPrintable(benchmarker.rawDataBaseDir()) + << '.' << std::endl; return EXIT_FAILURE; } } |