From 659e9ae93722c26b3bd855e021fbad0a3b73af3b Mon Sep 17 00:00:00 2001 From: Alexander Neundorf Date: Mon, 27 Feb 2023 22:56:26 +0100 Subject: cmGlobalVisualStudio8Generator: Collect CMake input files earlier --- Source/cmGlobalVisualStudio8Generator.cxx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 2aba46fe2c..7c5ad62376 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -262,6 +262,17 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() cmTarget* tgt = lg.AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false, std::move(cc)); + // Collect the input files used to generate all targets in this + // project. + std::vector listFiles; + for (const auto& gen : generators) { + cm::append(listFiles, gen->GetMakefile()->GetListFiles()); + } + // Sort the list of input files and remove duplicates. + std::sort(listFiles.begin(), listFiles.end(), std::less()); + auto new_end = std::unique(listFiles.begin(), listFiles.end()); + listFiles.erase(new_end, listFiles.end()); + auto ptr = cm::make_unique(tgt, &lg); auto* gt = ptr.get(); lg.AddGeneratorTarget(std::move(ptr)); @@ -295,13 +306,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // The custom rule runs cmake so set UTF-8 pipes. bool stdPipesUTF8 = true; - // Collect the input files used to generate all targets in this - // project. - std::vector listFiles; - for (const auto& gen : generators) { - cm::append(listFiles, gen->GetMakefile()->GetListFiles()); - } - // Add a custom prebuild target to run the VerifyGlobs script. cmake* cm = this->GetCMakeInstance(); if (cm->DoWriteGlobVerifyTarget()) { @@ -325,11 +329,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() listFiles.push_back(cm->GetGlobVerifyStamp()); } - // Sort the list of input files and remove duplicates. - std::sort(listFiles.begin(), listFiles.end(), std::less()); - auto new_end = std::unique(listFiles.begin(), listFiles.end()); - listFiles.erase(new_end, listFiles.end()); - // Create a rule to re-run CMake. std::string argS = cmStrCat("-S", lg.GetSourceDirectory()); std::string argB = cmStrCat("-B", lg.GetBinaryDirectory()); -- cgit v1.2.1 From df58dbb0e9ffc204abc82dd64fbf88059e769ec6 Mon Sep 17 00:00:00 2001 From: Alexander Neundorf Date: Sun, 19 Mar 2023 23:30:02 +0100 Subject: VS: Add CMake input files to ZERO_CHECK Add all cmake input files to the `ZERO_CHECK` project. Place files under `CMAKE_SOURCE_DIR` in a folder structure matching the directory structure. This way they are easier to find, and Visual Studio does not close them when reloading the project. Fixes: #24557 --- Source/cmGlobalVisualStudio8Generator.cxx | 16 ++ Source/cmVisualStudio10TargetGenerator.cxx | 56 +++++- Source/cmVisualStudio10TargetGenerator.h | 4 + Tests/RunCMake/FileAPI/codemodel-v2-check.py | 214 +++++++++++++++++++++ Tests/RunCMake/VS10Project/CMakeInputs-check.cmake | 25 +++ Tests/RunCMake/VS10Project/CMakeInputs.cmake | 0 Tests/RunCMake/VS10Project/RunCMakeTest.cmake | 1 + 7 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/VS10Project/CMakeInputs-check.cmake create mode 100644 Tests/RunCMake/VS10Project/CMakeInputs.cmake diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 7c5ad62376..d902c68234 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -273,6 +273,22 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() auto new_end = std::unique(listFiles.begin(), listFiles.end()); listFiles.erase(new_end, listFiles.end()); + // Add all cmake input files which are used by the project + // so Visual Studio does not close them when reloading it. + for (const std::string& listFile : listFiles) { + if (listFile.find("/CMakeFiles/") != std::string::npos) { + continue; + } + if (!cmSystemTools::IsSubDirectory(listFile, + lg.GetMakefile()->GetHomeDirectory()) && + !cmSystemTools::IsSubDirectory( + listFile, lg.GetMakefile()->GetHomeOutputDirectory())) { + continue; + } + + tgt->AddSource(listFile); + } + auto ptr = cm::make_unique(tgt, &lg); auto* gt = ptr.get(); lg.AddGeneratorTarget(std::move(ptr)); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 6266328c57..ec6608dac9 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -51,6 +52,8 @@ #include "cmValue.h" #include "cmVisualStudioGeneratorOptions.h" +const std::string kBuildSystemSources = "Buildsystem Input Files"; + struct cmIDEFlagTable; static void ConvertToWindowsSlash(std::string& s); @@ -1950,7 +1953,13 @@ void cmVisualStudio10TargetGenerator::WriteGroups() "http://schemas.microsoft.com/developer/msbuild/2003"); for (auto const& ti : this->Tools) { - this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups); + if ((this->GeneratorTarget->GetName() == + CMAKE_CHECK_BUILD_SYSTEM_TARGET) && + (ti.first == "None")) { + this->WriteBuildSystemSources(e0, ti.first, ti.second); + } else { + this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups); + } } // Added files are images and the manifest. @@ -2021,6 +2030,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups() "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;" "gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms"); } + + if (this->GeneratorTarget->GetName() == + CMAKE_CHECK_BUILD_SYSTEM_TARGET) { + for (const std::string& filter : this->BuildSystemSourcesFilters) { + std::string guidName = "SG_Filter_"; + guidName += filter; + std::string guid = this->GlobalGenerator->GetGUID(guidName); + Elem e2(e1, "Filter"); + e2.Attribute("Include", filter); + e2.Element("UniqueIdentifier", "{" + guid + "}"); + } + } } } fout << '\n'; @@ -2087,6 +2108,39 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources( } } +void cmVisualStudio10TargetGenerator::WriteBuildSystemSources( + Elem& e0, std::string const& name, ToolSources const& sources) +{ + const std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + const std::string::size_type srcDirLength = srcDir.length(); + + Elem e1(e0, "ItemGroup"); + e1.SetHasElements(); + for (ToolSource const& s : sources) { + cmSourceFile const* sf = s.SourceFile; + std::string const& source = sf->GetFullPath(); + + cm::filesystem::path sourcePath(source); + bool isInSrcDir = cmHasPrefix(source, srcDir); + + std::string filter = kBuildSystemSources; + if (isInSrcDir) { + std::string parentPath = sourcePath.parent_path().string(); + if (srcDir != parentPath) { + filter += parentPath.substr(srcDirLength); + } + ConvertToWindowsSlash(filter); + this->BuildSystemSourcesFilters.insert(filter); + } + + std::string path = this->ConvertPath(source, s.RelativePath); + ConvertToWindowsSlash(path); + Elem e2(e1, name); + e2.Attribute("Include", path); + e2.Element("Filter", filter); + } +} + void cmVisualStudio10TargetGenerator::WriteHeaderSource( Elem& e1, cmSourceFile const* sf, ConfigToSettings const& toolSettings) { diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 97ae69fc37..a87cb01b7e 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -193,6 +193,9 @@ private: void WriteGroupSources(Elem& e0, std::string const& name, ToolSources const& sources, std::vector&); + void WriteBuildSystemSources(Elem& e0, std::string const& name, + ToolSources const& sources); + void AddMissingSourceGroups(std::set& groupsUsed, const std::vector& allGroups); bool IsResxHeader(const std::string& headerFile); @@ -243,6 +246,7 @@ private: std::set ASanEnabledConfigurations; std::set FuzzerEnabledConfigurations; std::map SpectreMitigation; + std::set BuildSystemSourcesFilters; cmGlobalVisualStudio10Generator* const GlobalGenerator; cmLocalVisualStudio10Generator* const LocalGenerator; std::set CSharpCustomCommandNames; diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index fda18b5c08..eb52975265 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -848,7 +848,203 @@ def gen_check_targets(c, g, inSource): for e in expected: if e["type"] == "UTILITY": if e["id"] == "^ZERO_CHECK::@6890427a1f51a3e7e1df$": + # The json files have data for Xcode. Substitute data for VS. e["sources"] = [ + { + "path": "^CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^alias/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^codemodel-v2\\.cmake$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^custom/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^cxx/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^dir/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^dir/dir/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^fileset/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^imported/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^include_test\\.cmake$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^interface/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^object/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "path": "^subdir/CMakeLists\\.txt$", + "isGenerated": None, + "fileSetName": None, + "sourceGroupName": "", + "compileGroupLanguage": None, + "backtrace": [ + { + "file": "^CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, { "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/([0-9a-f]+/)?generate\\.stamp\\.rule$", "isGenerated": True, @@ -866,6 +1062,24 @@ def gen_check_targets(c, g, inSource): }, ] e["sourceGroups"] = [ + { + "name": "", + "sourcePaths": [ + "^CMakeLists\\.txt$", + "^alias/CMakeLists\\.txt$", + "^codemodel-v2\\.cmake$", + "^custom/CMakeLists\\.txt$", + "^cxx/CMakeLists\\.txt$", + "^dir/CMakeLists\\.txt$", + "^dir/dir/CMakeLists\\.txt$", + "^fileset/CMakeLists\\.txt$", + "^imported/CMakeLists\\.txt$", + "^include_test\\.cmake$", + "^interface/CMakeLists\\.txt$", + "^object/CMakeLists\\.txt$", + "^subdir/CMakeLists\\.txt$", + ], + }, { "name": "CMake Rules", "sourcePaths": [ diff --git a/Tests/RunCMake/VS10Project/CMakeInputs-check.cmake b/Tests/RunCMake/VS10Project/CMakeInputs-check.cmake new file mode 100644 index 0000000000..a125574d8e --- /dev/null +++ b/Tests/RunCMake/VS10Project/CMakeInputs-check.cmake @@ -0,0 +1,25 @@ +set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/ZERO_CHECK.vcxproj") +if(NOT EXISTS "${vcProjectFile}") + set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.") + return() +endif() + +set(found_CMakeInputs 0) +file(STRINGS "${vcProjectFile}" lines) +foreach(line IN LISTS lines) + if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*CMakeInputs.cmake") + set(rule "${CMAKE_MATCH_1}") + if(NOT rule STREQUAL "None") + set(RunCMake_TEST_FAILED "CMakeInputs.cmake referenced as ${rule} instead of None") + return() + endif() + if(found_CMakeInputs) + set(RunCMake_TEST_FAILED "CMakeInputs.cmake referenced multiple times") + return() + endif() + set(found_CMakeInputs 1) + endif() +endforeach() +if(NOT found_CMakeInputs) + set(RunCMake_TEST_FAILED "CMakeInputs.cmake not referenced") +endif() diff --git a/Tests/RunCMake/VS10Project/CMakeInputs.cmake b/Tests/RunCMake/VS10Project/CMakeInputs.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index 669049a737..cb1a5d5403 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -7,6 +7,7 @@ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREA run_cmake(LanguageStandard) endif() +run_cmake(CMakeInputs) run_cmake(CustomCommandGenex) if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio 1[1-5] ") run_cmake(CustomCommandParallel) -- cgit v1.2.1