diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 6b159474015..a83ca14aaf8 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -414,14 +414,16 @@ void ServerModeReader::extractConfigurationData(const QVariantMap &data) { const QString name = data.value(NAME_KEY).toString(); Q_UNUSED(name); + QSet knownTargets; // To filter duplicate target names:-/ const QVariantList projects = data.value("projects").toList(); for (const QVariant &p : projects) { 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 &knownTargets) { auto project = new Project; project->name = data.value(NAME_KEY).toString(); @@ -430,16 +432,28 @@ ServerModeReader::Project *ServerModeReader::extractProjectData(const QVariantMa const QVariantList targets = data.value("targets").toList(); for (const QVariant &t : targets) { 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; } -ServerModeReader::Target *ServerModeReader::extractTargetData(const QVariantMap &data, Project *p) +ServerModeReader::Target *ServerModeReader::extractTargetData(const QVariantMap &data, Project *p, + QSet &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; target->project = p; - target->name = data.value(NAME_KEY).toString(); + target->name = targetName; target->sourceDirectory = FileName::fromString(data.value(SOURCE_DIRECTORY_KEY).toString()); target->buildDirectory = FileName::fromString(data.value("buildDirectory").toString()); diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index 01c98182ea3..3b1202c009a 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -107,8 +107,8 @@ private: void extractCodeModelData(const QVariantMap &data); void extractConfigurationData(const QVariantMap &data); - Project *extractProjectData(const QVariantMap &data); - Target *extractTargetData(const QVariantMap &data, Project *p); + Project *extractProjectData(const QVariantMap &data, QSet &knownTargets); + Target *extractTargetData(const QVariantMap &data, Project *p, QSet &knownTargets); FileGroup *extractFileGroupData(const QVariantMap &data, const QDir &srcDir, Target *t); void extractCMakeInputsData(const QVariantMap &data); void extractCacheData(const QVariantMap &data);