1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-16 05:26:58 +08:00

VS: Fix access violation when calling Visual Studio macro

Fixes: #19730
This commit is contained in:
Daniel Eiband
2019-09-22 17:55:12 +02:00
parent ebb9346490
commit 7847fef510
11 changed files with 46 additions and 20 deletions

View File

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

View File

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

View File

@@ -90,7 +90,7 @@ public:
* Call the ReloadProjects macro if necessary based on * Call the ReloadProjects macro if necessary based on
* GetFilesReplacedDuringGenerate results. * 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 // return true if target is fortran only
bool TargetIsFortranOnly(const cmGeneratorTarget* gt); bool TargetIsFortranOnly(const cmGeneratorTarget* gt);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,3 +9,9 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${depend})
file(READ ${depend} content) file(READ ${depend} content)
file(WRITE ${output} "${content}") file(WRITE ${output} "${content}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS RerunCMake.txt) 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()

View File

@@ -14,6 +14,7 @@ set(input "${RunCMake_TEST_BINARY_DIR}/CustomCMakeInput.txt")
set(stamp "${RunCMake_TEST_BINARY_DIR}/CustomCMakeStamp.txt") set(stamp "${RunCMake_TEST_BINARY_DIR}/CustomCMakeStamp.txt")
set(depend "${RunCMake_TEST_BINARY_DIR}/CustomCMakeDepend.txt") set(depend "${RunCMake_TEST_BINARY_DIR}/CustomCMakeDepend.txt")
set(output "${RunCMake_TEST_BINARY_DIR}/CustomCMakeOutput.txt") set(output "${RunCMake_TEST_BINARY_DIR}/CustomCMakeOutput.txt")
set(error "${RunCMake_TEST_BINARY_DIR}/CustomCMakeError.txt")
file(WRITE "${input}" "1") file(WRITE "${input}" "1")
file(WRITE "${depend}" "1") file(WRITE "${depend}" "1")
run_cmake(RerunCMake) run_cmake(RerunCMake)
@@ -22,6 +23,22 @@ file(WRITE "${input}" "2")
run_cmake_command(RerunCMake-build1 ${CMAKE_COMMAND} --build .) run_cmake_command(RerunCMake-build1 ${CMAKE_COMMAND} --build .)
file(WRITE "${depend}" "2") file(WRITE "${depend}" "2")
run_cmake_command(RerunCMake-build2 ${CMAKE_COMMAND} --build .) 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_BINARY_DIR)
unset(RunCMake_TEST_NO_CLEAN) unset(RunCMake_TEST_NO_CLEAN)