VS: Fix regression causing source accumulation across Fortran projects

Since commit de2afc5d53 (cmMakeFile: Remove source groups argument from
`FindSourceGroup`, 2025-11-07, v4.3.0-rc1~414^2~2) we share source group
assignments across targets to avoid copying and repeated work.  However,
the VS 7 generator, still used for Fortran, relies on per-target
per-group source lists.  Build them specifically for that case.

The deprecated Eclipse CDT4 extra generator had the same regression,
so fix it too.

Fixes: #27779
This commit is contained in:
Brad King
2026-05-01 10:42:55 -04:00
parent 26e52f3c36
commit f513867bc4
6 changed files with 54 additions and 45 deletions
+11 -8
View File
@@ -463,7 +463,8 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
}
void cmExtraEclipseCDT4Generator::WriteGroups(
SourceGroupVector const& sourceGroups, std::string& linkName,
SourceGroupVector const& sourceGroups,
cmSourceGroupFiles const& sourceGroupFiles, std::string& linkName,
cmXMLWriter& xml)
{
for (auto const& sg : sourceGroups) {
@@ -475,10 +476,11 @@ void cmExtraEclipseCDT4Generator::WriteGroups(
xml, linkName3, "virtual:/virtual", VirtualFolder);
SourceGroupVector const& children = sg->GetGroupChildren();
if (!children.empty()) {
this->WriteGroups(children, linkName, xml);
this->WriteGroups(children, sourceGroupFiles, linkName, xml);
}
std::vector<cmSourceFile const*> sFiles = sg->GetSourceFiles();
for (cmSourceFile const* file : sFiles) {
std::vector<cmSourceFile const*> const& sourceFiles =
sourceGroupFiles.GetSourceFiles(sg.get());
for (cmSourceFile const* file : sourceFiles) {
std::string const& fullPath = file->GetFullPath();
if (!cmSystemTools::FileIsDirectory(fullPath)) {
@@ -521,17 +523,18 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
break; // skip generating the linked resources to the source files
}
// get the files from the source lists then add them to the groups
cmSourceGroupFiles sourceGroupFiles;
std::vector<cmSourceFile*> files;
target->GetSourceFiles(
files, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* sf : files) {
// Add the file to the list of sources.
std::string const& source = sf->ResolveFullPath();
cmSourceGroup* sourceGroup = lg->FindSourceGroup(source);
sourceGroup->AssignSource(sf);
sourceGroupFiles.Add(lg->FindSourceGroup(sf->ResolveFullPath()),
sf);
}
this->WriteGroups(makefile->GetSourceGroups(), linkName2, xml);
this->WriteGroups(makefile->GetSourceGroups(), sourceGroupFiles,
linkName2, xml);
} break;
// ignore all others:
default:
+1
View File
@@ -88,6 +88,7 @@ private:
cmLocalGenerator& lg);
void WriteGroups(SourceGroupVector const& sourceGroups,
cmSourceGroupFiles const& sourceGroupFiles,
std::string& linkName, cmXMLWriter& xml);
void CreateLinksToSubprojects(cmXMLWriter& xml, std::string const& baseDir);
void CreateLinksForTargets(cmXMLWriter& xml);
+9 -7
View File
@@ -1386,6 +1386,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
AllConfigSources sources;
sources.Sources = target->GetAllConfigSources();
cmSourceGroupFiles sourceGroupFiles;
// Add CMakeLists.txt file with rule to re-run CMake for user convenience.
if (target->GetType() != cmStateEnums::GLOBAL_TARGET &&
target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
@@ -1423,9 +1425,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
}
}
// Add the file to the list of sources.
std::string const source = sf->GetFullPath();
cmSourceGroup* sourceGroup = this->FindSourceGroup(source);
sourceGroup->AssignSource(sf);
sourceGroupFiles.Add(this->FindSourceGroup(sf->GetFullPath()), sf);
}
// open the project
@@ -1438,7 +1438,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// Loop through every source group.
SourceGroupVector const& sourceGroups = this->Makefile->GetSourceGroups();
for (auto const& sg : sourceGroups) {
this->WriteGroup(sg.get(), target, fout, libName, configs, sources);
this->WriteGroup(sg.get(), target, fout, libName, configs, sources,
sourceGroupFiles);
}
fout << "\t</Files>\n";
@@ -1648,11 +1649,12 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
bool cmLocalVisualStudio7Generator::WriteGroup(
cmSourceGroup const* sg, cmGeneratorTarget* target, std::ostream& fout,
std::string const& libName, std::vector<std::string> const& configs,
AllConfigSources const& sources)
AllConfigSources const& sources, cmSourceGroupFiles const& sourceGroupFiles)
{
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
std::vector<cmSourceFile const*> const& sourceFiles = sg->GetSourceFiles();
std::vector<cmSourceFile const*> const& sourceFiles =
sourceGroupFiles.GetSourceFiles(sg);
SourceGroupVector const& children = sg->GetGroupChildren();
// Write the children to temporary output.
@@ -1660,7 +1662,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
std::ostringstream tmpOut;
for (auto const& child : children) {
if (this->WriteGroup(child.get(), target, tmpOut, libName, configs,
sources)) {
sources, sourceGroupFiles)) {
hasChildrenWithSources = true;
}
}
+3 -1
View File
@@ -23,6 +23,7 @@ class cmLocalVisualStudio7GeneratorInternals;
class cmMakefile;
class cmSourceFile;
class cmSourceGroup;
class cmSourceGroupFiles;
class cmVS7GeneratorOptions : public cmVisualStudioGeneratorOptions
{
@@ -147,7 +148,8 @@ private:
bool WriteGroup(cmSourceGroup const* sg, cmGeneratorTarget* target,
std::ostream& fout, std::string const& libName,
std::vector<std::string> const& configs,
AllConfigSources const& sources);
AllConfigSources const& sources,
cmSourceGroupFiles const& sourceGroupFiles);
friend class cmLocalVisualStudio7GeneratorFCInfo;
friend class cmLocalVisualStudio7GeneratorInternals;
+16 -11
View File
@@ -7,7 +7,6 @@
#include <cm/memory>
#include "cmGeneratorExpression.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
class cmSourceGroupInternals
@@ -85,21 +84,11 @@ bool cmSourceGroup::MatchesFiles(std::string const& name) const
return this->GroupFiles.find(name) != this->GroupFiles.cend();
}
void cmSourceGroup::AssignSource(cmSourceFile const* sf)
{
this->SourceFiles.push_back(sf);
}
std::set<std::string> const& cmSourceGroup::GetGroupFiles() const
{
return this->GroupFiles;
}
std::vector<cmSourceFile const*> const& cmSourceGroup::GetSourceFiles() const
{
return this->SourceFiles;
}
void cmSourceGroup::AddChild(std::unique_ptr<cmSourceGroup> child)
{
this->Internal->GroupChildren.push_back(std::move(child));
@@ -196,3 +185,19 @@ cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& source,
// Shouldn't get here, but just in case, return the default group.
return groups.data()->get();
}
void cmSourceGroupFiles::Add(cmSourceGroup const* sg, cmSourceFile const* sf)
{
this->SourceFiles[sg].push_back(sf);
}
std::vector<cmSourceFile const*> const& cmSourceGroupFiles::GetSourceFiles(
cmSourceGroup const* sg) const
{
auto i = this->SourceFiles.find(sg);
if (i != this->SourceFiles.end()) {
return i->second;
}
static std::vector<cmSourceFile const*> const empty;
return empty;
}
+14 -18
View File
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
#include <memory>
#include <set>
#include <string>
@@ -99,23 +100,11 @@ public:
*/
cmSourceGroup* MatchChildrenRegex(std::string const& name) const;
/**
* Assign the given source file to this group. Used only by
* generators.
*/
void AssignSource(cmSourceFile const* sf);
/**
* Get the set of file names explicitly added to this source group.
*/
std::set<std::string> const& GetGroupFiles() const;
/**
* Get the list of the source files that have been assigned to this
* source group.
*/
std::vector<cmSourceFile const*> const& GetSourceFiles() const;
SourceGroupVector const& GetGroupChildren() const;
/**
@@ -142,11 +131,18 @@ private:
*/
std::set<std::string> GroupFiles;
/**
* Vector of all source files that have been assigned to
* this group.
*/
std::vector<cmSourceFile const*> SourceFiles;
std::unique_ptr<cmSourceGroupInternals> Internal;
};
/** \class cmSourceGroup
* \brief Used by generators to organize a target's sources into groups.
*/
class cmSourceGroupFiles
{
std::map<cmSourceGroup const*, std::vector<cmSourceFile const*>> SourceFiles;
public:
void Add(cmSourceGroup const* sg, cmSourceFile const* sf);
std::vector<cmSourceFile const*> const& GetSourceFiles(
cmSourceGroup const* sg) const;
};