diff options
author | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2015-10-26 15:16:41 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2015-10-26 15:28:28 +0100 |
commit | f2c955bcba3d7b477c831e1c53c77ff6024062e4 (patch) | |
tree | 31e08988779d99d208e347fa6d99500240686499 | |
parent | 6b965166479d326aeb43e2e80fa21eedb4be3f7c (diff) | |
parent | 9bbbf55ea6d1e80871ab810eebaeaf377bc0aad0 (diff) |
Merge branch 1.4 into master.
Change-Id: I45ee8897a07522c51833739afc8de374ec269e08
14 files changed, 110 insertions, 34 deletions
diff --git a/doc/reference/items/installpackage.qdoc b/doc/reference/items/installpackage.qdoc index 596de590c..d29a062c6 100644 --- a/doc/reference/items/installpackage.qdoc +++ b/doc/reference/items/installpackage.qdoc @@ -69,7 +69,7 @@ } } - BinaryPackage { + InstallPackage { archiver.type: "tar" name: "tar-package" Depends { name: "myapp" } diff --git a/examples/code-generator/code-generator.qbs b/examples/code-generator/code-generator.qbs index 591d7cb82..a8a804be2 100644 --- a/examples/code-generator/code-generator.qbs +++ b/examples/code-generator/code-generator.qbs @@ -38,16 +38,15 @@ import qbs Project { // A code generator that outputs a "Hello World" C++ program. - Product { + CppApplication { name: "hwgen" - Depends { name: "cpp" } files: ["hwgen.cpp"] + bundle.isBundle: false } // Generate and build a hello-world application. - Product { + CppApplication { name: "hello-world" - Depends { name: "cpp" } Depends { name: "hwgen" } Rule { inputs: ["qbs"] // needed to trigger this rule diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp index a2f18bda8..b5a57afa5 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.cpp +++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp @@ -336,16 +336,11 @@ void BuildGraphLoader::trackProjectChanges() bool BuildGraphLoader::hasEnvironmentChanged(const TopLevelProjectConstPtr &restoredProject) const { - for (QHash<QString, QString>::ConstIterator it = restoredProject->usedEnvironment.constBegin(); - it != restoredProject->usedEnvironment.constEnd(); ++it) { - const QString var = it.key(); - const QString oldValue = it.value(); - const QString newValue = m_environment.value(var); - if (newValue != oldValue) { - m_logger.qbsDebug() << QString::fromLatin1("Environment variable '%1' changed " - "from '%2' to '%3'. Must re-resolve project.").arg(var, oldValue, newValue); - return true; - } + if (m_environment != restoredProject->environment) { + m_logger.qbsDebug() << "Set of environment variables changed. Must re-resolve project."; + m_logger.qbsTrace() << "old: " << restoredProject->environment.toStringList() << "\nnew:" + << m_environment.toStringList(); + return true; } return false; } diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index 3fe36ad61..6bcdcb887 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -187,13 +187,15 @@ private: } if (cr.toBool()) { // condition is true, let's use the value of this alternative - if (alternative->value->sourceUsesOuter()) { + if (alternative->value->sourceUsesOuter() && !outerItem) { // Clone value but without alternatives. JSSourceValuePtr outerValue = JSSourceValue::create(); outerValue->setFile(value->file()); outerValue->setHasFunctionForm(value->hasFunctionForm()); outerValue->setSourceCode(value->sourceCode()); outerValue->setBaseValue(value->baseValue()); + if (value->sourceUsesBase()) + outerValue->setSourceUsesBaseFlag(); outerValue->setLocation(value->line(), value->column()); outerItem = Item::create(data->item->pool()); outerItem->setProperty(propertyName->toString(), outerValue); @@ -213,9 +215,14 @@ private: } setupConvenienceProperty(QLatin1String("base"), &extraScope, baseValue); } - if (value->sourceUsesOuter() && outerItem) - setupConvenienceProperty(QLatin1String("outer"), &extraScope, - data->evaluator->property(outerItem, *propertyName)); + if (value->sourceUsesOuter() && outerItem) { + const QScriptValue v = data->evaluator->property(outerItem, *propertyName); + if (engine->hasErrorOrException(v)) { + *result = engine->lastErrorValue(v); + return; + } + setupConvenienceProperty(QLatin1String("outer"), &extraScope, v); + } if (value->sourceUsesOriginal()) { const Item *item = itemOfProperty; while (item->type() == ItemType::ModuleInstance) diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h index b86cba33d..857170fe0 100644 --- a/src/lib/corelib/language/language.h +++ b/src/lib/corelib/language/language.h @@ -460,7 +460,13 @@ public: QString buildDirectory; // Not saved QProcessEnvironment environment; - QHash<QString, QString> usedEnvironment; // Environment variables requested by the project while resolving. + + // Environment variables requested by the project while resolving. + // TODO: This information is currently not used. Remove in 1.5 or use elaborate change tracking + // logic where rules declare the environment variables that could influence their + // behavior. + QHash<QString, QString> usedEnvironment; + QHash<QString, QString> canonicalFilePathResults; // Results of calls to "File.canonicalFilePath()." QHash<QString, bool> fileExistsResults; // Results of calls to "File.exists()". QHash<QPair<QString, quint32>, QStringList> directoryEntriesResults; // Results of calls to "File.directoryEntries()". diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index aeabfc5e8..c88ca6809 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -273,16 +273,16 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, dummyProductContext.project = &projectContext; dummyProductContext.moduleProperties = m_parameters.finalBuildConfigurationTree(); loadBaseModule(&dummyProductContext, projectItem); - if (!checkItemCondition(projectItem)) { - delete p; - return; - } - topLevelProjectContext->projects << &projectContext; overrideItemProperties(projectItem, QLatin1String("project"), m_parameters.overriddenValuesTree()); const QString projectName = m_evaluator->stringValue(projectItem, QLatin1String("name")); if (!projectName.isEmpty()) overrideItemProperties(projectItem, projectName, m_parameters.overriddenValuesTree()); + if (!checkItemCondition(projectItem)) { + delete p; + return; + } + topLevelProjectContext->projects << &projectContext; m_reader->pushExtraSearchPaths(readExtraSearchPaths(projectItem) << projectItem->file()->dirPath()); projectContext.searchPathsStack = m_reader->extraSearchPathsStack(); diff --git a/src/lib/corelib/language/testdata/dummy.txt b/src/lib/corelib/language/testdata/dummy.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/lib/corelib/language/testdata/dummy.txt diff --git a/src/lib/corelib/language/testdata/properties-block-in-group.qbs b/src/lib/corelib/language/testdata/properties-block-in-group.qbs new file mode 100644 index 000000000..c2bfea0a8 --- /dev/null +++ b/src/lib/corelib/language/testdata/properties-block-in-group.qbs @@ -0,0 +1,16 @@ +import qbs + +Product { + name: "in-group" + property bool featureEnabled: true + Depends { name: "dummy" } + dummy.defines: ["BASEDEF"] + Group { + name: "the group" + files: ["dummy.txt" ] + Properties { + condition: featureEnabled + dummy.defines: outer.concat("FEATURE_ENABLED") + } + } +} diff --git a/src/lib/corelib/language/tst_language.cpp b/src/lib/corelib/language/tst_language.cpp index f9a9e936d..5b4142547 100644 --- a/src/lib/corelib/language/tst_language.cpp +++ b/src/lib/corelib/language/tst_language.cpp @@ -1443,6 +1443,31 @@ void TestLanguage::propertiesBlocks() } } +void TestLanguage::propertiesBlockInGroup() +{ + bool exceptionCaught = false; + try { + defaultParameters.setProjectFilePath(testProject("properties-block-in-group.qbs")); + const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + QVERIFY(project); + QCOMPARE(project->allProducts().count(), 1); + const ResolvedProductConstPtr product = project->allProducts().first(); + const auto groupIt = std::find_if(product->groups.constBegin(), product->groups.constEnd(), + [](const GroupConstPtr &g) { return g->name == "the group"; }); + QVERIFY(groupIt != product->groups.constEnd()); + const QVariantMap propertyMap = (*groupIt)->properties->value(); + const QVariantList value = PropertyFinder().propertyValues(propertyMap, "dummy", "defines"); + QStringList stringListValue; + std::transform(value.constBegin(), value.constEnd(), std::back_inserter(stringListValue), + [](const QVariant &v) { return v.toString(); }); + QCOMPARE(stringListValue, QStringList() << "BASEDEF" << "FEATURE_ENABLED"); + } catch (const ErrorInfo &e) { + exceptionCaught = true; + qDebug() << e.toString(); + } + QCOMPARE(exceptionCaught, false); +} + void TestLanguage::qbsPropertiesInProjectCondition() { bool exceptionCaught = false; diff --git a/src/lib/corelib/language/tst_language.h b/src/lib/corelib/language/tst_language.h index 58623183e..902697af6 100644 --- a/src/lib/corelib/language/tst_language.h +++ b/src/lib/corelib/language/tst_language.h @@ -107,6 +107,7 @@ private slots: void profileValuesAndOverriddenValues(); void propertiesBlocks_data(); void propertiesBlocks(); + void propertiesBlockInGroup(); void qbsPropertiesInProjectCondition(); void defaultValue(); void defaultValue_data(); diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/hidden/hiddenheaderqbs.h b/tests/auto/blackbox/testdata/trackExternalProductChanges/hidden/hiddenheaderqbs.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/hidden/hiddenheaderqbs.h diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/including.cpp b/tests/auto/blackbox/testdata/trackExternalProductChanges/including.cpp new file mode 100644 index 000000000..bfe738d1d --- /dev/null +++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/including.cpp @@ -0,0 +1,3 @@ +#include <hiddenheaderqbs.h> + +void f() {} diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs b/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs index df1ddc1f9..451b0a25a 100644 --- a/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs +++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs @@ -6,4 +6,10 @@ CppApplication { property stringList filesFromEnv: qbs.getEnv("QBS_TEST_PULL_IN_FILE_VIA_ENV") ? ["environmentChange.cpp"] : [] files: ["main.cpp"].concat(FileList.fileList()).concat(filesFromEnv).concat(FileList.filesFromFs(qbs)) + + Group { + condition: qbs.getEnv("INCLUDE_PATH_TEST") + name: "file that needs help from the environment to find a header" + files: "including.cpp" + } } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index ecf5189d0..eed5e1438 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -884,6 +884,22 @@ void TestBlackbox::trackExternalProductChanges() QVERIFY(!m_qbsStdout.contains("compiling environmentChange.cpp")); QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp")); QVERIFY(m_qbsStdout.contains("compiling fileExists.cpp")); + + rmDirR(relativeBuildDir()); + Settings s((QString())); + const Profile profile(profileName(), &s); + const QStringList toolchainTypes = profile.value("qbs.toolchain").toStringList(); + if (!toolchainTypes.contains("gcc")) + QSKIP("Need GCC-like compiler to run this test"); + params.environment = QProcessEnvironment::systemEnvironment(); + params.environment.insert("INCLUDE_PATH_TEST", "1"); + params.expectFailure = true; + QVERIFY(runQbs(params) != 0); + QVERIFY2(m_qbsStderr.contains("hiddenheaderqbs.h"), m_qbsStderr.constData()); + params.environment.insert("CPLUS_INCLUDE_PATH", + QDir::toNativeSeparators(QDir::currentPath() + "/hidden")); + params.expectFailure = false; + QCOMPARE(runQbs(params), 0); } void TestBlackbox::trackRemoveFile() @@ -1712,15 +1728,17 @@ void TestBlackbox::java() process.setProcessEnvironment(processEnvironmentWithCurrentDirectoryInLibraryPath()); process.start(HostOsInfo::appendExecutableSuffix(jdkTools["java"]), QStringList() << "-jar" << "jar_file.jar"); - QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); - QVERIFY2(process.exitCode() == 0, process.readAllStandardError().constData()); - const QByteArray stdOut = process.readAllStandardOutput(); - QVERIFY2(stdOut.contains("Driving!"), stdOut.constData()); - QVERIFY2(stdOut.contains("Flying!"), stdOut.constData()); - QVERIFY2(stdOut.contains("Flying (this is a space ship)!"), stdOut.constData()); - QVERIFY2(stdOut.contains("Sailing!"), stdOut.constData()); - QVERIFY2(stdOut.contains("Native code performing complex internal combustion process ("), - stdOut.constData()); + if (process.waitForStarted()) { + QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); + QVERIFY2(process.exitCode() == 0, process.readAllStandardError().constData()); + const QByteArray stdOut = process.readAllStandardOutput(); + QVERIFY2(stdOut.contains("Driving!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Flying!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Flying (this is a space ship)!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Sailing!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Native code performing complex internal combustion process ("), + stdOut.constData()); + } process.start("unzip", QStringList() << "-p" << "jar_file.jar"); if (process.waitForStarted()) { |