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();
Q_UNUSED(name);
QSet<QString> 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<QString> &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<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;
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());