mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-15 12:16:40 +08:00
VS: Fix access violation when calling Visual Studio macro
Fixes: #19730
This commit is contained in:
@@ -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) {
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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
Tests/RunCMake/Configure/RerunCMake-build3-result.txt
Normal file
1
Tests/RunCMake/Configure/RerunCMake-build3-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
[^0]
|
1
Tests/RunCMake/Configure/RerunCMake-build3-stdout.txt
Normal file
1
Tests/RunCMake/Configure/RerunCMake-build3-stdout.txt
Normal file
@@ -0,0 +1 @@
|
||||
Rerun error 3
|
1
Tests/RunCMake/Configure/RerunCMake-build4-result.txt
Normal file
1
Tests/RunCMake/Configure/RerunCMake-build4-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
[^0]
|
1
Tests/RunCMake/Configure/RerunCMake-build4-stdout.txt
Normal file
1
Tests/RunCMake/Configure/RerunCMake-build4-stdout.txt
Normal file
@@ -0,0 +1 @@
|
||||
Rerun error 4
|
@@ -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()
|
||||
|
@@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user