summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2011-04-08 14:40:57 (GMT)
committerBrad King <brad.king@kitware.com>2011-04-08 19:36:16 (GMT)
commit06fcbc4757c7a52733a554d4050735452d49a5e7 (patch)
treeec735575eb956a5a5ea873b87e0e43ea6c73168d /Source
parenta961ecdad0ec31bacb3f6abff83aa65f0b51a676 (diff)
downloadCMake-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.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx4
-rw-r--r--Source/cmLocalVisualStudio10Generator.h2
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx42
-rw-r--r--Source/cmLocalVisualStudioGenerator.h9
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>