aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/qtprofilesetup
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2018-02-13 11:51:26 +0100
committerJoerg Bornemann <joerg.bornemann@qt.io>2018-02-28 12:34:18 +0000
commitfa16f0ee15b90df818ed8bbfe30fea7f7cc743b7 (patch)
tree14f5d5d507e172b0840fe2d7e4aa152ca0c1cbd4 /src/lib/qtprofilesetup
parent56f5af3644f8382ec4e45d5a8fa65d8c7ce26049 (diff)
setup-qt: Remove duplicated library entries in Qt modules
Do not specify {dynamic|static}Libraries that are already specified in dependencies of the current Qt module. This avoids having e.g. -lpthread multiple times in the linker's command line. Task-number: QBS-1273 Change-Id: I1328a19efc968cbd70f6cfcc882fb2c27f08e049 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/lib/qtprofilesetup')
-rw-r--r--src/lib/qtprofilesetup/qtmoduleinfo.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/lib/qtprofilesetup/qtmoduleinfo.cpp b/src/lib/qtprofilesetup/qtmoduleinfo.cpp
index 50a2f5924..95799632c 100644
--- a/src/lib/qtprofilesetup/qtmoduleinfo.cpp
+++ b/src/lib/qtprofilesetup/qtmoduleinfo.cpp
@@ -45,11 +45,17 @@
#include <tools/profile.h>
#include <tools/qttools.h>
#include <tools/set.h>
+#include <tools/stlutils.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qfile.h>
#include <QtCore/qhash.h>
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <unordered_map>
+
namespace qbs {
namespace Internal {
@@ -86,6 +92,105 @@ static void replaceQtLibNamesWithFilePath(QList<QtModuleInfo> *modules, const Qt
}
}
+class DuplicatedDependencyLibsRemover
+{
+public:
+ void apply(QList<QtModuleInfo> *modules)
+ {
+ setupReverseDependencies(modules);
+
+ // Traverse the debug variants of modules.
+ m_getLibraries = [](QtModuleInfo *module) {
+ return std::vector<QStringList *>{
+ &module->dynamicLibrariesDebug, &module->staticLibrariesDebug
+ };
+ };
+ m_getLibFilePath = [](QtModuleInfo *module) {
+ return module->libFilePathDebug;
+ };
+ const auto &rootModules = roots(modules);
+ for (QtModuleInfo *module : rootModules)
+ traverse(module, QStringList());
+
+ // Traverse the release variants of modules.
+ m_getLibraries = [](QtModuleInfo *module) {
+ return std::vector<QStringList *>{
+ &module->dynamicLibrariesRelease, &module->staticLibrariesRelease
+ };
+ };
+ m_getLibFilePath = [](QtModuleInfo *module) {
+ return module->libFilePathRelease;
+ };
+ for (QtModuleInfo *module : rootModules)
+ traverse(module, QStringList());
+ }
+
+private:
+ void setupReverseDependencies(QList<QtModuleInfo> *modules)
+ {
+ std::map<QString, QtModuleInfo *> moduleByName;
+ for (QtModuleInfo &module : *modules)
+ moduleByName[module.qbsName] = &module;
+ for (QtModuleInfo &module : *modules) {
+ for (const QString &dep : module.dependencies) {
+ QtModuleInfo *depmod = moduleByName[dep];
+ if (!depmod)
+ continue;
+ m_revDeps[depmod].push_back(&module);
+ }
+ }
+ }
+
+ std::vector<QtModuleInfo *> roots(QList<QtModuleInfo> *modules)
+ {
+ std::vector<QtModuleInfo *> result;
+ for (auto it = modules->begin(); it != modules->end(); ++it) {
+ QtModuleInfo &module = *it;
+ if (module.dependencies.empty())
+ result.push_back(&module);
+ }
+ return result;
+ }
+
+ void traverse(QtModuleInfo *module, QStringList libs)
+ {
+ if (contains(m_currentPath, module))
+ return;
+ m_currentPath.push_back(module);
+
+ auto isInLibs = [&libs](const QString &str) {
+ return std::binary_search(libs.begin(), libs.end(), str);
+ };
+ auto moduleLibraryLists = m_getLibraries(module);
+ for (QStringList *lst : moduleLibraryLists) {
+ auto it = std::remove_if(lst->begin(), lst->end(), isInLibs);
+ if (it != lst->end())
+ lst->erase(it, lst->end());
+ }
+ const QString libFilePath = m_getLibFilePath(module);
+ if (!libFilePath.isEmpty())
+ libs.push_back(libFilePath);
+ for (QStringList *lst : moduleLibraryLists)
+ std::copy(lst->begin(), lst->end(), std::back_inserter(libs));
+ std::sort(libs.begin(), libs.end());
+
+ for (auto rdep : m_revDeps[module])
+ traverse(rdep, libs);
+
+ m_currentPath.pop_back();
+ }
+
+ std::unordered_map<QtModuleInfo *, std::vector<QtModuleInfo *>> m_revDeps;
+ std::vector<QtModuleInfo *> m_currentPath;
+ std::function<std::vector<QStringList *>(QtModuleInfo *)> m_getLibraries;
+ std::function<QString(QtModuleInfo *)> m_getLibFilePath;
+};
+
+static void removeDuplicatedDependencyLibs(QList<QtModuleInfo> *modules)
+{
+ DuplicatedDependencyLibsRemover dlr;
+ dlr.apply(modules);
+}
QtModuleInfo::QtModuleInfo()
: isPrivate(false), hasLibrary(true), isStaticLibrary(false), isPlugin(false), mustExist(true)
@@ -651,6 +756,7 @@ QList<QtModuleInfo> allQt5Modules(const Profile &profile, const QtEnvironment &q
}
replaceQtLibNamesWithFilePath(&modules, qtEnvironment);
+ removeDuplicatedDependencyLibs(&modules);
return modules;
}