aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2017-11-08 11:05:44 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2017-11-09 09:05:43 +0000
commit9c1aa4ece11a8481772b340123a232b70d16858d (patch)
tree0d818c8c9763b92280cc3798cba086550886cdeb
parent8f8ea38dfd9c76092917fe63e7a132b00c456739 (diff)
Fix check for the "same file as different artifact" case in connect()
That can legally happen if the child artifact is a source file present in different products. Task-number: QBS-1241 Change-Id: Ideba1321072deee5c01b8915f32a747b45864793 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r--src/lib/corelib/buildgraph/buildgraph.cpp9
-rw-r--r--tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/header.h0
-rw-r--r--tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs59
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp22
-rw-r--r--tests/auto/blackbox/tst_blackbox.h1
5 files changed, 89 insertions, 2 deletions
diff --git a/src/lib/corelib/buildgraph/buildgraph.cpp b/src/lib/corelib/buildgraph/buildgraph.cpp
index 58192d3df..f053e2ee7 100644
--- a/src/lib/corelib/buildgraph/buildgraph.cpp
+++ b/src/lib/corelib/buildgraph/buildgraph.cpp
@@ -342,7 +342,11 @@ void connect(BuildGraphNode *p, BuildGraphNode *c)
qCDebug(lcBuildGraph) << "connect" << p->toString() << "->" << c->toString();
if (Artifact *ac = dynamic_cast<Artifact *>(c)) {
for (const Artifact *child : filterByType<Artifact>(p->children)) {
- if (child != ac && child->filePath() == ac->filePath()) {
+ if (child == ac)
+ return;
+ const bool filePathsMustBeDifferent = child->artifactType == Artifact::Generated
+ || child->product == ac->product || child->artifactType != ac->artifactType;
+ if (filePathsMustBeDifferent && child->filePath() == ac->filePath()) {
throw ErrorInfo(QString::fromLatin1("%1 already has a child artifact %2 as "
"different object.").arg(p->toString(),
ac->filePath()),
@@ -550,7 +554,8 @@ static void doSanityChecksForProduct(const ResolvedProductConstPtr &product,
continue;
}
- QBS_CHECK(!filePaths.contains(artifact->filePath()));
+ QBS_CHECK(artifact->artifactType == Artifact::SourceFile ||
+ !filePaths.contains(artifact->filePath()));
filePaths << artifact->filePath();
for (Artifact * const child : qAsConst(artifact->childrenAddedByScanner))
diff --git a/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/header.h b/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/header.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/header.h
diff --git a/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs b/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs
new file mode 100644
index 000000000..ef038a687
--- /dev/null
+++ b/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs
@@ -0,0 +1,59 @@
+import qbs
+import qbs.FileInfo
+import qbs.TextFile
+
+Project {
+ Product {
+ name: "dep1"
+ Group {
+ files: ["header.h"]
+ qbs.install: true
+ qbs.installDir: "include1"
+ }
+ }
+
+ Product {
+ name: "dep2"
+ Group {
+ files: ["header.h"]
+ qbs.install: true
+ qbs.installDir: "include2"
+ }
+ }
+
+ Product {
+ name: "p"
+ type: ["custom"]
+ Depends { name: "dep1" }
+ Depends { name: "dep2" }
+
+ Rule {
+ multiplex: true
+ inputsFromDependencies: ["installable"]
+ Artifact {
+ filePath: "output.txt"
+ fileTags: ["custom"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ var tf;
+ try {
+ tf = new TextFile(output.filePath, TextFile.WriteOnly);
+ var artifactList = inputs["installable"];
+ for (var i = 0; i < (artifactList ? artifactList.length : 0); ++i) {
+ var artifact = artifactList[i];
+ tf.writeLine(FileInfo.joinPaths(artifact.qbs.installDir,
+ artifact.fileName));
+ }
+ } finally {
+ if (tf)
+ tf.close();
+ }
+ }
+ return [cmd];
+ }
+ }
+ }
+}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 3981b99ad..b8cea5294 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -161,6 +161,28 @@ void TestBlackbox::sevenZip()
QVERIFY2(output.contains("archivable.qbs"), output.constData());
}
+void TestBlackbox::sourceArtifactInInputsFromDependencies()
+{
+ QDir::setCurrent(testDataDir + "/source-artifact-in-inputs-from-dependencies");
+ QCOMPARE(runQbs(), 0);
+ QFile outFile(relativeProductBuildDir("p") + "/output.txt");
+ QVERIFY2(outFile.exists(), qPrintable(outFile.fileName()));
+ QVERIFY2(outFile.open(QIODevice::ReadOnly), qPrintable(outFile.errorString()));
+ const QByteArrayList output = outFile.readAll().trimmed().split('\n');
+ QCOMPARE(output.size(), 2);
+ bool header1Found = false;
+ bool header2Found = false;
+ for (const QByteArray &line : output) {
+ const QByteArray &path = line.trimmed();
+ if (path == "include1/header.h")
+ header1Found = true;
+ else if (path == "include2/header.h")
+ header2Found = true;
+ }
+ QVERIFY(header1Found);
+ QVERIFY(header2Found);
+}
+
void TestBlackbox::staticLibWithoutSources()
{
QDir::setCurrent(testDataDir + "/static-lib-without-sources");
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index a75cf1aa4..6386491ac 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -193,6 +193,7 @@ private slots:
void renameDependency();
void separateDebugInfo();
void sevenZip();
+ void sourceArtifactInInputsFromDependencies();
void staticLibWithoutSources();
void suspiciousCalls();
void suspiciousCalls_data();