VS10: Fix working directory of consecutive custom commands (#11938)
The VS 10 msbuild tool uses a single command shell to invoke all the custom command scripts in a project. Isolate the environment and working directory of custom commands using setlocal/endlocal. The form of each command is set errlev= setlocal cd c:\work\dir if %errorlevel% neq 0 goto :cmEnd c: if %errorlevel% neq 0 goto :cmEnd command1 ... if %errorlevel% neq 0 goto :cmEnd ... commandN ... if %errorlevel% neq 0 goto :cmEnd :cmEnd endlocal & set errlev=%errorlevel% if %errlev% neq 0 goto :VCEnd so that all changes to the environment and working directory are isolated within the script and the return code is preserved.
This commit is contained in:
parent
a961ecdad0
commit
06fcbc4757
|
@ -119,7 +119,7 @@ void cmLocalVisualStudio10Generator
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmLocalVisualStudio10Generator::CheckForErrorLine()
|
||||
const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
|
||||
{
|
||||
return "if errorlevel 1 goto :VCEnd";
|
||||
return ":VCEnd";
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
const char* path);
|
||||
|
||||
protected:
|
||||
virtual std::string CheckForErrorLine();
|
||||
virtual const char* ReportErrorLabel() const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -154,15 +154,15 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmLocalVisualStudioGenerator::CheckForErrorLine()
|
||||
const char* cmLocalVisualStudioGenerator::ReportErrorLabel() const
|
||||
{
|
||||
return "if errorlevel 1 goto :VCReportError";
|
||||
return ":VCReportError";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmLocalVisualStudioGenerator::GetCheckForErrorLine()
|
||||
const char* cmLocalVisualStudioGenerator::GetReportErrorLabel() const
|
||||
{
|
||||
return this->CheckForErrorLine();
|
||||
return this->ReportErrorLabel();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -170,35 +170,43 @@ std::string
|
|||
cmLocalVisualStudioGenerator
|
||||
::ConstructScript(cmCustomCommand const& cc,
|
||||
const char* configName,
|
||||
const char* newline_text)
|
||||
const char* newline)
|
||||
{
|
||||
const cmCustomCommandLines& commandLines = cc.GetCommandLines();
|
||||
const char* workingDirectory = cc.GetWorkingDirectory();
|
||||
cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
|
||||
RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT;
|
||||
|
||||
// Avoid leading or trailing newlines.
|
||||
const char* newline = "";
|
||||
// Line to check for error between commands.
|
||||
std::string check_error = newline;
|
||||
check_error += "if %errorlevel% neq 0 goto :cmEnd";
|
||||
|
||||
// Store the script in a string.
|
||||
std::string script;
|
||||
|
||||
// Open a local context.
|
||||
script += "set errlev=";
|
||||
script += newline;
|
||||
script += "setlocal";
|
||||
|
||||
if(workingDirectory)
|
||||
{
|
||||
// Change the working directory.
|
||||
script += newline;
|
||||
newline = newline_text;
|
||||
script += "cd ";
|
||||
script += this->Convert(workingDirectory, FULL, SHELL);
|
||||
script += check_error;
|
||||
|
||||
// Change the working drive.
|
||||
if(workingDirectory[0] && workingDirectory[1] == ':')
|
||||
{
|
||||
script += newline;
|
||||
newline = newline_text;
|
||||
script += workingDirectory[0];
|
||||
script += workingDirectory[1];
|
||||
script += check_error;
|
||||
}
|
||||
}
|
||||
|
||||
// for visual studio IDE add extra stuff to the PATH
|
||||
// if CMAKE_MSVCIDE_RUN_PATH is set.
|
||||
if(this->Makefile->GetDefinition("MSVC_IDE"))
|
||||
|
@ -208,18 +216,17 @@ cmLocalVisualStudioGenerator
|
|||
if(extraPath)
|
||||
{
|
||||
script += newline;
|
||||
newline = newline_text;
|
||||
script += "set PATH=";
|
||||
script += extraPath;
|
||||
script += ";%PATH%";
|
||||
}
|
||||
}
|
||||
|
||||
// Write each command on a single line.
|
||||
for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
|
||||
{
|
||||
// Start a new line.
|
||||
script += newline;
|
||||
newline = newline_text;
|
||||
|
||||
// Add this command line.
|
||||
std::string cmd = ccg.GetCommand(c);
|
||||
|
@ -230,10 +237,17 @@ cmLocalVisualStudioGenerator
|
|||
// If there was an error, jump to the VCReportError label,
|
||||
// skipping the run of any subsequent commands in this
|
||||
// sequence.
|
||||
//
|
||||
script += newline_text;
|
||||
script += this->GetCheckForErrorLine();
|
||||
script += check_error;
|
||||
}
|
||||
|
||||
// Close the local context.
|
||||
script += newline;
|
||||
script += ":cmEnd";
|
||||
script += newline;
|
||||
script += "endlocal & set errlev=%errorlevel%";
|
||||
script += newline;
|
||||
script += "if %errlev% neq 0 goto ";
|
||||
script += this->GetReportErrorLabel();
|
||||
|
||||
return script;
|
||||
}
|
||||
|
|
|
@ -37,13 +37,12 @@ public:
|
|||
const char* configName,
|
||||
const char* newline = "\n");
|
||||
|
||||
/** Line of batch file text that skips to the end after
|
||||
* a failed step in a sequence of custom commands.
|
||||
*/
|
||||
std::string GetCheckForErrorLine();
|
||||
/** Label to which to jump in a batch file after a failed step in a
|
||||
sequence of custom commands. */
|
||||
const char* GetReportErrorLabel() const;
|
||||
|
||||
protected:
|
||||
virtual std::string CheckForErrorLine();
|
||||
virtual const char* ReportErrorLabel() const;
|
||||
|
||||
/** Construct a custom command to make exe import lib dir. */
|
||||
cmsys::auto_ptr<cmCustomCommand>
|
||||
|
|
Loading…
Reference in New Issue