diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-08-03 10:48:10 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-08-03 12:43:00 +0200 |
commit | 51b63d5e805814c1ec88e4a874cd7eabd58eb20a (patch) | |
tree | 600a94fe14b9741dc58492df5300265fe284118c | |
parent | ffbc37129d6a2623ddc731520baba0f4d3b6f3b1 (diff) | |
parent | 66131652f178cd1605b8a2c0ba7023392e13ad5a (diff) |
Merge 1.12 into master
Change-Id: I0ce6c28f9117f945c9fec0654bd06daf3d13ace0
20 files changed, 221 insertions, 42 deletions
diff --git a/changelogs/changes-1.12.1.md b/changelogs/changes-1.12.1.md new file mode 100644 index 000000000..ff14d8169 --- /dev/null +++ b/changelogs/changes-1.12.1.md @@ -0,0 +1,6 @@ +# Important bugfixes +* Lifted the restriction that the -march option cannot appear in cpp.*Flags (QBS-1018). +* All required header files get installed now (QBS-1370). +* Fixed rpaths not ending up on the command line under certain circumstances (QBS-1372). +* Fixed possible crash when scanning qrc files (QBS-1375). +* Fixed spurious re-building of .pc and .qbs module files. diff --git a/doc/man/qbs.1 b/doc/man/qbs.1 index 32c112886..b3d0a6022 100644 --- a/doc/man/qbs.1 +++ b/doc/man/qbs.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6. -.TH QBS "1" "June 2018" "qbs 1.12.0" "User Commands" +.TH QBS "1" "July 2018" "qbs 1.12.1" "User Commands" .SH NAME qbs \- the Qbs build tool .SH SYNOPSIS .B qbs [\fI\,command\/\fR] [\fI\,command parameters\/\fR] .SH DESCRIPTION -Qbs 1.12.0, a cross\-platform build tool. +Qbs 1.12.1, a cross\-platform build tool. .SS "Built-in commands:" .TP build diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs index 871eeeefa..423d964d5 100644 --- a/share/qbs/modules/cpp/GenericGCC.qbs +++ b/share/qbs/modules/cpp/GenericGCC.qbs @@ -342,8 +342,7 @@ CppModule { var validateFlagsFunction = function (value) { if (value) { for (var i = 0; i < value.length; ++i) { - if (["-target", "-triple", "-arch"].contains(value[i]) - || value[i].startsWith("-march=")) + if (["-target", "-triple", "-arch"].contains(value[i])) return false; } } @@ -351,7 +350,7 @@ CppModule { } var validator = new ModUtils.PropertyValidator("cpp"); - var msg = "'-target', '-triple', '-arch' and '-march' cannot appear in flags; set qbs.architecture instead"; + var msg = "'-target', '-triple' and '-arch' cannot appear in flags; set qbs.architecture instead"; validator.addCustomValidator("assemblerFlags", assemblerFlags, validateFlagsFunction, msg); validator.addCustomValidator("cppFlags", cppFlags, validateFlagsFunction, msg); validator.addCustomValidator("cFlags", cFlags, validateFlagsFunction, msg); diff --git a/share/qbs/modules/cpp/LinuxGCC.qbs b/share/qbs/modules/cpp/LinuxGCC.qbs index e93a5d7e7..14fb0a7e9 100644 --- a/share/qbs/modules/cpp/LinuxGCC.qbs +++ b/share/qbs/modules/cpp/LinuxGCC.qbs @@ -53,8 +53,12 @@ UnixGCC { var line; do { line = ldconfig.readLine(); - if (line.charAt(0) === '/') - paths.push(line.slice(0, line.length - 1)); + if (line.charAt(0) === '/') { + var colonIndex = line.indexOf(':'); + if (colonIndex == -1) + continue; + paths.push(line.slice(0, colonIndex)); + } } while (line && line.length > 0) found = true; systemRunPaths = paths; diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index c3ba53ff2..6e8622b93 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -345,8 +345,8 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat } function isNotSystemRunPath(p) { - return !systemRunPaths.contains(p) - && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)); + return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p) + && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p))); }; for (i in rpaths) { if (isNotSystemRunPath(rpaths[i])) diff --git a/src/lib/corelib/buildgraph/artifactsscriptvalue.cpp b/src/lib/corelib/buildgraph/artifactsscriptvalue.cpp index 0fcede324..c32e95b2a 100644 --- a/src/lib/corelib/buildgraph/artifactsscriptvalue.cpp +++ b/src/lib/corelib/buildgraph/artifactsscriptvalue.cpp @@ -45,6 +45,7 @@ #include <language/language.h> #include <language/scriptengine.h> +#include <QtScript/qscriptclass.h> #include <QtScript/qscriptcontext.h> namespace qbs { @@ -52,7 +53,44 @@ namespace Internal { enum BuildGraphScriptValueCommonPropertyKeys : quint32 { CachedValueKey, - FileTagKey + FileTagKey, + ProductPtrKey, +}; + +class ArtifactsScriptClass : public QScriptClass +{ +public: + ArtifactsScriptClass(QScriptEngine *engine) : QScriptClass(engine) { } + +private: + QueryFlags queryProperty(const QScriptValue &object, const QScriptString &name, + QueryFlags flags, uint *id) override + { + getProduct(object); + qbsEngine()->setNonExistingArtifactSetRequested(m_product, name.toString()); + return QScriptClass::queryProperty(object, name, flags, id); + } + + QScriptClassPropertyIterator *newIterator(const QScriptValue &object) override + { + getProduct(object); + qbsEngine()->setArtifactsEnumerated(m_product); + return QScriptClass::newIterator(object); + } + + void getProduct(const QScriptValue &object) + { + if (m_lastObjectId != object.objectId()) { + m_lastObjectId = object.objectId(); + m_product = reinterpret_cast<const ResolvedProduct *>( + object.data().property(ProductPtrKey).toVariant().value<quintptr>()); + } + } + + ScriptEngine *qbsEngine() const { return static_cast<ScriptEngine *>(engine()); } + + qint64 m_lastObjectId = 0; + const ResolvedProduct *m_product = nullptr; }; static bool isRelevantArtifact(const ResolvedProduct *, const Artifact *artifact) @@ -74,6 +112,27 @@ static ArtifactSetByFileTag artifactsMap(const ResolvedModule *module) return artifactsMap(module->product); } +static QScriptValue createArtifactsObject(const ResolvedProduct *product, ScriptEngine *engine) +{ + QScriptClass *scriptClass = engine->artifactsScriptClass(); + if (!scriptClass) { + scriptClass = new ArtifactsScriptClass(engine); + engine->setArtifactsScriptClass(scriptClass); + } + QScriptValue artifactsObj = engine->newObject(scriptClass); + QScriptValue data = engine->newObject(); + QVariant v; + v.setValue<quintptr>(reinterpret_cast<quintptr>(product)); + data.setProperty(ProductPtrKey, engine->newVariant(v)); + artifactsObj.setData(data); + return artifactsObj; +} + +static QScriptValue createArtifactsObject(const ResolvedModule *, ScriptEngine *engine) +{ + return engine->newObject(); +} + static bool checkAndSetArtifactsMapUpToDateFlag(const ResolvedProduct *p) { return p->buildData->checkAndSetJsArtifactsMapUpToDateFlag(); @@ -119,7 +178,7 @@ template<class ProductOrModule> static QScriptValue js_artifacts( QScriptValue artifactsObj = ctx->callee().property(CachedValueKey); if (artifactsObj.isObject() && checkAndSetArtifactsMapUpToDateFlag(productOrModule)) return artifactsObj; - artifactsObj = engine->newObject(); + artifactsObj = createArtifactsObject(productOrModule, engine); ctx->callee().setProperty(CachedValueKey, artifactsObj); const auto &map = artifactsMap(productOrModule); for (auto it = map.cbegin(); it != map.cend(); ++it) { diff --git a/src/lib/corelib/buildgraph/requestedartifacts.cpp b/src/lib/corelib/buildgraph/requestedartifacts.cpp index 0028c21bb..200f226ce 100644 --- a/src/lib/corelib/buildgraph/requestedartifacts.cpp +++ b/src/lib/corelib/buildgraph/requestedartifacts.cpp @@ -95,6 +95,20 @@ void RequestedArtifacts::setArtifactsForTag(const ResolvedProduct *product, filePaths.insert(a->filePath()); } +void RequestedArtifacts::setNonExistingTagRequested(const ResolvedProduct *product, + const QString &tag) +{ + RequestedArtifactsPerProduct &ra = m_requestedArtifactsPerProduct[product->uniqueName()]; + QBS_ASSERT(!ra.allTags.empty(), ;); + Set<QString> &filePaths = ra.requestedTags[tag]; + QBS_CHECK(filePaths.empty()); +} + +void RequestedArtifacts::setArtifactsEnumerated(const ResolvedProduct *product) +{ + m_requestedArtifactsPerProduct[product->uniqueName()].artifactsEnumerated = true; +} + void RequestedArtifacts::unite(const RequestedArtifacts &other) { for (auto it = other.m_requestedArtifactsPerProduct.begin(); @@ -129,24 +143,33 @@ bool RequestedArtifacts::RequestedArtifactsPerProduct::isUpToDate( << "is now disabled"; return false; } + + if (!artifactsEnumerated && requestedTags.empty()) + return true; + const ArtifactSetByFileTag currentArtifacts = product->buildData->artifactsByFileTag(); - Set<QString> currentTags; - for (auto it = currentArtifacts.begin(); it != currentArtifacts.end(); ++it) { - const QString tagString = it.key().toString(); - currentTags.insert(tagString); - const auto reqTagsIt = requestedTags.find(tagString); - if (reqTagsIt == requestedTags.end()) - continue; + for (auto reqIt = requestedTags.cbegin(); reqIt != requestedTags.cend(); ++reqIt) { + const FileTag tag = FileTag(reqIt->first.toUtf8()); + const auto currentIt = currentArtifacts.constFind(tag); Set<QString> currentFilePathsForTag; - for (const Artifact * const a : it.value()) - currentFilePathsForTag.insert(a->filePath()); - if (currentFilePathsForTag != reqTagsIt->second) { + if (currentIt != currentArtifacts.constEnd()) { + for (const Artifact * const a : currentIt.value()) + currentFilePathsForTag.insert(a->filePath()); + } + if (currentFilePathsForTag != reqIt->second) { qCDebug(lcBuildGraph) << "artifacts map not up to date: requested artifact set for " - "file tag" << tagString << "in product" + "file tag" << reqIt->first << "in product" << product->uniqueName() << "differs from the current one"; return false; } } + + if (!artifactsEnumerated) + return true; + + Set<QString> currentTags; + for (auto it = currentArtifacts.begin(); it != currentArtifacts.end(); ++it) + currentTags.insert(it.key().toString()); if (currentTags != allTags) { qCDebug(lcBuildGraph) << "artifacts map not up to date: overall file tags differ for " << "product" << product->uniqueName(); @@ -169,10 +192,8 @@ void RequestedArtifacts::RequestedArtifactsPerProduct::unite( void RequestedArtifacts::RequestedArtifactsPerProduct::doSanityChecks() const { - Set<QString> requestedTagsSet; for (auto it = requestedTags.begin(); it != requestedTags.end(); ++it) - requestedTagsSet.insert(it->first); - QBS_CHECK(allTags.contains(requestedTagsSet)); + QBS_CHECK(allTags.contains(it->first) || it->second.empty()); } void RequestedArtifacts::RequestedArtifactsPerProduct::load(PersistentPool &pool) diff --git a/src/lib/corelib/buildgraph/requestedartifacts.h b/src/lib/corelib/buildgraph/requestedartifacts.h index 4d4a01297..82c393803 100644 --- a/src/lib/corelib/buildgraph/requestedartifacts.h +++ b/src/lib/corelib/buildgraph/requestedartifacts.h @@ -61,6 +61,8 @@ public: void clear() { m_requestedArtifactsPerProduct.clear(); } void setAllArtifactTags(const ResolvedProduct *product); void setArtifactsForTag(const ResolvedProduct *product, const FileTag &tag); + void setNonExistingTagRequested(const ResolvedProduct *product, const QString &tag); + void setArtifactsEnumerated(const ResolvedProduct *product); void unite(const RequestedArtifacts &other); void doSanityChecks() const; @@ -78,6 +80,7 @@ private: { Set<QString> allTags; std::unordered_map<QString, Set<QString>> requestedTags; + bool artifactsEnumerated = false; bool isUpToDate(const ResolvedProduct *product) const; @@ -87,7 +90,7 @@ private: template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool) { - pool.serializationOp<opType>(allTags, requestedTags); + pool.serializationOp<opType>(allTags, requestedTags, artifactsEnumerated); } void load(PersistentPool &pool); diff --git a/src/lib/corelib/buildgraph/transformer.cpp b/src/lib/corelib/buildgraph/transformer.cpp index baf104df5..df371e1fe 100644 --- a/src/lib/corelib/buildgraph/transformer.cpp +++ b/src/lib/corelib/buildgraph/transformer.cpp @@ -49,6 +49,7 @@ #include <tools/scripttools.h> #include <tools/qbsassert.h> #include <tools/stringconstants.h> +#include <tools/stlutils.h> #include <QtCore/qdir.h> @@ -117,7 +118,7 @@ QScriptValue Transformer::translateFileConfig(ScriptEngine *scriptEngine, const setArtifactProperty(obj, StringConstants::completeBaseNameProperty(), js_completeBaseName, artifact); setArtifactProperty(obj, QStringLiteral("baseDir"), js_baseDir, artifact); - const QStringList fileTags = artifact->fileTags().toStringList(); + const QStringList fileTags = sorted(artifact->fileTags().toStringList()); scriptEngine->setObservedProperty(obj, StringConstants::fileTagsProperty(), scriptEngine->toScriptValue(fileTags)); scriptEngine->observer()->addArtifactId(obj.objectId()); diff --git a/src/lib/corelib/buildgraph/transformerchangetracking.cpp b/src/lib/corelib/buildgraph/transformerchangetracking.cpp index 41f4c8219..aa13f967f 100644 --- a/src/lib/corelib/buildgraph/transformerchangetracking.cpp +++ b/src/lib/corelib/buildgraph/transformerchangetracking.cpp @@ -276,7 +276,7 @@ bool TrafoChangeTracker::prepareScriptNeedsRerun() const if (!artifact) return true; if (property.kind == Property::PropertyInArtifact) { - if (artifact->fileTags().toStringList() != property.value.toStringList()) + if (sorted(artifact->fileTags().toStringList()) != property.value.toStringList()) return true; continue; } @@ -312,7 +312,7 @@ bool TrafoChangeTracker::commandsNeedRerun() const if (!artifact) return true; if (property.kind == Property::PropertyInArtifact) { - if (artifact->fileTags().toStringList() != property.value.toStringList()) + if (sorted(artifact->fileTags().toStringList()) != property.value.toStringList()) return true; continue; } diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs index 08733b624..93509763b 100644 --- a/src/lib/corelib/corelib.qbs +++ b/src/lib/corelib/corelib.qbs @@ -440,7 +440,6 @@ QbsLibrary { "settingscreator.h", "settingsmodel.cpp", "settingsrepresentation.cpp", - "settingsrepresentation.h", "setupprojectparameters.cpp", "shellutils.cpp", "shellutils.h", @@ -475,6 +474,7 @@ QbsLibrary { "qbs_export.h", "settings.h", "settingsmodel.h", + "settingsrepresentation.h", "setupprojectparameters.h", "toolchains.h", "version.h", diff --git a/src/lib/corelib/jsextensions/moduleproperties.cpp b/src/lib/corelib/jsextensions/moduleproperties.cpp index d80a4bc5f..7607b3dc2 100644 --- a/src/lib/corelib/jsextensions/moduleproperties.cpp +++ b/src/lib/corelib/jsextensions/moduleproperties.cpp @@ -51,6 +51,7 @@ #include <tools/error.h> #include <tools/qbsassert.h> #include <tools/qttools.h> +#include <tools/stlutils.h> #include <tools/stringconstants.h> #include <QtScript/qscriptclass.h> @@ -249,7 +250,7 @@ void ModuleProperties::init(QScriptValue artifactObject, const Artifact *artifac {StringConstants::nameProperty(), product->name}, {StringConstants::sourceDirectoryProperty(), product->sourceDirectory}, {StringConstants::targetNameProperty(), product->targetName}, - {StringConstants::typeProperty(), product->fileTags.toStringList()} + {StringConstants::typeProperty(), sorted(product->fileTags.toStringList())} }; QScriptEngine * const engine = artifactObject.engine(); artifactObject.setProperty(StringConstants::productVar(), diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index 6449655fb..ac6d756b8 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -3796,11 +3796,33 @@ Item *ModuleLoader::createNonPresentModule(const QString &name, const QString &r void ModuleLoader::handleProductError(const ErrorInfo &error, ModuleLoader::ProductContext *productContext) { - if (!productContext->info.delayedError.hasError()) { + const bool alreadyHadError = productContext->info.delayedError.hasError(); + if (!alreadyHadError) { productContext->info.delayedError.append(Tr::tr("Error while handling product '%1':") .arg(productContext->name), productContext->item->location()); } + if (error.isInternalError()) { + if (alreadyHadError) { + qCDebug(lcModuleLoader()) << "ignoring subsequent internal error" << error.toString() + << "in product" << productContext->name; + return; + } + const auto &deps = productContext->productModuleDependencies; + for (auto it = deps.cbegin(); it != deps.cend(); ++it) { + const auto rangeForName = m_productsByName.equal_range(it->first); + for (auto rangeIt = rangeForName.first; rangeIt != rangeForName.second; ++rangeIt) { + const ProductContext * const dep = rangeIt->second; + if (dep->info.delayedError.hasError()) { + qCDebug(lcModuleLoader()) << "ignoring internal error" << error.toString() + << "in product" << productContext->name + << "assumed to be caused by erroneous dependency" + << dep->name; + return; + } + } + } + } for (const ErrorItem &ei : error.items()) productContext->info.delayedError.append(ei.description(), ei.codeLocation()); productContext->project->result->productInfos.insert(productContext->item, diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index b226ce91a..ec29e00c0 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -573,7 +573,7 @@ void ProjectResolver::gatherProductTypes(ResolvedProduct *product, Item *item) } } item->setProperty(StringConstants::typeProperty(), - VariantValue::create(product->fileTags.toStringList())); + VariantValue::create(sorted(product->fileTags.toStringList()))); } SourceArtifactPtr ProjectResolver::createSourceArtifact(const ResolvedProductPtr &rproduct, diff --git a/src/lib/corelib/language/scriptengine.h b/src/lib/corelib/language/scriptengine.h index 078890512..e27df7701 100644 --- a/src/lib/corelib/language/scriptengine.h +++ b/src/lib/corelib/language/scriptengine.h @@ -128,6 +128,14 @@ public: { m_requestedArtifacts.setArtifactsForTag(product, tag); } + void setNonExistingArtifactSetRequested(const ResolvedProduct *product, const QString &tag) + { + m_requestedArtifacts.setNonExistingTagRequested(product, tag); + } + void setArtifactsEnumerated(const ResolvedProduct *product) + { + m_requestedArtifacts.setArtifactsEnumerated(product); + } void addPropertyRequestedFromArtifact(const Artifact *artifact, const Property &property); void addRequestedExport(const ResolvedProduct *product) { m_requestedExports.insert(product); } void clearRequestedProperties() { @@ -242,6 +250,12 @@ public: m_productPropertyScriptClass = productPropertyScriptClass; } + QScriptClass *artifactsScriptClass() const { return m_artifactsScriptClass; } + void setArtifactsScriptClass(QScriptClass *artifactsScriptClass) + { + m_artifactsScriptClass = artifactsScriptClass; + } + void addResourceAcquiringScriptObject(ResourceAcquiringScriptObject *obj); void releaseResourcesOfScriptObjects(); @@ -302,6 +316,7 @@ private: ScriptImporter *m_scriptImporter; QScriptClass *m_modulePropertyScriptClass; QScriptClass *m_productPropertyScriptClass = nullptr; + QScriptClass *m_artifactsScriptClass = nullptr; QHash<JsImport, QScriptValue> m_jsImportCache; std::unordered_map<QString, QScriptValue> m_jsFileCache; bool m_propertyCacheEnabled; diff --git a/src/lib/corelib/tools/tools.pri b/src/lib/corelib/tools/tools.pri index 9db30664f..bb3a55f12 100644 --- a/src/lib/corelib/tools/tools.pri +++ b/src/lib/corelib/tools/tools.pri @@ -131,6 +131,7 @@ osx { $$PWD/qbs_export.h \ $$PWD/settings.h \ $$PWD/settingsmodel.h \ + $$PWD/settingsrepresentation.h \ $$PWD/setupprojectparameters.h \ $$PWD/toolchains.h \ $$PWD/version.h diff --git a/src/plugins/scanner/qt/qtscanner.cpp b/src/plugins/scanner/qt/qtscanner.cpp index 5a790efc1..51faadab3 100644 --- a/src/plugins/scanner/qt/qtscanner.cpp +++ b/src/plugins/scanner/qt/qtscanner.cpp @@ -119,7 +119,8 @@ static void *openScannerQrc(const unsigned short *filePath, const char *fileTags int r = fstat(opaque->fd, &s); if (r != 0) return nullptr; - opaque->mapl = s.st_size; + const int fileSize = static_cast<int>(s.st_size); + opaque->mapl = fileSize; void *map = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, opaque->fd, 0); if (map == nullptr) @@ -129,13 +130,14 @@ static void *openScannerQrc(const unsigned short *filePath, const char *fileTags if (!opaque->file->open(QFile::ReadOnly)) return nullptr; - uchar *map = opaque->file->map(0, opaque->file->size()); + const int fileSize = opaque->file->size(); + uchar *map = opaque->file->map(0, fileSize); if (!map) return nullptr; #endif opaque->map = reinterpret_cast<char *>(map); - opaque->xml = new QXmlStreamReader(opaque->map); + opaque->xml = new QXmlStreamReader(QByteArray::fromRawData(opaque->map, fileSize)); return static_cast<void *>(opaque.release()); } diff --git a/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs b/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs index 3237e90dc..571feced8 100644 --- a/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs +++ b/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs @@ -6,6 +6,11 @@ Project { Depends { name: 'cpp' } + Properties { + condition: qbs.toolchain.contains("gcc") + cpp.cxxFlags: "-march=native" + } + Group { cpp.defines: ['WORLD="BANANA"'] files : [ "main.cpp" ] diff --git a/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs b/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs index 2d9c95e95..879138536 100644 --- a/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs +++ b/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs @@ -55,4 +55,31 @@ Project { } } } + + Product { + name: "p" + type: "p_type" + Rule { + multiplex: true + Artifact { filePath: "dummy1"; fileTags: "d_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var blubb = product.artifacts.qbs; + }; + return cmd; + } + } + Rule { + inputs: "d_type" + Artifact { filePath: "dummy2"; fileTags: "p_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { }; + return cmd; + } + } + } } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 367be97ea..490632b6e 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -392,12 +392,14 @@ void TestBlackbox::artifactsMapChangeTracking() QVERIFY2(m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("linking"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QStringList{"-p", "meta"}), 0); + QCOMPARE(runQbs(QStringList{"-p", "meta,p"}), 0); QVERIFY2(m_qbsStdout.contains("printing artifacts"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("test.txt"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("main.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("TheBinary"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("dummy1"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("dummy2"), m_qbsStdout.constData()); // Change name of target binary. Command must be re-run, because the file name of an // artifact changed. @@ -409,13 +411,15 @@ void TestBlackbox::artifactsMapChangeTracking() QVERIFY2(!m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("linking"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QStringList{"-p", "meta"}), 0); + QCOMPARE(runQbs(QStringList{"-p", "meta,p"}), 0); QVERIFY2(m_qbsStdout.contains("printing artifacts"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("test.txt"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("main.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("TheNewBinary"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("TheBinary"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy1"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy2"), m_qbsStdout.constData()); // Add file tag to generated artifact. Command must be re-run, because it enumerates the keys // of the artifacts map. @@ -425,12 +429,14 @@ void TestBlackbox::artifactsMapChangeTracking() QVERIFY2(m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("linking"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QStringList{"-p", "meta"}), 0); + QCOMPARE(runQbs(QStringList{"-p", "meta,p"}), 0); QVERIFY2(m_qbsStdout.contains("printing artifacts"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("test.txt"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("main.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("TheNewBinary"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy1"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy2"), m_qbsStdout.constData()); // Add redundant file tag to generated artifact. Command must not be re-run, because // the artifacts map has not changed. @@ -442,8 +448,10 @@ void TestBlackbox::artifactsMapChangeTracking() QVERIFY2(!m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("linking"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QStringList{"-p", "meta"}), 0); + QCOMPARE(runQbs(QStringList{"-p", "meta,p"}), 0); QVERIFY2(!m_qbsStdout.contains("printing artifacts"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy1"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy2"), m_qbsStdout.constData()); // Rebuild the app. Command must not be re-run, because the artifacts map has not changed. WAIT_FOR_NEW_TIMESTAMP(); @@ -452,8 +460,10 @@ void TestBlackbox::artifactsMapChangeTracking() QVERIFY2(!m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("linking"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QStringList{"-p", "meta"}), 0); + QCOMPARE(runQbs(QStringList{"-p", "meta,p"}), 0); QVERIFY2(!m_qbsStdout.contains("printing artifacts"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy1"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy2"), m_qbsStdout.constData()); // Add source file to app. Command must be re-run, because the artifacts map has changed. WAIT_FOR_NEW_TIMESTAMP(); @@ -463,12 +473,14 @@ void TestBlackbox::artifactsMapChangeTracking() QVERIFY2(!m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("linking"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QStringList{"-p", "meta"}), 0); + QCOMPARE(runQbs(QStringList{"-p", "meta,p"}), 0); QVERIFY2(m_qbsStdout.contains("printing artifacts"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("test.txt"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("main.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("TheNewBinary"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy1"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("dummy2"), m_qbsStdout.constData()); } void TestBlackbox::artifactsMapInvalidation() @@ -6381,6 +6393,7 @@ void TestBlackbox::groupsInModules() WAIT_FOR_NEW_TIMESTAMP(); touch("modules/helper/diamondc.c"); + waitForFileUnlock(); QCOMPARE(runQbs(params), 0); QVERIFY(m_qbsStdout.contains("compiling diamondc.c")); QVERIFY(m_qbsStdout.contains("compile rock.coal => rock.diamond")); |