diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2016-10-17 11:43:09 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2016-10-17 11:43:09 +0200 |
commit | 830503d04708ebd6a64dfd260b35cfeea26ba60a (patch) | |
tree | b43c489469f8d452e7ba9d568f0f1d36e85fbe08 | |
parent | b2b9d77f5cdfbb5ed19554e2d424b5be75ef8e73 (diff) | |
parent | 704eb30d27117d88e3edbe5d255ea5b8989509f3 (diff) |
Merge 1.6 into master
Change-Id: Ie98233d955f3695da0b20069fb2317931e353e4e
18 files changed, 189 insertions, 51 deletions
diff --git a/doc/reference/modules/cpp-module.qdoc b/doc/reference/modules/cpp-module.qdoc index e8994c76c..160ee977f 100644 --- a/doc/reference/modules/cpp-module.qdoc +++ b/doc/reference/modules/cpp-module.qdoc @@ -319,6 +319,13 @@ \li determined by qbs-setup-toolchains \li Full path of the linker binary. This is set in the build profile. \row + \li linkerWrapper + \li \c{stringList} + \li 1.6.2 + \li \c{undefined} + \li Wrapper binary and its arguments for wrapping linker calls. + This is useful for linker wrappers as needed by Bullseye Coverage, for example. + \row \li entryPoint \li \c{string} \li 1.3 diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs index a267b5252..7c2278977 100644 --- a/share/qbs/modules/bundle/BundleModule.qbs +++ b/share/qbs/modules/bundle/BundleModule.qbs @@ -487,7 +487,7 @@ Module { condition: qbs.targetOS.contains("darwin") multiplex: true inputs: ["aggregate_infoplist", "pkginfo", "hpp", - "icns", "resourcerules", "xcent", + "icns", "xcent", "compiled_ibdoc", "compiled_assetcatalog", "xcode.provisioningprofile.main"] diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs index 6aa0211a3..2459a419b 100644 --- a/share/qbs/modules/cpp/CppModule.qbs +++ b/share/qbs/modules/cpp/CppModule.qbs @@ -146,6 +146,7 @@ Module { property stringList compilerWrapper property string linkerName property string linkerPath: linkerName + property stringList linkerWrapper property string staticLibraryPrefix property string dynamicLibraryPrefix property string loadableModulePrefix diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index 7c85f1ed4..3590bd34c 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -749,10 +749,22 @@ function prepareLinker(project, product, inputs, outputs, input, output) { primaryOutput = outputs.loadablemodule[0]; } - cmd = new Command(effectiveLinkerPath(product, inputs), - linkerFlags(project, product, inputs, primaryOutput)); + var linkerPath = effectiveLinkerPath(product, inputs) + + var args = linkerFlags(project, product, inputs, primaryOutput) + var wrapperArgsLength = 0; + var wrapperArgs = ModUtils.moduleProperty(product, "linkerWrapper"); + if (wrapperArgs && wrapperArgs.length > 0) { + wrapperArgsLength = wrapperArgs.length; + args.unshift(linkerPath); + linkerPath = wrapperArgs.shift(); + args = wrapperArgs.concat(args); + } + + cmd = new Command(linkerPath, args); cmd.description = 'linking ' + primaryOutput.fileName; cmd.highlight = 'linker'; + cmd.responseFileArgumentIndex = wrapperArgsLength; cmd.responseFileUsagePrefix = '@'; commands.push(cmd); diff --git a/share/qbs/modules/cpp/ios-gcc.qbs b/share/qbs/modules/cpp/ios-gcc.qbs index 1ab6e8021..2ff4dc49c 100644 --- a/share/qbs/modules/cpp/ios-gcc.qbs +++ b/share/qbs/modules/cpp/ios-gcc.qbs @@ -62,30 +62,6 @@ DarwinGCC { Rule { condition: !product.moduleProperty("qbs", "targetOS").contains("ios-simulator") - multiplex: true - inputs: ["qbs"] - - Artifact { - filePath: product.destinationDirectory + "/" - + product.moduleProperty("bundle", "contentsFolderPath") - + "/ResourceRules.plist" - fileTags: ["resourcerules"] - } - - prepare: { - var cmd = new JavaScriptCommand(); - cmd.description = "generating ResourceRules"; - cmd.highlight = "codegen"; - cmd.sysroot = product.moduleProperty("qbs","sysroot"); - cmd.sourceCode = function() { - File.copy(sysroot + "/ResourceRules.plist", outputs.resourcerules[0].filePath); - } - return cmd; - } - } - - Rule { - condition: !product.moduleProperty("qbs", "targetOS").contains("ios-simulator") inputsFromDependencies: ["bundle"] Artifact { diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js index b8464a651..cb8c48482 100644 --- a/share/qbs/modules/cpp/msvc.js +++ b/share/qbs/modules/cpp/msvc.js @@ -319,8 +319,15 @@ function prepareLinker(project, product, inputs, outputs, input, output) { if (ModUtils.moduleProperty(product, "allowUnresolvedSymbols")) args.push("/FORCE:UNRESOLVED"); + var linkerPath = product.moduleProperty("cpp", "linkerPath"); + var wrapperArgs = product.moduleProperty("cpp", "linkerWrapper"); + if (wrapperArgs && wrapperArgs.length > 0) { + args.unshift(linkerPath); + linkerPath = wrapperArgs.shift(); + args = wrapperArgs.concat(args); + } var commands = []; - var cmd = new Command(product.moduleProperty("cpp", "linkerPath"), args) + var cmd = new Command(linkerPath, args) cmd.description = 'linking ' + primaryOutput.fileName; cmd.highlight = 'linker'; cmd.workingDirectory = FileInfo.path(primaryOutput.filePath) diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index 7ca472364..e7d5a3647 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -422,11 +422,17 @@ static void makeTypeError(const PropertyDeclaration &decl, const CodeLocation &l } static void convertToPropertyType(const Item *item, const PropertyDeclaration& decl, - const CodeLocation &location, QScriptValue &v) + const Value *value, QScriptValue &v) { + if (value->type() == Value::VariantValueType && v.isUndefined() && !decl.isScalar()) { + v = v.engine()->newArray(); // QTBUG-51237 + return; + } + if (v.isUndefined() || v.isError()) return; QString srcDir; + const CodeLocation &location = value->location(); switch (decl.type()) { case PropertyDeclaration::UnknownType: case PropertyDeclaration::Variant: @@ -537,7 +543,7 @@ QScriptValue EvaluatorScriptClass::property(const QScriptValue &object, const QS converter.start(); const PropertyDeclaration decl = data->item->propertyDeclaration(name.toString()); - convertToPropertyType(data->item, decl, value->location(), result); + convertToPropertyType(data->item, decl, value.data(), result); } if (debugProperties) diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index eeb33662b..2b180e920 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -1144,7 +1144,12 @@ QVariantMap ProjectResolver::evaluateProperties(Item *item, Item *propertiesCont if (result.contains(it.key())) break; VariantValuePtr vvp = it.value().staticCast<VariantValue>(); - result[it.key()] = vvp->value(); + QVariant v = vvp->value(); + + if (v.isNull() && !item->propertyDeclaration(it.key()).isScalar()) // QTBUG-51237 + v = QStringList(); + + result[it.key()] = v; break; } } diff --git a/src/lib/corelib/language/testdata/modulepropertiesingroups.qbs b/src/lib/corelib/language/testdata/modulepropertiesingroups.qbs index 6bfbf42d3..22fb750e4 100644 --- a/src/lib/corelib/language/testdata/modulepropertiesingroups.qbs +++ b/src/lib/corelib/language/testdata/modulepropertiesingroups.qbs @@ -3,11 +3,34 @@ import qbs 1.0 Project { Product { name: "grouptest" + + Depends { name: "gmod1" } Depends { name: "dummyqt.core" } + + gmod1.listProp2: ["product", gmod1.stringProp] + gmod1.p1: 1 + + // TODO: Also test nested groups in >= 1.7 Group { - name: "thegroup" + name: "g1" files: ["Banana"] + + gmod1.stringProp: "g1" + gmod1.listProp2: ["g1"] + gmod1.p2: 2 + gmod2.prop: 1 dummyqt.core.zort: "X" } + + Group { + name: "g2" + files: ["zort"] + + gmod1.stringProp: "g2" + gmod1.listProp2: ["g2"] + gmod1.p1: 2 + gmod1.p2: 4 + gmod2.prop: 2 + } } } diff --git a/src/lib/corelib/language/testdata/modules/gmod1/gmod1.qbs b/src/lib/corelib/language/testdata/modules/gmod1/gmod1.qbs new file mode 100644 index 000000000..416372e3d --- /dev/null +++ b/src/lib/corelib/language/testdata/modules/gmod1/gmod1.qbs @@ -0,0 +1,12 @@ +import qbs + +Module { + Depends { name: "gmod2" } + property stringList listProp1: ["prototype", stringProp] + property stringList listProp2: ["prototype"] + property string stringProp: "prototype" + property int depProp: gmod2.prop + property int p0: p1 + p2 + property int p1: 0 + property int p2: 0 +} diff --git a/src/lib/corelib/language/testdata/modules/gmod2/gmod2.qbs b/src/lib/corelib/language/testdata/modules/gmod2/gmod2.qbs new file mode 100644 index 000000000..208f7330d --- /dev/null +++ b/src/lib/corelib/language/testdata/modules/gmod2/gmod2.qbs @@ -0,0 +1,5 @@ +import qbs + +Module { + property int prop: 0 +} diff --git a/src/lib/corelib/language/tst_language.cpp b/src/lib/corelib/language/tst_language.cpp index 6647089ee..ccea88737 100644 --- a/src/lib/corelib/language/tst_language.cpp +++ b/src/lib/corelib/language/tst_language.cpp @@ -1129,21 +1129,62 @@ void TestLanguage::modulePropertiesInGroups() const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); const ResolvedProductPtr product = products.value("grouptest"); QVERIFY(product); - GroupConstPtr group; + GroupConstPtr g1; + GroupConstPtr g2; foreach (const GroupConstPtr &g, product->groups) { - if (g->name == "thegroup") { - group = g; - break; - } + if (g->name == "g1") + g1= g; + else if (g->name == "g2") + g2 = g; } - QVERIFY(group); - QVariantList values = PropertyFinder().propertyValue(group->properties->value(), - "dummy", "cFlags").toList(); - QStringList valueStrings; - foreach (const QVariant &v, values) - valueStrings += v.toString(); + QVERIFY(g1); + QVERIFY(g2); + + const QVariantMap productProps = product->moduleProperties->value(); + PropertyFinder pf; + + const auto &productListProp1 = pf.propertyValue(productProps, "gmod1", "listProp1") + .toStringList(); + QCOMPARE(productListProp1, QStringList() << "prototype" << "prototype"); + const auto &productListProp2 = pf.propertyValue(productProps, "gmod1", "listProp2") + .toStringList(); + QCOMPARE(productListProp2, QStringList() << "product" << "prototype" << "prototype"); + const int productP0 = pf.propertyValue(productProps, "gmod1", "p0").toInt(); + QCOMPARE(productP0, 1); + const int productDepProp = pf.propertyValue(productProps, "gmod1", "depProp").toInt(); + QCOMPARE(productDepProp, 0); + + const QVariantMap g1Props = g1->properties->value(); + const auto &g1ListProp1 = pf.propertyValue(g1Props, "gmod1", "listProp1") + .toStringList(); + QCOMPARE(g1ListProp1, QStringList() << "prototype" << "g1"); + const auto &g1ListProp2 = pf.propertyValue(g1Props, "gmod1", "listProp2") + .toStringList(); + QEXPECT_FAIL(0, "QBS-1005", Continue); + QCOMPARE(g1ListProp2, QStringList() << "product" << "g1" << "prototype"); + const int g1P0 = pf.propertyValue(g1Props, "gmod1", "p0").toInt(); + QCOMPARE(g1P0, 3); + const int g1DepProp = pf.propertyValue(g1Props, "gmod1", "depProp").toInt(); + QEXPECT_FAIL(0, "QBS-1005", Continue); + QCOMPARE(g1DepProp, 1); + const auto &g1DummyCFlags = pf.propertyValue(g1Props, "dummy", "cFlags") + .toStringList(); + QEXPECT_FAIL(0, "QBS-1005", Continue); + QCOMPARE(g1DummyCFlags, QStringList("X")); + + const QVariantMap g2Props = g2->properties->value(); + const auto &g2ListProp1 = pf.propertyValue(g2Props, "gmod1", "listProp1") + .toStringList(); + QCOMPARE(g2ListProp1, QStringList() << "prototype" << "g2"); + const auto &g2ListProp2 = pf.propertyValue(g2Props, "gmod1", "listProp2") + .toStringList(); + QEXPECT_FAIL(0, "QBS-1005", Continue); + QCOMPARE(g2ListProp2, QStringList() << "product" << "g2" << "prototype"); + const int g2P0 = pf.propertyValue(g2Props, "gmod1", "p0").toInt(); + QCOMPARE(g2P0, 6); + const int g2DepProp = pf.propertyValue(g2Props, "gmod1", "depProp").toInt(); QEXPECT_FAIL(0, "QBS-1005", Continue); - QCOMPARE(valueStrings, QStringList("X")); + QCOMPARE(g2DepProp, 2); } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); diff --git a/src/lib/corelib/tools/msvcinfo.cpp b/src/lib/corelib/tools/msvcinfo.cpp index 258699dfb..ce3a540a4 100644 --- a/src/lib/corelib/tools/msvcinfo.cpp +++ b/src/lib/corelib/tools/msvcinfo.cpp @@ -160,6 +160,9 @@ static QVariantMap getMsvcDefines(const QString &hostCompilerFilePath, } DummyFile actualDummyFile(actualDummyFilePath); const QString qbsClFrontend = nativeDummyFilePath + QStringLiteral(".exe"); + const QString qbsClFrontendObj = nativeDummyFilePath + QStringLiteral(".obj"); + DummyFile actualQbsClFrontend(qbsClFrontend); + DummyFile actualQbsClFrontendObj(qbsClFrontendObj); // The host compiler is the x86 compiler, which will execute on any edition of Windows // for which host compilers have been released so far (x86, x86_64, ia64) @@ -171,6 +174,7 @@ static QVariantMap getMsvcDefines(const QString &hostCompilerFilePath, runProcess(hostCompilerFilePath, QStringList() << QStringLiteral("/nologo") << QStringLiteral("/TC") + << (QStringLiteral("/Fo") + qbsClFrontendObj) << nativeDummyFilePath << QStringLiteral("/link") << (QStringLiteral("/out:") + qbsClFrontend), msvc2.environments[QString()]); diff --git a/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs new file mode 100644 index 000000000..223da0b3c --- /dev/null +++ b/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs @@ -0,0 +1,6 @@ +import qbs + +Module { + property stringList theProperty: [] + //property stringList otherProperty: theProperty.concat([]) +} diff --git a/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs b/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs new file mode 100644 index 000000000..e1f8d8ef6 --- /dev/null +++ b/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs @@ -0,0 +1,22 @@ +import qbs + +Product { + type: "custom" + Depends { name: "mymodule" } + Rule { + multiplex: true + Artifact { + filePath: "dummy.custom" + fileTags: ["custom"] + } + prepare: { + var theProperty = product.moduleProperty("mymodule", "theProperty"); + if (!theProperty) + throw "Oh no!"; + var dummy = new JavaScriptCommand(); + dummy.silent = true; + dummy.sourceCode = function() {}; + return [dummy]; + } + } +} diff --git a/tests/auto/blackbox/testdata/bundle-structure/bundle-structure.qbs b/tests/auto/blackbox/testdata/bundle-structure/bundle-structure.qbs index 19586522c..5b372589a 100644 --- a/tests/auto/blackbox/testdata/bundle-structure/bundle-structure.qbs +++ b/tests/auto/blackbox/testdata/bundle-structure/bundle-structure.qbs @@ -3,7 +3,7 @@ import qbs Project { property stringList bundleFileTags: [ "aggregate_infoplist", "pkginfo", "hpp", - "icns", "resourcerules", "xcent", + "icns", "xcent", "compiled_ibdoc", "compiled_assetcatalog", "bundle.symlink.headers", "bundle.symlink.private-headers", "bundle.symlink.resources", "bundle.symlink.executable", diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 8572ecc36..4f41cd6ea 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -450,7 +450,6 @@ void TestBlackbox::bundleStructure() QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app/Info.plist").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app/PkgInfo").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app/resource.txt").isRegularFile()); - QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app/ResourceRules.plist").isRegularFile()); } if (productName == "B") { @@ -465,7 +464,6 @@ void TestBlackbox::bundleStructure() QVERIFY(QFileInfo2(defaultInstallRoot + "/B.framework/PrivateHeaders").isRegularDir()); QVERIFY(QFileInfo2(defaultInstallRoot + "/B.framework/PrivateHeaders/dummy_p.h").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/B.framework/resource.txt").isRegularFile()); - QVERIFY(QFileInfo2(defaultInstallRoot + "/B.framework/ResourceRules.plist").isRegularFile()); } if (productName == "C") { @@ -480,7 +478,6 @@ void TestBlackbox::bundleStructure() QVERIFY(QFileInfo2(defaultInstallRoot + "/C.framework/PrivateHeaders").isRegularDir()); QVERIFY(QFileInfo2(defaultInstallRoot + "/C.framework/PrivateHeaders/dummy_p.h").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/C.framework/resource.txt").isRegularFile()); - QVERIFY(QFileInfo2(defaultInstallRoot + "/C.framework/ResourceRules.plist").isRegularFile()); } if (productName == "D") { @@ -493,7 +490,6 @@ void TestBlackbox::bundleStructure() QVERIFY(QFileInfo2(defaultInstallRoot + "/D.bundle/PrivateHeaders").isRegularDir()); QVERIFY(QFileInfo2(defaultInstallRoot + "/D.bundle/PrivateHeaders/dummy_p.h").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/D.bundle/resource.txt").isRegularFile()); - QVERIFY(QFileInfo2(defaultInstallRoot + "/D.bundle/ResourceRules.plist").isRegularFile()); } if (productName == "E") { @@ -506,7 +502,6 @@ void TestBlackbox::bundleStructure() QVERIFY(QFileInfo2(defaultInstallRoot + "/E.appex/PrivateHeaders").isRegularDir()); QVERIFY(QFileInfo2(defaultInstallRoot + "/E.appex/PrivateHeaders/dummy_p.h").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/E.appex/resource.txt").isRegularFile()); - QVERIFY(QFileInfo2(defaultInstallRoot + "/E.appex/ResourceRules.plist").isRegularFile()); } if (productName == "F") { @@ -519,7 +514,6 @@ void TestBlackbox::bundleStructure() QVERIFY(QFileInfo2(defaultInstallRoot + "/F.xpc/PrivateHeaders").isRegularDir()); QVERIFY(QFileInfo2(defaultInstallRoot + "/F.xpc/PrivateHeaders/dummy_p.h").isRegularFile()); QVERIFY(QFileInfo2(defaultInstallRoot + "/F.xpc/resource.txt").isRegularFile()); - QVERIFY(QFileInfo2(defaultInstallRoot + "/F.xpc/ResourceRules.plist").isRegularFile()); } if (productName == "G") { @@ -2181,6 +2175,22 @@ void TestBlackbox::qobjectInObjectiveCpp() QCOMPARE(runQbs(), 0); } +void TestBlackbox::qtBug51237() +{ + const QString profileName = "profile-qtBug51237"; + const QString propertyName = "mymodule.theProperty"; + { + Settings settings((QString())); + Profile profile(profileName, &settings); + profile.setValue(propertyName, QStringList()); + } + QDir::setCurrent(testDataDir + "/QTBUG-51237"); + QbsRunParameters params; + params.arguments << "profile:" + profileName; + params.useProfile = false; + QCOMPARE(runQbs(params), 0); +} + void TestBlackbox::dynamicMultiplexRule() { const QString testDir = testDataDir + "/dynamicMultiplexRule"; diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 69ffc5341..182221b78 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -145,6 +145,7 @@ private slots: void qbsVersion(); void qmlDebugging(); void qobjectInObjectiveCpp(); + void qtBug51237(); void radAfterIncompleteBuild(); void radAfterIncompleteBuild_data(); void recursiveRenaming(); |