diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-06-15 17:44:58 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-06-20 08:26:08 +0000 |
commit | 4764e3eb961013e169c155648f26b0e63eb2b574 (patch) | |
tree | a1b761e77188b98eaf8fdba251f18fcc75822696 | |
parent | 5a8e20fe51e95ac5ab97c4c691a3c194383cff55 (diff) | |
download | qbs-4764e3eb961013e169c155648f26b0e63eb2b574.tar.gz |
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>
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(); |