From f513867bc46ca12589ad4e1f32a919f46bafed35 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 30 Apr 2026 21:49:15 -0400 Subject: [PATCH] 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 --- Source/cmExtraEclipseCDT4Generator.cxx | 19 ++++++++------ Source/cmExtraEclipseCDT4Generator.h | 1 + Source/cmLocalVisualStudio7Generator.cxx | 16 ++++++------ Source/cmLocalVisualStudio7Generator.h | 4 ++- Source/cmSourceGroup.cxx | 27 ++++++++++++-------- Source/cmSourceGroup.h | 32 +++++++++++------------- 6 files changed, 54 insertions(+), 45 deletions(-) diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 9a5e10903d..7427422ddd 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -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 sFiles = sg->GetSourceFiles(); - for (cmSourceFile const* file : sFiles) { + std::vector 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 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: diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index aa7cc25022..fa92fb4174 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h @@ -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); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 567ce3b280..a6bf9c8a51 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -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\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 const& configs, - AllConfigSources const& sources) + AllConfigSources const& sources, cmSourceGroupFiles const& sourceGroupFiles) { cmGlobalVisualStudio7Generator* gg = static_cast(this->GlobalGenerator); - std::vector const& sourceFiles = sg->GetSourceFiles(); + std::vector 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; } } diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 38df53ba2a..885d8ca6dc 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -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 const& configs, - AllConfigSources const& sources); + AllConfigSources const& sources, + cmSourceGroupFiles const& sourceGroupFiles); friend class cmLocalVisualStudio7GeneratorFCInfo; friend class cmLocalVisualStudio7GeneratorInternals; diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 7251810949..3b5feea256 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -7,7 +7,6 @@ #include #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 const& cmSourceGroup::GetGroupFiles() const { return this->GroupFiles; } -std::vector const& cmSourceGroup::GetSourceFiles() const -{ - return this->SourceFiles; -} - void cmSourceGroup::AddChild(std::unique_ptr 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 const& cmSourceGroupFiles::GetSourceFiles( + cmSourceGroup const* sg) const +{ + auto i = this->SourceFiles.find(sg); + if (i != this->SourceFiles.end()) { + return i->second; + } + static std::vector const empty; + return empty; +} diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 4ce79ed3b7..ff7d23fdf0 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h @@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include #include #include #include @@ -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 const& GetGroupFiles() const; - /** - * Get the list of the source files that have been assigned to this - * source group. - */ - std::vector const& GetSourceFiles() const; - SourceGroupVector const& GetGroupChildren() const; /** @@ -142,11 +131,18 @@ private: */ std::set GroupFiles; - /** - * Vector of all source files that have been assigned to - * this group. - */ - std::vector SourceFiles; - std::unique_ptr Internal; }; + +/** \class cmSourceGroup + * \brief Used by generators to organize a target's sources into groups. + */ +class cmSourceGroupFiles +{ + std::map> SourceFiles; + +public: + void Add(cmSourceGroup const* sg, cmSourceFile const* sf); + std::vector const& GetSourceFiles( + cmSourceGroup const* sg) const; +};