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 <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2017-03-24 18:38:00 +01:00
parent 54be52a4fa
commit 17b89cd422
2 changed files with 38 additions and 27 deletions

View File

@@ -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<Utils::FileName, ProjectNode *> 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<FileNode *> &cmakeLists)
QHash<Utils::FileName, ProjectNode *>
ServerModeReader::addCMakeLists(CMakeProjectNode *root, const QList<FileNode *> &cmakeLists)
{
QHash<Utils::FileName, ProjectNode *> cmakeListsNodes;
cmakeListsNodes.insert(root->filePath(), root);
const QSet<Utils::FileName> cmakeDirs
= Utils::transform<QSet>(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<Utils::FileName, ProjectNode *> &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<Utils::FileName, ProjectNode *> &cmakeListsNodes,
const QList<Project *> &projects,
const QList<const FileNode *> &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<Utils::FileName, ProjectNode *> &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<Utils::FileName, ProjectNode *> &cmakeListsNodes,
const QList<ServerModeReader::Target *> &targets,
const QHash<FileName, QList<const FileNode *>> &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);

View File

@@ -113,10 +113,13 @@ private:
void extractCMakeInputsData(const QVariantMap &data);
void extractCacheData(const QVariantMap &data);
void addCMakeLists(CMakeProjectNode *root, const QList<ProjectExplorer::FileNode *> &cmakeLists);
void addProjects(CMakeProjectNode *root, const QList<Project *> &projects,
QHash<Utils::FileName, ProjectExplorer::ProjectNode *>
addCMakeLists(CMakeProjectNode *root, const QList<ProjectExplorer::FileNode *> &cmakeLists);
void addProjects(const QHash<Utils::FileName, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
const QList<Project *> &projects,
const QList<const ProjectExplorer::FileNode *> &allFiles);
void addTargets(CMakeProjectNode *root, const QList<Target *> &targets,
void addTargets(const QHash<Utils::FileName, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
const QList<Target *> &targets,
const QHash<Utils::FileName, QList<const ProjectExplorer::FileNode *>> &headers);
void addFileGroups(ProjectExplorer::ProjectNode *targetRoot,
const Utils::FileName &sourceDirectory,