CMake: Deduplicate targets in server-mode

CMake server-mode does report targets for each "PROJECT" that was
encountered before the target was defined. So it reports several
copies of the same data all the time. Deduplicate that information.

This fixes files being duplicated in the code model and the project
tree.

Task-number: QTCREATORBUG-17955
Change-Id: I95daa0f48e37587234d7e04e9bed6d20884f8be0
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Tobias Hunger
2017-04-07 12:01:41 +02:00
parent 06ccc35b3b
commit 5972f7fac6
2 changed files with 21 additions and 7 deletions

View File

@@ -414,14 +414,16 @@ void ServerModeReader::extractConfigurationData(const QVariantMap &data)
{ {
const QString name = data.value(NAME_KEY).toString(); const QString name = data.value(NAME_KEY).toString();
Q_UNUSED(name); Q_UNUSED(name);
QSet<QString> knownTargets; // To filter duplicate target names:-/
const QVariantList projects = data.value("projects").toList(); const QVariantList projects = data.value("projects").toList();
for (const QVariant &p : projects) { for (const QVariant &p : projects) {
const QVariantMap pData = p.toMap(); const QVariantMap pData = p.toMap();
m_projects.append(extractProjectData(pData)); m_projects.append(extractProjectData(pData, knownTargets));
} }
} }
ServerModeReader::Project *ServerModeReader::extractProjectData(const QVariantMap &data) ServerModeReader::Project *ServerModeReader::extractProjectData(const QVariantMap &data,
QSet<QString> &knownTargets)
{ {
auto project = new Project; auto project = new Project;
project->name = data.value(NAME_KEY).toString(); project->name = data.value(NAME_KEY).toString();
@@ -430,16 +432,28 @@ ServerModeReader::Project *ServerModeReader::extractProjectData(const QVariantMa
const QVariantList targets = data.value("targets").toList(); const QVariantList targets = data.value("targets").toList();
for (const QVariant &t : targets) { for (const QVariant &t : targets) {
const QVariantMap tData = t.toMap(); const QVariantMap tData = t.toMap();
project->targets.append(extractTargetData(tData, project)); Target *tp = extractTargetData(tData, project, knownTargets);
if (tp)
project->targets.append(tp);
} }
return project; return project;
} }
ServerModeReader::Target *ServerModeReader::extractTargetData(const QVariantMap &data, Project *p) ServerModeReader::Target *ServerModeReader::extractTargetData(const QVariantMap &data, Project *p,
QSet<QString> &knownTargets)
{ {
const QString targetName = data.value(NAME_KEY).toString();
// Remove duplicate targets: CMake unfortunately does duplicate targets for all projects that
// contain them. Keep at least till cmake 3.9 is deprecated.
const int count = knownTargets.count();
knownTargets.insert(targetName);
if (knownTargets.count() == count)
return nullptr;
auto target = new Target; auto target = new Target;
target->project = p; target->project = p;
target->name = data.value(NAME_KEY).toString(); target->name = targetName;
target->sourceDirectory = FileName::fromString(data.value(SOURCE_DIRECTORY_KEY).toString()); target->sourceDirectory = FileName::fromString(data.value(SOURCE_DIRECTORY_KEY).toString());
target->buildDirectory = FileName::fromString(data.value("buildDirectory").toString()); target->buildDirectory = FileName::fromString(data.value("buildDirectory").toString());

View File

@@ -107,8 +107,8 @@ private:
void extractCodeModelData(const QVariantMap &data); void extractCodeModelData(const QVariantMap &data);
void extractConfigurationData(const QVariantMap &data); void extractConfigurationData(const QVariantMap &data);
Project *extractProjectData(const QVariantMap &data); Project *extractProjectData(const QVariantMap &data, QSet<QString> &knownTargets);
Target *extractTargetData(const QVariantMap &data, Project *p); Target *extractTargetData(const QVariantMap &data, Project *p, QSet<QString> &knownTargets);
FileGroup *extractFileGroupData(const QVariantMap &data, const QDir &srcDir, Target *t); FileGroup *extractFileGroupData(const QVariantMap &data, const QDir &srcDir, Target *t);
void extractCMakeInputsData(const QVariantMap &data); void extractCMakeInputsData(const QVariantMap &data);
void extractCacheData(const QVariantMap &data); void extractCacheData(const QVariantMap &data);