aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2018-06-15 17:44:58 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2018-06-20 08:26:08 +0000
commit4764e3eb961013e169c155648f26b0e63eb2b574 (patch)
treea1b761e77188b98eaf8fdba251f18fcc75822696
parent5a8e20fe51e95ac5ab97c4c691a3c194383cff55 (diff)
Don't link to multiplexed libraries when depending on the aggregate
... library, this can lead to warnings or linker errors. Most easily seen on macOS when multiplexing across multiple architectures, and an app ends up linking against multiple multiplexed variants of a dependent product library. Change-Id: I4ea4b419099a1010f7b8c32ee11079da93f1d236 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--share/qbs/modules/cpp/gcc.js6
-rw-r--r--tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs35
-rw-r--r--tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/app.c8
-rw-r--r--tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/lib.c12
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.cpp14
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.h1
6 files changed, 76 insertions, 0 deletions
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 5ac936eb0..896ae48fa 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -157,6 +157,12 @@ function collectLibraryDependencies(product, isDarwin) {
var nextIsBelowIndirectDynamicLib = isBelowIndirectDynamicLib || isDynamicLibrary;
dep.dependencies.forEach(function(depdep) {
+ // If "dep" is an aggregate product, and "depdep" is one of the multiplexed variants
+ // of the same product, we don't want to depend on the multiplexed variants, because
+ // that could mean linking more than one time against the same library. Instead skip
+ // the multiplexed dependency, and depend only on the aggregate one.
+ if (depdep.name === dep.name)
+ return;
traverse(depdep, nextIsBelowIndirectDynamicLib);
});
if (isStaticLibrary) {
diff --git a/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs
new file mode 100644
index 000000000..e7c8867bd
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs
@@ -0,0 +1,35 @@
+import qbs
+
+Project {
+ minimumQbsVersion: "1.8"
+
+ StaticLibrary {
+ name: "multi_arch_lib"
+ files: ["lib.c"]
+
+ Depends { name: "cpp" }
+ Depends { name: "bundle" }
+ bundle.isBundle: false
+
+ // This will generate 2 multiplex configs and an aggregate.
+ qbs.architectures: ["x86", "x86_64"]
+ qbs.buildVariant: "debug"
+ }
+
+ CppApplication {
+ name: "just_app"
+ files: ["app.c"]
+
+ // This should link only against the aggregate static library, and not against
+ // the {debug, x86_64} variant, or worse - against both the single arch variant
+ // and the lipo-ed one.
+ Depends { name: "multi_arch_lib" }
+
+ Depends { name: "bundle" }
+ bundle.isBundle: false
+
+ qbs.architecture: "x86_64"
+ qbs.buildVariant: "debug"
+ multiplexByQbsProperties: []
+ }
+}
diff --git a/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/app.c b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/app.c
new file mode 100644
index 000000000..ae414324b
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/app.c
@@ -0,0 +1,8 @@
+extern int foo();
+
+int main(int argc, char *argv[]) {
+ (void) argc;
+ (void) argv;
+
+ return foo();
+}
diff --git a/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/lib.c b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/lib.c
new file mode 100644
index 000000000..9ef95547b
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/lib.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int foo()
+{
+#ifdef __i386__
+ printf("Hello from i386\n");
+#endif
+#ifdef __x86_64__
+ printf("Hello from x86_64\n");
+#endif
+ return 0;
+}
diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp
index 6fc526cd8..c08cc9759 100644
--- a/tests/auto/blackbox/tst_blackboxapple.cpp
+++ b/tests/auto/blackbox/tst_blackboxapple.cpp
@@ -145,6 +145,20 @@ void TestBlackboxApple::appleMultiConfig()
}
}
+void TestBlackboxApple::aggregateDependencyLinking()
+{
+ if (HostOsInfo::hostOsVersion() > qbs::Version(10, 13, 4))
+ QSKIP("32-bit arch build is no longer supported on macOS versions higher than 10.13.4.");
+
+ QDir::setCurrent(testDataDir + "/aggregateDependencyLinking");
+ QCOMPARE(runQbs(QStringList{"-p", "multi_arch_lib"}), 0);
+
+ QCOMPARE(runQbs(QStringList{"-p", "just_app", "--command-echo-mode", "command-line"}), 0);
+ int linkedInLibrariesCount =
+ QString::fromUtf8(m_qbsStdout).count(QStringLiteral("multi_arch_lib.a"));
+ QCOMPARE(linkedInLibrariesCount, 1);
+}
+
void TestBlackboxApple::assetCatalog()
{
QFETCH(bool, flatten);
diff --git a/tests/auto/blackbox/tst_blackboxapple.h b/tests/auto/blackbox/tst_blackboxapple.h
index 05e0d8acd..76711ddf5 100644
--- a/tests/auto/blackbox/tst_blackboxapple.h
+++ b/tests/auto/blackbox/tst_blackboxapple.h
@@ -47,6 +47,7 @@ public slots:
private slots:
void appleMultiConfig();
+ void aggregateDependencyLinking();
void assetCatalog();
void assetCatalog_data();
void assetCatalogsEmpty();