diff options
author | Brad King <brad.king@kitware.com> | 2011-04-08 14:40:57 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2011-04-08 19:36:16 (GMT) |
commit | 06fcbc4757c7a52733a554d4050735452d49a5e7 (patch) | |
tree | ec735575eb956a5a5ea873b87e0e43ea6c73168d | |
parent | a961ecdad0ec31bacb3f6abff83aa65f0b51a676 (diff) | |
download | CMake-06fcbc4757c7a52733a554d4050735452d49a5e7.zip CMake-06fcbc4757c7a52733a554d4050735452d49a5e7.tar.gz CMake-06fcbc4757c7a52733a554d4050735452d49a5e7.tar.bz2 |
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.
-rw-r--r-- | Source/cmLocalVisualStudio10Generator.cxx | 4 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio10Generator.h | 2 | ||||
-rw-r--r-- | Source/cmLocalVisualStudioGenerator.cxx | 42 | ||||
-rw-r--r-- | Source/cmLocalVisualStudioGenerator.h | 9 |
4 files changed, 35 insertions, 22 deletions
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index de2a837..1850c16 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -119,7 +119,7 @@ void cmLocalVisualStudio10Generator } //---------------------------------------------------------------------------- -std::string cmLocalVisualStudio10Generator::CheckForErrorLine() +const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const { - return "if errorlevel 1 goto :VCEnd"; + return ":VCEnd"; } diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h index 06b8b09..2330432 100644 --- a/Source/cmLocalVisualStudio10Generator.h +++ b/Source/cmLocalVisualStudio10Generator.h @@ -38,7 +38,7 @@ public: const char* path); protected: - virtual std::string CheckForErrorLine(); + virtual const char* ReportErrorLabel() const; private: }; diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 39f9962..b2057b8 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -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; } diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index 22112b3..278291e 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h @@ -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> |