From e68a7a584f84ed889255341fae21a5e35fdb1132 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 2 Jun 2017 20:12:10 -0700 Subject: Fix handling of same subproject names in generated VS solutions While Qbs product names must be unambiguous, using the same project name several times is perfectly valid, as long as all projects with the same name belong to a different root project. Utilize the project's source file location to distinguish projects that have the same name. Use this in conjunction with the name to create an ID that is used as the key for the solutionFolders map. Change-Id: I47079cd4207d505892e79755a3986614025d2749 Task-number: QBS-1082 Reviewed-by: Jake Petroules Reviewed-by: Thomas Epting Reviewed-by: Joerg Bornemann --- src/lib/corelib/generators/generatordata.cpp | 23 ++++++++++++++++++++++ src/lib/corelib/generators/generatordata.h | 12 +++++++++++ .../visualstudio/visualstudiogenerator.cpp | 12 ++++++----- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/lib/corelib/generators/generatordata.cpp b/src/lib/corelib/generators/generatordata.cpp index eb0cb2d09..e8d554d20 100644 --- a/src/lib/corelib/generators/generatordata.cpp +++ b/src/lib/corelib/generators/generatordata.cpp @@ -92,6 +92,29 @@ QString GeneratableProjectData::name() const return name; } +CodeLocation GeneratableProjectData::location() const +{ + CodeLocation location; + QMapIterator it(data); + while (it.hasNext()) { + it.next(); + CodeLocation oldLocation = location; + location = it.value().location(); + if (oldLocation.isValid() && oldLocation != location) + throw ErrorInfo(QLatin1String("Projects with different code locations " + "per-configuration are not compatible with this " + "generator.")); + } + return location; +} + +GeneratableProjectData::Id GeneratableProjectData::uniqueName() const +{ + GeneratableProjectData::Id id; + id.value = name() + QLatin1Char('-') + location().toString(); + return id; +} + QDir GeneratableProject::baseBuildDirectory() const { Internal::Set baseBuildDirectory; diff --git a/src/lib/corelib/generators/generatordata.h b/src/lib/corelib/generators/generatordata.h index 2c64bb370..d57f2f510 100644 --- a/src/lib/corelib/generators/generatordata.h +++ b/src/lib/corelib/generators/generatordata.h @@ -59,10 +59,22 @@ struct GeneratableProductData { }; struct GeneratableProjectData { + struct Id { + private: + friend class GeneratableProjectData; + Id() { } + QString value; + + public: + bool operator<(const Id &id) const { return value < id.value; } + }; + GeneratableProjectDataMap data; QList subProjects; QList products; QString name() const; + CodeLocation location() const; + Id uniqueName() const; }; struct GeneratableProject : public GeneratableProjectData { diff --git a/src/lib/corelib/generators/visualstudio/visualstudiogenerator.cpp b/src/lib/corelib/generators/visualstudio/visualstudiogenerator.cpp index ea621b271..179232114 100644 --- a/src/lib/corelib/generators/visualstudio/visualstudiogenerator.cpp +++ b/src/lib/corelib/generators/visualstudio/visualstudiogenerator.cpp @@ -79,7 +79,7 @@ public: QString solutionFilePath; QMap> msbuildProjects; QMap solutionProjects; - QMap solutionFolders; + QMap solutionFolders; QList> propertySheetNames; void reset(); @@ -118,9 +118,9 @@ public: // as its parent object (so skip giving it a parent folder) if (!parentProjectData.name().isEmpty()) { nestedProjects->appendProperty( - generator->d->solutionFolders.value(projectData.name())->guid() + generator->d->solutionFolders.value(projectData.uniqueName())->guid() .toString(), - generator->d->solutionFolders.value(parentProjectData.name())->guid() + generator->d->solutionFolders.value(parentProjectData.uniqueName())->guid() .toString()); } } @@ -138,7 +138,8 @@ public: nestedProjects->appendProperty( generator->d->solutionProjects.value(productData.name())->guid().toString(), - generator->d->solutionFolders.value(projectData.name())->guid().toString()); + generator->d->solutionFolders.value(projectData.uniqueName())->guid() + .toString()); } private: @@ -340,7 +341,8 @@ void VisualStudioGenerator::visitProjectData(const GeneratableProject &project, auto solutionFolder = new VisualStudioSolutionFolderProject(d->solution.data()); solutionFolder->setName(projectData.name()); d->solution->appendProject(solutionFolder); - d->solutionFolders.insert(projectData.name(), solutionFolder); + QBS_CHECK(!d->solutionFolders.contains(projectData.uniqueName())); + d->solutionFolders.insert(projectData.uniqueName(), solutionFolder); } void VisualStudioGenerator::visitProduct(const GeneratableProject &project, -- cgit v1.2.3