From 17b89cd422ff2d024df00dd8c8b35c42c3985819 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Mar 2017 18:38:00 +0100 Subject: [PATCH] CMake: Speed up server-mode reader This patch reduces the time to generate a project tree by 15% in my test project. Change-Id: Ie5956cdd2108873118654857dc299bdb0b6d3636 Reviewed-by: Tim Jenssen --- .../cmakeprojectmanager/servermodereader.cpp | 56 +++++++++++-------- .../cmakeprojectmanager/servermodereader.h | 9 ++- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 871ede041aa..86430e041f8 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -284,8 +284,8 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root, addCMakeInputs(root, m_parameters.sourceDirectory, m_parameters.buildDirectory, cmakeFilesSource, cmakeFilesBuild, cmakeFilesOther); - addCMakeLists(root, cmakeLists); - addProjects(root, m_projects, allFiles); + QHash cmakeListsNodes = addCMakeLists(root, cmakeLists); + addProjects(cmakeListsNodes, m_projects, allFiles); } void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps) @@ -530,28 +530,36 @@ void ServerModeReader::extractCacheData(const QVariantMap &data) m_cmakeCache = config; } -void ServerModeReader::addCMakeLists(CMakeProjectNode *root, const QList &cmakeLists) +QHash +ServerModeReader::addCMakeLists(CMakeProjectNode *root, const QList &cmakeLists) { + QHash cmakeListsNodes; + cmakeListsNodes.insert(root->filePath(), root); + const QSet cmakeDirs = Utils::transform(cmakeLists, [](const Node *n) { return n->filePath().parentDir(); }); root->addNestedNodes(cmakeLists, Utils::FileName(), - [&cmakeDirs](const Utils::FileName &fp) -> ProjectExplorer::FolderNode * { - return cmakeDirs.contains(fp) ? new CMakeListsNode(fp) : new FolderNode(fp); + [&cmakeDirs, &cmakeListsNodes](const Utils::FileName &fp) + -> ProjectExplorer::FolderNode * { + FolderNode *fn = nullptr; + if (cmakeDirs.contains(fp)) { + CMakeListsNode *n = new CMakeListsNode(fp); + cmakeListsNodes.insert(fp, n); + fn = n; + } else { + fn = new FolderNode(fp); + } + return fn; }); root->compress(); + return cmakeListsNodes; } -static ProjectNode *findCMakeNode(ProjectNode *root, const Utils::FileName &dir) +static ProjectNode *createProjectNode(const QHash &cmakeListsNodes, + const Utils::FileName &dir, const QString &displayName) { - Node *n = root->findNode([&dir](Node *n) { return n->asProjectNode() && n->filePath() == dir; }); - return n ? n->asProjectNode() : nullptr; -} - -static ProjectNode *findOrCreateProjectNode(ProjectNode *root, const Utils::FileName &dir, - const QString &displayName) -{ - ProjectNode *cmln = findCMakeNode(root, dir); - QTC_ASSERT(cmln, return nullptr); + ProjectNode *cmln = cmakeListsNodes.value(dir); + QTC_ASSERT(cmln, qDebug() << dir.toUserOutput() ; return nullptr); Utils::FileName projectName = dir; projectName.appendPath(".project::" + displayName); @@ -565,7 +573,7 @@ static ProjectNode *findOrCreateProjectNode(ProjectNode *root, const Utils::File return pn; } -void ServerModeReader::addProjects(CMakeProjectNode *root, +void ServerModeReader::addProjects(const QHash &cmakeListsNodes, const QList &projects, const QList &allFiles) { @@ -577,16 +585,16 @@ void ServerModeReader::addProjects(CMakeProjectNode *root, } for (const Project *p : projects) { - ProjectNode *pNode = findOrCreateProjectNode(root, p->sourceDirectory, p->name); - QTC_ASSERT(pNode, continue); - addTargets(root, p->targets, includeFiles); + ProjectNode *pNode = createProjectNode(cmakeListsNodes, p->sourceDirectory, p->name); + QTC_ASSERT(pNode, qDebug() << p->sourceDirectory.toUserOutput() ; continue); + addTargets(cmakeListsNodes, p->targets, includeFiles); } } -static CMakeTargetNode *findOrCreateTargetNode(ProjectNode *root, const Utils::FileName &dir, - const QString &displayName) +static CMakeTargetNode *createTargetNode(const QHash &cmakeListsNodes, + const Utils::FileName &dir, const QString &displayName) { - ProjectNode *cmln = findCMakeNode(root, dir); + ProjectNode *cmln = cmakeListsNodes.value(dir); QTC_ASSERT(cmln, return nullptr); Utils::FileName targetName = dir; @@ -601,12 +609,12 @@ static CMakeTargetNode *findOrCreateTargetNode(ProjectNode *root, const Utils::F return tn; } -void ServerModeReader::addTargets(CMakeProjectNode *root, +void ServerModeReader::addTargets(const QHash &cmakeListsNodes, const QList &targets, const QHash> &headers) { for (const Target *t : targets) { - CMakeTargetNode *tNode = findOrCreateTargetNode(root, t->sourceDirectory, t->name); + CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, t->sourceDirectory, t->name); QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; return); tNode->setTargetInformation(t->artifacts, t->type); addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, headers); diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index 8b973ce0ecd..7eb831df8ec 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -113,10 +113,13 @@ private: void extractCMakeInputsData(const QVariantMap &data); void extractCacheData(const QVariantMap &data); - void addCMakeLists(CMakeProjectNode *root, const QList &cmakeLists); - void addProjects(CMakeProjectNode *root, const QList &projects, + QHash + addCMakeLists(CMakeProjectNode *root, const QList &cmakeLists); + void addProjects(const QHash &cmakeListsNodes, + const QList &projects, const QList &allFiles); - void addTargets(CMakeProjectNode *root, const QList &targets, + void addTargets(const QHash &cmakeListsNodes, + const QList &targets, const QHash> &headers); void addFileGroups(ProjectExplorer::ProjectNode *targetRoot, const Utils::FileName &sourceDirectory,