Ver Fonte

VS: Generate .slnx files for VS 2026

Since the `Visual Studio 18 2026` generator is new, we can switch
to the `.slnx` file format without changing behavior for users of
VS 2022 and older.

Fixes: #25887
Brad King há 4 meses atrás
pai
commit
e6aa7742b0
49 ficheiros alterados com 773 adições e 44 exclusões
  1. 45 8
      Source/cmGlobalVisualStudio10Generator.cxx
  2. 24 14
      Source/cmGlobalVisualStudioGenerator.cxx
  3. 91 0
      Source/cmVSSolution.cxx
  4. 3 0
      Source/cmVSSolution.h
  5. 25 0
      Tests/RunCMake/RunCMake.cmake
  6. 19 0
      Tests/RunCMake/VSSolution/AddPackageToDefault-check-slnx.cmake
  7. 1 1
      Tests/RunCMake/VSSolution/AddPackageToDefault-check.cmake
  8. 28 0
      Tests/RunCMake/VSSolution/CMP0143-NEW-check-slnx.cmake
  9. 1 1
      Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake
  10. 26 0
      Tests/RunCMake/VSSolution/CMP0143-OLD-check-slnx.cmake
  11. 1 1
      Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake
  12. 26 0
      Tests/RunCMake/VSSolution/CMP0143-WARN-check-slnx.cmake
  13. 1 1
      Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake
  14. 26 0
      Tests/RunCMake/VSSolution/DeployEnabled-check-slnx.cmake
  15. 1 1
      Tests/RunCMake/VSSolution/DeployEnabled-check.cmake
  16. 28 0
      Tests/RunCMake/VSSolution/MorePost-check-slnx.cmake
  17. 1 1
      Tests/RunCMake/VSSolution/MorePost-check.cmake
  18. 28 0
      Tests/RunCMake/VSSolution/MorePre-check-slnx.cmake
  19. 1 1
      Tests/RunCMake/VSSolution/MorePre-check.cmake
  20. 23 0
      Tests/RunCMake/VSSolution/OnePost-check-slnx.cmake
  21. 1 1
      Tests/RunCMake/VSSolution/OnePost-check.cmake
  22. 23 0
      Tests/RunCMake/VSSolution/OnePre-check-slnx.cmake
  23. 1 1
      Tests/RunCMake/VSSolution/OnePre-check.cmake
  24. 26 0
      Tests/RunCMake/VSSolution/Override1-check-slnx.cmake
  25. 1 1
      Tests/RunCMake/VSSolution/Override1-check.cmake
  26. 26 0
      Tests/RunCMake/VSSolution/Override2-check-slnx.cmake
  27. 1 1
      Tests/RunCMake/VSSolution/Override2-check.cmake
  28. 23 0
      Tests/RunCMake/VSSolution/Override3-check-slnx.cmake
  29. 1 1
      Tests/RunCMake/VSSolution/Override3-check.cmake
  30. 27 0
      Tests/RunCMake/VSSolution/PrePost-check-slnx.cmake
  31. 1 1
      Tests/RunCMake/VSSolution/PrePost-check.cmake
  32. 8 1
      Tests/RunCMake/VSSolution/RunCMakeTest.cmake
  33. 52 0
      Tests/RunCMake/VSSolution/SolutionItems-check-slnx.cmake
  34. 1 1
      Tests/RunCMake/VSSolution/SolutionItems-check.cmake
  35. 26 0
      Tests/RunCMake/VSSolution/StartupProject-check-slnx.cmake
  36. 1 1
      Tests/RunCMake/VSSolution/StartupProject-check.cmake
  37. 19 0
      Tests/RunCMake/VSSolution/StartupProjectMissing-check-slnx.cmake
  38. 1 1
      Tests/RunCMake/VSSolution/StartupProjectMissing-check.cmake
  39. 28 0
      Tests/RunCMake/VSSolution/StartupProjectUseFolders-check-slnx.cmake
  40. 1 1
      Tests/RunCMake/VSSolution/StartupProjectUseFolders-check.cmake
  41. 24 0
      Tests/RunCMake/include_external_msproject/CustomConfig-check-slnx.cmake
  42. 1 1
      Tests/RunCMake/include_external_msproject/CustomConfig-check.cmake
  43. 23 0
      Tests/RunCMake/include_external_msproject/CustomGuid-check-slnx.cmake
  44. 1 1
      Tests/RunCMake/include_external_msproject/CustomGuid-check.cmake
  45. 24 0
      Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check-slnx.cmake
  46. 1 1
      Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check.cmake
  47. 24 0
      Tests/RunCMake/include_external_msproject/CustomTypePlatform-check-slnx.cmake
  48. 1 1
      Tests/RunCMake/include_external_msproject/CustomTypePlatform-check.cmake
  49. 7 0
      Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake

+ 45 - 8
Source/cmGlobalVisualStudio10Generator.cxx

@@ -36,9 +36,29 @@
 #include "cmVersion.h"
 #include "cmVisualStudioSlnData.h"
 #include "cmVisualStudioSlnParser.h"
+#include "cmXMLParser.h"
 #include "cmXMLWriter.h"
 #include "cmake.h"
 
+class cmSlnxParser : public cmXMLParser
+{
+public:
+  std::map<std::string, std::string> ProjectToPath;
+  void StartElement(std::string const& name, char const** atts) override
+  {
+    if (name == "Project"_s) {
+      if (char const* rawPath = this->FindAttribute(atts, "Path")) {
+        std::string path = rawPath;
+        cmSystemTools::ConvertToUnixSlashes(path);
+        std::string nameOnly =
+          cmsys::SystemTools::GetFilenameWithoutLastExtension(path);
+        this->ProjectToPath[cmSystemTools::LowerCase(nameOnly)] = path;
+      }
+    }
+  }
+  void EndElement(std::string const&) override {}
+};
+
 static std::map<std::string, std::vector<cmIDEFlagTable>> loadedFlagJsonFiles;
 
 static void ConvertToWindowsSlashes(std::string& s)
@@ -1079,19 +1099,27 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
 
   // MSBuild is preferred (and required for VS Express), but if the .sln has
   // an Intel Fortran .vfproj then we have to use devenv. Parse it to find out.
+  cmSlnxParser slnxParser;
   cmSlnData slnData;
-  {
+  if (this->Version >= VSVersion::VS18) {
+    if (slnxParser.ParseFile(slnFile.c_str())) {
+      for (auto const& i : slnxParser.ProjectToPath) {
+        if (cmHasLiteralSuffix(i.second, ".vfproj")) {
+          useDevEnv = true;
+          break;
+        }
+      }
+    }
+  } else {
     cmVisualStudioSlnParser parser;
     if (parser.ParseFile(slnFile, slnData,
                          cmVisualStudioSlnParser::DataGroupAll)) {
       std::vector<cmSlnProjectEntry> slnProjects = slnData.GetProjects();
       for (cmSlnProjectEntry const& project : slnProjects) {
-        if (useDevEnv) {
-          break;
-        }
         std::string proj = project.GetRelativePath();
-        if (proj.size() > 7 && proj.substr(proj.size() - 7) == ".vfproj"_s) {
+        if (cmHasLiteralSuffix(proj, ".vfproj")) {
           useDevEnv = true;
+          break;
         }
       }
     }
@@ -1127,9 +1155,18 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
       std::string targetProject = cmStrCat(tname, ".vcxproj");
       if (targetProject.find('/') == std::string::npos) {
         // it might be in a subdir
-        if (cmSlnProjectEntry const* proj = slnData.GetProjectByName(tname)) {
-          targetProject = proj->GetRelativePath();
-          cmSystemTools::ConvertToUnixSlashes(targetProject);
+        if (this->Version >= VSVersion::VS18) {
+          auto i =
+            slnxParser.ProjectToPath.find(cmSystemTools::LowerCase(tname));
+          if (i != slnxParser.ProjectToPath.end()) {
+            targetProject = i->second;
+          }
+        } else {
+          if (cmSlnProjectEntry const* proj =
+                slnData.GetProjectByName(tname)) {
+            targetProject = proj->GetRelativePath();
+            cmSystemTools::ConvertToUnixSlashes(targetProject);
+          }
         }
       }
       makeCommand.Add(targetProject);

+ 24 - 14
Source/cmGlobalVisualStudioGenerator.cxx

@@ -1064,19 +1064,22 @@ cm::VS::Solution cmGlobalVisualStudioGenerator::CreateSolution(
     }
   }
 
-  if (!pgExtensibilityGlobals) {
-    pgExtensibilityGlobals =
-      solution.GetPropertyGroup("ExtensibilityGlobals"_s);
-    solution.PropertyGroups.emplace_back(pgExtensibilityGlobals);
-  }
-  std::string const solutionGuid =
-    this->GetGUID(cmStrCat(root->GetProjectName(), ".sln"));
-  pgExtensibilityGlobals->Map.emplace("SolutionGuid",
-                                      cmStrCat('{', solutionGuid, '}'));
-
-  if (!pgExtensibilityAddIns) {
-    pgExtensibilityAddIns = solution.GetPropertyGroup("ExtensibilityAddIns"_s);
-    solution.PropertyGroups.emplace_back(pgExtensibilityAddIns);
+  if (this->Version <= cm::VS::Version::VS17) {
+    if (!pgExtensibilityGlobals) {
+      pgExtensibilityGlobals =
+        solution.GetPropertyGroup("ExtensibilityGlobals"_s);
+      solution.PropertyGroups.emplace_back(pgExtensibilityGlobals);
+    }
+    std::string const solutionGuid =
+      this->GetGUID(cmStrCat(root->GetProjectName(), ".sln"));
+    pgExtensibilityGlobals->Map.emplace("SolutionGuid",
+                                        cmStrCat('{', solutionGuid, '}'));
+
+    if (!pgExtensibilityAddIns) {
+      pgExtensibilityAddIns =
+        solution.GetPropertyGroup("ExtensibilityAddIns"_s);
+      solution.PropertyGroups.emplace_back(pgExtensibilityAddIns);
+    }
   }
 
   solution.CanonicalizeOrder();
@@ -1099,6 +1102,9 @@ std::string cmGlobalVisualStudioGenerator::GetSLNFile(
     slnFile.push_back('/');
   }
   slnFile = cmStrCat(slnFile, projectName, ".sln");
+  if (this->Version >= cm::VS::Version::VS18) {
+    slnFile += "x";
+  }
   return slnFile;
 }
 
@@ -1162,7 +1168,11 @@ void cmGlobalVisualStudioGenerator::GenerateSolution(
   }
 
   cm::VS::Solution const solution = this->CreateSolution(root, projectTargets);
-  WriteSln(fout, solution);
+  if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS18) {
+    WriteSlnx(fout, solution);
+  } else {
+    WriteSln(fout, solution);
+  }
 
   if (fout.Close()) {
     this->FileReplacedDuringGenerate(fname);

+ 91 - 0
Source/cmVSSolution.cxx

@@ -10,7 +10,9 @@
 #include <cm/string_view>
 #include <cmext/string_view>
 
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmXMLWriter.h"
 
 namespace cm {
 namespace VS {
@@ -279,5 +281,94 @@ void WriteSln(std::ostream& sln, Solution const& solution)
   sln << "EndGlobal\n";
 }
 
+namespace {
+void WriteSlnxSolutionConfigurationPlatforms(cmXMLElement& xmlParent,
+                                             Solution const& solution)
+{
+  cmXMLElement xmlConfigurations(xmlParent, "Configurations");
+  for (std::string const& c : solution.Configs) {
+    cmXMLElement(xmlConfigurations, "BuildType").Attribute("Name", c);
+  }
+  cmXMLElement(xmlConfigurations, "Platform")
+    .Attribute("Name", solution.Platform);
+};
+
+void WriteSlnxProject(cmXMLElement& xmlParent, Solution const& solution,
+                      Solution::Project const& project)
+{
+  cmXMLElement xmlProject(xmlParent, "Project");
+  xmlProject.Attribute("Path", project.Path);
+  xmlProject.Attribute("Id", cmSystemTools::LowerCase(project.Id));
+  for (Solution::Project const* d : project.BuildDependencies) {
+    cmXMLElement(xmlProject, "BuildDependency").Attribute("Project", d->Path);
+  }
+  assert(project.Configs.size() == solution.Configs.size());
+  for (std::size_t i = 0; i < solution.Configs.size(); ++i) {
+    if (project.Configs[i].Config != solution.Configs[i]) {
+      cmXMLElement(xmlProject, "BuildType")
+        .Attribute("Project", project.Configs[i].Config);
+    }
+    if (!project.Configs[i].Build) {
+      cmXMLElement(xmlProject, "Build")
+        .Attribute("Solution", cmStrCat(solution.Configs[i], "|*"))
+        .Attribute("Project", "false");
+    }
+    if (project.Configs[i].Deploy) {
+      cmXMLElement(xmlProject, "Deploy")
+        .Attribute("Solution", cmStrCat(solution.Configs[i], "|*"));
+    }
+  }
+  if (project.Platform != solution.Platform) {
+    cmXMLElement(xmlProject, "Platform")
+      .Attribute("Project", project.Platform);
+  }
+};
+
+void WriteSlnxFolder(cmXMLElement& xmlParent, Solution const& solution,
+                     Solution::Folder const& folder)
+{
+  cmXMLElement xmlFolder(xmlParent, "Folder");
+  xmlFolder.Attribute("Name", cmStrCat('/', folder.Name, '/'));
+  for (std::string const& filePath : folder.Files) {
+    cmXMLElement(xmlFolder, "File").Attribute("Path", filePath);
+  }
+  for (Solution::Project const* project : folder.Projects) {
+    WriteSlnxProject(xmlFolder, solution, *project);
+  }
+};
+
+void WriteSlnxPropertyGroup(cmXMLElement& xmlParent,
+                            Solution::PropertyGroup const& pg)
+{
+  cmXMLElement xmlProperties(xmlParent, "Properties");
+  xmlProperties.Attribute("Name", pg.Name);
+  if (pg.Scope == Solution::PropertyGroup::Load::Post) {
+    xmlProperties.Attribute("Scope", "PostLoad");
+  }
+  for (auto const& i : pg.Map) {
+    cmXMLElement(xmlProperties, "Properties")
+      .Attribute("Name", i.first)
+      .Attribute("Value", i.second);
+  }
+}
+}
+
+void WriteSlnx(std::ostream& slnx, Solution const& solution)
+{
+  cmXMLWriter xw(slnx);
+  cmXMLDocument xml(xw);
+  cmXMLElement xmlSolution(xml, "Solution");
+  WriteSlnxSolutionConfigurationPlatforms(xmlSolution, solution);
+  for (Solution::Project const* project : solution.Projects) {
+    WriteSlnxProject(xmlSolution, solution, *project);
+  }
+  for (Solution::Folder const* folder : solution.Folders) {
+    WriteSlnxFolder(xmlSolution, solution, *folder);
+  }
+  for (Solution::PropertyGroup const* pg : solution.PropertyGroups) {
+    WriteSlnxPropertyGroup(xmlSolution, *pg);
+  }
+}
+
 }
 }

+ 3 - 0
Source/cmVSSolution.h

@@ -165,5 +165,8 @@ private:
 /** Write the .sln-format representation.  */
 void WriteSln(std::ostream& sln, Solution const& solution);
 
+/** Write the .slnx-format representation.  */
+void WriteSlnx(std::ostream& slnx, Solution const& solution);
+
 }
 }

+ 25 - 0
Tests/RunCMake/RunCMake.cmake

@@ -342,6 +342,31 @@ function(ensure_files_match expected_file actual_file)
   endif()
 endfunction()
 
+function(RunCMake_check_file type file expect_content)
+  if(EXISTS "${file}")
+    file(READ "${file}" actual_content)
+    string(REPLACE "\r\n" "\n" actual_content "${actual_content}")
+    string(REGEX REPLACE "\n+$" "" actual_content "${actual_content}")
+    string(REPLACE "\t" "  " actual_content "${actual_content}")
+    if(NOT actual_content MATCHES "${expect_content}")
+      string(REPLACE "\n" "\n expect-${type}> " expect_content " expect-${type}> ${expect_content}")
+      string(REPLACE "\n" "\n actual-${type}> " actual_content " actual-${type}> ${actual_content}")
+      string(APPEND RunCMake_TEST_FAILED "${type} does not match that expected.\n"
+        "Expected ${type} to match:\n${expect_content}\n"
+        "Actual ${type}:\n${actual_content}\n"
+      )
+    endif()
+  else()
+    string(APPEND RunCMake_TEST_FAILED "${type} file does not exist:\n ${file}\n")
+  endif()
+  return(PROPAGATE RunCMake_TEST_FAILED)
+endfunction()
+
+function(RunCMake_check_slnx slnx_file expect_slnx)
+  RunCMake_check_file("slnx" "${slnx_file}" "${expect_slnx}")
+  return(PROPAGATE RunCMake_TEST_FAILED)
+endfunction()
+
 # Get the user id on unix if possible.
 function(get_unix_uid var)
   set("${var}" "" PARENT_SCOPE)

+ 19 - 0
Tests/RunCMake/VSSolution/AddPackageToDefault-check-slnx.cmake

@@ -0,0 +1,19 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/AddPackageToDefault.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+  </Project>
+  <Project Path="PACKAGE.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ALL_BUILD.vcxproj"/>
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/AddPackageToDefault-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/AddPackageToDefault-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/AddPackageToDefault-check-${sln_ext}.cmake)

+ 28 - 0
Tests/RunCMake/VSSolution/CMP0143-NEW-check-slnx.cmake

@@ -0,0 +1,28 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CMP0143-NEW.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="TestStartup\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Folder Name="/CMakePredefinedTargets/">
+    <Project Path="ALL_BUILD.vcxproj" Id="[0-9a-f-]+">
+      <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+      <Build Solution="Debug\|\*" Project="false"/>
+      <Build Solution="Release\|\*" Project="false"/>
+      <Build Solution="MinSizeRel\|\*" Project="false"/>
+      <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+    </Project>
+    <Project Path="ZERO_CHECK.vcxproj" Id="[0-9a-f-]+"/>
+  </Folder>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CMP0143-NEW-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMP0143-NEW-check-${sln_ext}.cmake)

+ 26 - 0
Tests/RunCMake/VSSolution/CMP0143-OLD-check-slnx.cmake

@@ -0,0 +1,26 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CMP0143-OLD.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="TestStartup.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CMP0143-OLD-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMP0143-OLD-check-${sln_ext}.cmake)

+ 26 - 0
Tests/RunCMake/VSSolution/CMP0143-WARN-check-slnx.cmake

@@ -0,0 +1,26 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CMP0143-WARN.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="TestStartup.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CMP0143-WARN-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMP0143-WARN-check-${sln_ext}.cmake)

+ 26 - 0
Tests/RunCMake/VSSolution/DeployEnabled-check-slnx.cmake

@@ -0,0 +1,26 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/DeployEnabled.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <BuildDependency Project="foo\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Project Path="foo\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Deploy Solution="Debug\|\*"/>
+    <Deploy Solution="MinSizeRel\|\*"/>
+    <Deploy Solution="RelWithDebInfo\|\*"/>
+  </Project>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/DeployEnabled-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/DeployEnabled-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/DeployEnabled-check-${sln_ext}.cmake)

+ 28 - 0
Tests/RunCMake/VSSolution/MorePost-check-slnx.cmake

@@ -0,0 +1,28 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/MorePost.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="TestSec2" Scope="PostLoad">
+    <Properties Name="Key1" Value="Value1"/>
+    <Properties Name="Key2" Value="Value with spaces"/>
+  </Properties>
+  <Properties Name="TestSec4" Scope="PostLoad">
+    <Properties Name="Key6" Value="Value1"/>
+    <Properties Name="Key7" Value="Value with spaces"/>
+    <Properties Name="Key8" Value="ValueWithoutSpaces"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/MorePost-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/MorePost-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/MorePost-check-${sln_ext}.cmake)

+ 28 - 0
Tests/RunCMake/VSSolution/MorePre-check-slnx.cmake

@@ -0,0 +1,28 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/MorePre.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="TestSec1">
+    <Properties Name="Key1" Value="Value1"/>
+    <Properties Name="Key2" Value="Value with spaces"/>
+  </Properties>
+  <Properties Name="TestSec3">
+    <Properties Name="Key3" Value="Value1"/>
+    <Properties Name="Key4" Value="Value with spaces"/>
+    <Properties Name="Key5" Value="ValueWithoutSpaces"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/MorePre-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/MorePre-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/MorePre-check-${sln_ext}.cmake)

+ 23 - 0
Tests/RunCMake/VSSolution/OnePost-check-slnx.cmake

@@ -0,0 +1,23 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/OnePost.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="TestSec2" Scope="PostLoad">
+    <Properties Name="Key1" Value="Value1"/>
+    <Properties Name="Key2" Value="Value with spaces"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/OnePost-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/OnePost-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/OnePost-check-${sln_ext}.cmake)

+ 23 - 0
Tests/RunCMake/VSSolution/OnePre-check-slnx.cmake

@@ -0,0 +1,23 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/OnePre.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="TestSec1">
+    <Properties Name="Key1" Value="Value1"/>
+    <Properties Name="Key2" Value="Value with spaces"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/OnePre-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/OnePre-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/OnePre-check-${sln_ext}.cmake)

+ 26 - 0
Tests/RunCMake/VSSolution/Override1-check-slnx.cmake

@@ -0,0 +1,26 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/Override1.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="ExtensibilityGlobals" Scope="PostLoad">
+    <Properties Name="Key1" Value="Value1"/>
+  </Properties>
+  <Properties Name="TestSec" Scope="PostLoad">
+    <Properties Name="Key2" Value="Value2"/>
+    <Properties Name="Key3" Value="Value3"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/Override1-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/Override1-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/Override1-check-${sln_ext}.cmake)

+ 26 - 0
Tests/RunCMake/VSSolution/Override2-check-slnx.cmake

@@ -0,0 +1,26 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/Override2.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="ExtensibilityAddIns" Scope="PostLoad">
+    <Properties Name="Key1" Value="Value1"/>
+  </Properties>
+  <Properties Name="TestSec">
+    <Properties Name="Key2" Value="Value2"/>
+    <Properties Name="Key3" Value="Value3"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/Override2-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/Override2-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/Override2-check-${sln_ext}.cmake)

+ 23 - 0
Tests/RunCMake/VSSolution/Override3-check-slnx.cmake

@@ -0,0 +1,23 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/Override3.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="ExtensibilityGlobals" Scope="PostLoad">
+    <Properties Name="Key1" Value="Value1"/>
+    <Properties Name="SolutionGuid" Value="{custom-guid}"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/Override3-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/Override3-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/Override3-check-${sln_ext}.cmake)

+ 27 - 0
Tests/RunCMake/VSSolution/PrePost-check-slnx.cmake

@@ -0,0 +1,27 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/PrePost.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Properties Name="Emptysec" Scope="PostLoad"/>
+  <Properties Name="Postsec" Scope="PostLoad">
+    <Properties Name="Key1" Value="Value2"/>
+  </Properties>
+  <Properties Name="Presec">
+    <Properties Name="Key1" Value="Value1"/>
+    <Properties Name="Key2" Value="Value with some spaces"/>
+  </Properties>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/PrePost-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/PrePost-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/PrePost-check-${sln_ext}.cmake)

+ 8 - 1
Tests/RunCMake/VSSolution/RunCMakeTest.cmake

@@ -1,5 +1,12 @@
+cmake_minimum_required(VERSION 4.0)
 include(RunCMake)
-include(${CMAKE_CURRENT_LIST_DIR}/solution_parsing.cmake)
+
+if(RunCMake_GENERATOR MATCHES "Visual Studio 1[4-7]")
+  include(${CMAKE_CURRENT_LIST_DIR}/solution_parsing.cmake)
+  set(sln_ext "sln")
+else()
+  set(sln_ext "slnx")
+endif()
 
 run_cmake(DeployEnabled)
 run_cmake(OnePre)

+ 52 - 0
Tests/RunCMake/VSSolution/SolutionItems-check-slnx.cmake

@@ -0,0 +1,52 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/SolutionItems.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Folder Name="/Outer Group/">
+    <File Path="[^"]*/Tests/RunCMake/VSSolution/solution-item-1-1\.txt"/>
+  </Folder>
+  <Folder Name="/Outer Group/Inner Group/">
+    <File Path="[^"]*/Tests/RunCMake/VSSolution/solution-item-2-1\.txt"/>
+    <File Path="[^"]*/Tests/RunCMake/VSSolution/solution-item-2-2\.txt"/>
+  </Folder>
+  <Folder Name="/Solution Items/">
+    <File Path="[^"]*/Tests/RunCMake/VSSolution/solution-item-0-1\.txt"/>
+  </Folder>
+</Solution>$]])
+
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/SolutionItems/SolutionItemsSubproject.slnx" [[
+<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="\.\./ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="\.\./ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Folder Name="/Extraneous/">
+    <File Path="[^"]*/Tests/RunCMake/VSSolution/SolutionItems/extraneous\.txt"/>
+  </Folder>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/SolutionItems-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/SolutionItems-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/SolutionItems-check-${sln_ext}.cmake)

+ 26 - 0
Tests/RunCMake/VSSolution/StartupProject-check-slnx.cmake

@@ -0,0 +1,26 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/StartupProject.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="TestStartup\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/StartupProject-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/StartupProject-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/StartupProject-check-${sln_ext}.cmake)

+ 19 - 0
Tests/RunCMake/VSSolution/StartupProjectMissing-check-slnx.cmake

@@ -0,0 +1,19 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/StartupProjectMissing.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/StartupProjectMissing-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/StartupProjectMissing-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/StartupProjectMissing-check-${sln_ext}.cmake)

+ 28 - 0
Tests/RunCMake/VSSolution/StartupProjectUseFolders-check-slnx.cmake

@@ -0,0 +1,28 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/StartupProjectUseFolders.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="TestStartup\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Folder Name="/CMakePredefinedTargets/">
+    <Project Path="ALL_BUILD.vcxproj" Id="[0-9a-f-]+">
+      <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+      <Build Solution="Debug\|\*" Project="false"/>
+      <Build Solution="Release\|\*" Project="false"/>
+      <Build Solution="MinSizeRel\|\*" Project="false"/>
+      <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+    </Project>
+    <Project Path="ZERO_CHECK.vcxproj" Id="[0-9a-f-]+"/>
+  </Folder>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/VSSolution/StartupProjectUseFolders-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/StartupProjectUseFolders-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/StartupProjectUseFolders-check-${sln_ext}.cmake)

+ 24 - 0
Tests/RunCMake/include_external_msproject/CustomConfig-check-slnx.cmake

@@ -0,0 +1,24 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CustomConfig.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <BuildDependency Project="external.project"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Project Path="external.project" Id="aaa-bbb-ccc-000">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <BuildType Project="Custom - Release"/>
+  </Project>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/include_external_msproject/CustomConfig-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CustomConfig-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CustomConfig-check-${sln_ext}.cmake)

+ 23 - 0
Tests/RunCMake/include_external_msproject/CustomGuid-check-slnx.cmake

@@ -0,0 +1,23 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CustomGuid.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <BuildDependency Project="external.project"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Project Path="external.project" Id="aaa-bbb-ccc-000">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+  </Project>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/include_external_msproject/CustomGuid-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CustomGuid-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CustomGuid-check-${sln_ext}.cmake)

+ 24 - 0
Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check-slnx.cmake

@@ -0,0 +1,24 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CustomGuidTypePlatform.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <BuildDependency Project="external.project"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Project Path="external.project" Id="aaa-bbb-ccc-111">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <Platform Project="Custom Platform"/>
+  </Project>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CustomGuidTypePlatform-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CustomGuidTypePlatform-check-${sln_ext}.cmake)

+ 24 - 0
Tests/RunCMake/include_external_msproject/CustomTypePlatform-check-slnx.cmake

@@ -0,0 +1,24 @@
+RunCMake_check_slnx("${RunCMake_TEST_BINARY_DIR}/CustomTypePlatform.slnx" [[
+^<\?xml version="1\.0" encoding="UTF-8"\?>
+<Solution>
+  <Configurations>
+    <BuildType Name="Debug"/>
+    <BuildType Name="Release"/>
+    <BuildType Name="MinSizeRel"/>
+    <BuildType Name="RelWithDebInfo"/>
+    <Platform Name="[^"]+"/>
+  </Configurations>
+  <Project Path="ALL_BUILD\.vcxproj" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK\.vcxproj"/>
+    <BuildDependency Project="external.project"/>
+    <Build Solution="Debug\|\*" Project="false"/>
+    <Build Solution="Release\|\*" Project="false"/>
+    <Build Solution="MinSizeRel\|\*" Project="false"/>
+    <Build Solution="RelWithDebInfo\|\*" Project="false"/>
+  </Project>
+  <Project Path="ZERO_CHECK\.vcxproj" Id="[0-9a-f-]+"/>
+  <Project Path="external.project" Id="[0-9a-f-]+">
+    <BuildDependency Project="ZERO_CHECK.vcxproj"/>
+    <Platform Project="Custom Platform"/>
+  </Project>
+</Solution>$]])

+ 1 - 1
Tests/RunCMake/include_external_msproject/CustomTypePlatform-check.cmake

@@ -1 +1 @@
-include(${CMAKE_CURRENT_LIST_DIR}/CustomTypePlatform-check-sln.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CustomTypePlatform-check-${sln_ext}.cmake)

+ 7 - 0
Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake

@@ -1,6 +1,13 @@
+cmake_minimum_required(VERSION 4.0)
 include(RunCMake)
 include(${CMAKE_CURRENT_LIST_DIR}/check_utils.cmake)
 
+if(RunCMake_GENERATOR MATCHES "Visual Studio 1[4-7]")
+  set(sln_ext "sln")
+else()
+  set(sln_ext "slnx")
+endif()
+
 run_cmake(CustomGuid)
 run_cmake(CustomTypePlatform)
 run_cmake(CustomGuidTypePlatform)