Răsfoiți Sursa

Merge topic 'fix-vsmacro-access-violation'

7847fef510 VS: Fix access violation when calling Visual Studio macro

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3853
Brad King 6 ani în urmă
părinte
comite
a29b8d285e

+ 13 - 4
Source/cmGlobalVisualStudio7Generator.cxx

@@ -45,6 +45,14 @@ static cmVS7FlagTable cmVS7ExtraFlagTable[] = {
   { "", "", "", "", 0 }
 };
 
+namespace {
+std::string GetSLNFile(cmLocalGenerator* root)
+{
+  return cmStrCat(root->GetCurrentBinaryDirectory(), '/',
+                  root->GetProjectName(), ".sln");
+}
+}
+
 cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
   cmake* cm, std::string const& platformInGeneratorName)
   : cmGlobalVisualStudioGenerator(cm, platformInGeneratorName)
@@ -286,8 +294,10 @@ void cmGlobalVisualStudio7Generator::Generate()
   this->OutputSLNFile();
   // If any solution or project files changed during the generation,
   // tell Visual Studio to reload them...
-  if (!cmSystemTools::GetErrorOccuredFlag()) {
-    this->CallVisualStudioMacro(MacroReload);
+  if (!cmSystemTools::GetErrorOccuredFlag() &&
+      !this->LocalGenerators.empty()) {
+    this->CallVisualStudioMacro(MacroReload,
+                                GetSLNFile(this->LocalGenerators[0]));
   }
 }
 
@@ -298,8 +308,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile(
     return;
   }
   this->CurrentProject = root->GetProjectName();
-  std::string fname = cmStrCat(root->GetCurrentBinaryDirectory(), '/',
-                               root->GetProjectName(), ".sln");
+  std::string fname = GetSLNFile(root);
   cmGeneratedFileStream fout(fname.c_str());
   fout.SetCopyIfDifferent(true);
   if (!fout) {

+ 3 - 13
Source/cmGlobalVisualStudioGenerator.cxx

@@ -288,11 +288,10 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
 }
 
 void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
-  MacroName m, const char* vsSolutionFile)
+  MacroName m, const std::string& vsSolutionFile)
 {
   // If any solution or project files changed during the generation,
   // tell Visual Studio to reload them...
-  cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
   std::string dir = this->GetUserMacrosDirectory();
 
   // Only really try to call the macro if:
@@ -307,27 +306,18 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
     if (cmSystemTools::FileExists(macrosFile.c_str()) &&
         IsVisualStudioMacrosFileRegistered(
           macrosFile, this->GetUserMacrosRegKeyBase(), nextSubkeyName)) {
-      std::string topLevelSlnName;
-      if (vsSolutionFile) {
-        topLevelSlnName = vsSolutionFile;
-      } else {
-        topLevelSlnName =
-          cmStrCat(mf->GetCurrentBinaryDirectory(), '/',
-                   this->LocalGenerators[0]->GetProjectName(), ".sln");
-      }
-
       if (m == MacroReload) {
         std::vector<std::string> filenames;
         this->GetFilesReplacedDuringGenerate(filenames);
         if (!filenames.empty()) {
           std::string projects = cmJoin(filenames, ";");
           cmCallVisualStudioMacro::CallMacro(
-            topLevelSlnName, CMAKE_VSMACROS_RELOAD_MACRONAME, projects,
+            vsSolutionFile, CMAKE_VSMACROS_RELOAD_MACRONAME, projects,
             this->GetCMakeInstance()->GetDebugOutput());
         }
       } else if (m == MacroStop) {
         cmCallVisualStudioMacro::CallMacro(
-          topLevelSlnName, CMAKE_VSMACROS_STOP_MACRONAME, "",
+          vsSolutionFile, CMAKE_VSMACROS_STOP_MACRONAME, "",
           this->GetCMakeInstance()->GetDebugOutput());
       }
     }

+ 1 - 1
Source/cmGlobalVisualStudioGenerator.h

@@ -90,7 +90,7 @@ public:
    * Call the ReloadProjects macro if necessary based on
    * GetFilesReplacedDuringGenerate results.
    */
-  void CallVisualStudioMacro(MacroName m, const char* vsSolutionFile = 0);
+  void CallVisualStudioMacro(MacroName m, const std::string& vsSolutionFile);
 
   // return true if target is fortran only
   bool TargetIsFortranOnly(const cmGeneratorTarget* gt);

+ 1 - 1
Source/cmake.cxx

@@ -1751,7 +1751,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
       cmGlobalVisualStudioGenerator* gg =
         static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
       gg->CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
-                                this->VSSolutionFile.c_str());
+                                this->VSSolutionFile);
     }
 #endif
     return ret;

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -167,7 +167,7 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(CompilerChange)
 endif()
 add_RunCMake_test(CompilerNotFound)
-add_RunCMake_test(Configure)
+add_RunCMake_test(Configure -DMSVC_IDE=${MSVC_IDE})
 add_RunCMake_test(DisallowedCommands)
 add_RunCMake_test(ExternalData)
 add_RunCMake_test(FeatureSummary)

+ 1 - 0
Tests/RunCMake/Configure/RerunCMake-build3-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/Configure/RerunCMake-build3-stdout.txt

@@ -0,0 +1 @@
+Rerun error 3

+ 1 - 0
Tests/RunCMake/Configure/RerunCMake-build4-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/Configure/RerunCMake-build4-stdout.txt

@@ -0,0 +1 @@
+Rerun error 4

+ 6 - 0
Tests/RunCMake/Configure/RerunCMake.cmake

@@ -9,3 +9,9 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${depend})
 file(READ ${depend} content)
 file(WRITE ${output} "${content}")
 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS RerunCMake.txt)
+
+set(error  ${CMAKE_CURRENT_BINARY_DIR}/CustomCMakeError.txt)
+if(EXISTS ${error})
+  file(READ ${error} content)
+  message(FATAL_ERROR "Rerun error ${content}")
+endif()

+ 17 - 0
Tests/RunCMake/Configure/RunCMakeTest.cmake

@@ -14,6 +14,7 @@ set(input  "${RunCMake_TEST_BINARY_DIR}/CustomCMakeInput.txt")
 set(stamp  "${RunCMake_TEST_BINARY_DIR}/CustomCMakeStamp.txt")
 set(depend "${RunCMake_TEST_BINARY_DIR}/CustomCMakeDepend.txt")
 set(output "${RunCMake_TEST_BINARY_DIR}/CustomCMakeOutput.txt")
+set(error  "${RunCMake_TEST_BINARY_DIR}/CustomCMakeError.txt")
 file(WRITE "${input}" "1")
 file(WRITE "${depend}" "1")
 run_cmake(RerunCMake)
@@ -22,6 +23,22 @@ file(WRITE "${input}" "2")
 run_cmake_command(RerunCMake-build1 ${CMAKE_COMMAND} --build .)
 file(WRITE "${depend}" "2")
 run_cmake_command(RerunCMake-build2 ${CMAKE_COMMAND} --build .)
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
+file(WRITE "${depend}" "3")
+file(WRITE "${error}" "3")
+set(RunCMake_TEST_OUTPUT_MERGE 1)
+run_cmake_command(RerunCMake-build3 ${CMAKE_COMMAND} --build .)
+if(MSVC_IDE)
+  # Make sure that for Visual Studio the error occurs from within the build
+  # system.
+  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/generate.stamp.list")
+  file(WRITE "${error}" "4")
+  # With Visual Studio the error must be on stdout, otherwise the error was not
+  # emitted by ZERO_CHECK.
+  set(RunCMake_TEST_OUTPUT_MERGE 0)
+  run_cmake_command(RerunCMake-build4 ${CMAKE_COMMAND} --build .)
+endif()
+unset(RunCMake_TEST_OUTPUT_MERGE)
 unset(RunCMake_TEST_BINARY_DIR)
 unset(RunCMake_TEST_NO_CLEAN)