Merge topic 'custom-command-refactor'

53ea8b3 Merge branch 'imported-target-dependencies' into custom-command-refactor
1a29cca Remove cmLocalGenerator::GetRealLocation
542b517 Factor out common custom command generator
6fe5b3d Simplify VS generator ConstructScript interface
This commit is contained in:
Brad King 2010-12-21 14:03:02 -05:00 committed by CMake Topic Stage
commit 533f5a2037
13 changed files with 137 additions and 144 deletions

View File

@ -131,6 +131,8 @@ SET(SRCS
cmComputeTargetDepends.cxx cmComputeTargetDepends.cxx
cmCustomCommand.cxx cmCustomCommand.cxx
cmCustomCommand.h cmCustomCommand.h
cmCustomCommandGenerator.cxx
cmCustomCommandGenerator.h
cmDefinitions.cxx cmDefinitions.cxx
cmDefinitions.h cmDefinitions.h
cmDepends.cxx cmDepends.cxx

View File

@ -0,0 +1,64 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmCustomCommandGenerator.h"
#include "cmMakefile.h"
#include "cmCustomCommand.h"
#include "cmLocalGenerator.h"
//----------------------------------------------------------------------------
cmCustomCommandGenerator::cmCustomCommandGenerator(
cmCustomCommand const& cc, const char* config, cmMakefile* mf):
CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars())
{
}
//----------------------------------------------------------------------------
unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
{
return static_cast<unsigned int>(this->CC.GetCommandLines().size());
}
//----------------------------------------------------------------------------
std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
cmTarget* target = this->Makefile->FindTargetToUse(argv0.c_str());
if(target && target->GetType() == cmTarget::EXECUTABLE &&
(target->IsImported() || !this->Makefile->IsOn("CMAKE_CROSSCOMPILING")))
{
return target->GetLocation(this->Config);
}
return argv0;
}
//----------------------------------------------------------------------------
void
cmCustomCommandGenerator
::AppendArguments(unsigned int c, std::string& cmd) const
{
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
for(unsigned int j=1;j < commandLine.size(); ++j)
{
std::string const& arg = commandLine[j];
cmd += " ";
if(this->OldStyle)
{
cmd += this->LG->EscapeForShellOldStyle(arg.c_str());
}
else
{
cmd += this->LG->EscapeForShell(arg.c_str(), this->MakeVars);
}
}
}

View File

@ -0,0 +1,37 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmCustomCommandGenerator_h
#define cmCustomCommandGenerator_h
#include "cmStandardIncludes.h"
class cmCustomCommand;
class cmMakefile;
class cmLocalGenerator;
class cmCustomCommandGenerator
{
cmCustomCommand const& CC;
const char* Config;
cmMakefile* Makefile;
cmLocalGenerator* LG;
bool OldStyle;
bool MakeVars;
public:
cmCustomCommandGenerator(cmCustomCommand const& cc, const char* config,
cmMakefile* mf);
unsigned int GetNumberOfCommands() const;
std::string GetCommand(unsigned int c) const;
void AppendArguments(unsigned int c, std::string& cmd) const;
};
#endif

View File

@ -18,6 +18,7 @@
#include "cmGeneratedFileStream.h" #include "cmGeneratedFileStream.h"
#include "cmComputeLinkInformation.h" #include "cmComputeLinkInformation.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmCustomCommandGenerator.h"
#include <cmsys/auto_ptr.hxx> #include <cmsys/auto_ptr.hxx>
@ -1314,8 +1315,7 @@ void cmGlobalXCodeGenerator
cmCustomCommand const& cc = *i; cmCustomCommand const& cc = *i;
if(!cc.GetCommandLines().empty()) if(!cc.GetCommandLines().empty())
{ {
bool escapeOldStyle = cc.GetEscapeOldStyle(); cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars();
makefileStream << "\n"; makefileStream << "\n";
const std::vector<std::string>& outputs = cc.GetOutputs(); const std::vector<std::string>& outputs = cc.GetOutputs();
if(!outputs.empty()) if(!outputs.empty())
@ -1348,20 +1348,15 @@ void cmGlobalXCodeGenerator
{ {
std::string echo_cmd = "echo "; std::string echo_cmd = "echo ";
echo_cmd += (this->CurrentLocalGenerator-> echo_cmd += (this->CurrentLocalGenerator->
EscapeForShell(comment, escapeAllowMakeVars)); EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
makefileStream << "\t" << echo_cmd.c_str() << "\n"; makefileStream << "\t" << echo_cmd.c_str() << "\n";
} }
// Add each command line to the set of commands. // Add each command line to the set of commands.
for(cmCustomCommandLines::const_iterator cl = for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
cc.GetCommandLines().begin();
cl != cc.GetCommandLines().end(); ++cl)
{ {
// Build the command line in a single string. // Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl; std::string cmd2 = ccg.GetCommand(c);
std::string cmd2 = this->CurrentLocalGenerator
->GetRealLocation(commandLine[0].c_str(), configName);
cmSystemTools::ReplaceString(cmd2, "/./", "/"); cmSystemTools::ReplaceString(cmd2, "/./", "/");
cmd2 = this->ConvertToRelativeForMake(cmd2.c_str()); cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
std::string cmd; std::string cmd;
@ -1372,21 +1367,7 @@ void cmGlobalXCodeGenerator
cmd += " && "; cmd += " && ";
} }
cmd += cmd2; cmd += cmd2;
for(unsigned int j=1; j < commandLine.size(); ++j) ccg.AppendArguments(c, cmd);
{
cmd += " ";
if(escapeOldStyle)
{
cmd += (this->CurrentLocalGenerator
->EscapeForShellOldStyle(commandLine[j].c_str()));
}
else
{
cmd += (this->CurrentLocalGenerator->
EscapeForShell(commandLine[j].c_str(),
escapeAllowMakeVars));
}
}
makefileStream << "\t" << cmd.c_str() << "\n"; makefileStream << "\t" << cmd.c_str() << "\n";
} }
} }

View File

@ -1912,24 +1912,6 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
return true; return true;
} }
//----------------------------------------------------------------------------
std::string cmLocalGenerator::GetRealLocation(const char* inName,
const char* config)
{
std::string outName=inName;
// Look for a CMake target with the given name, which is an executable
// and which can be run
cmTarget* target = this->Makefile->FindTargetToUse(inName);
if ((target != 0)
&& (target->GetType() == cmTarget::EXECUTABLE)
&& ((this->Makefile->IsOn("CMAKE_CROSSCOMPILING") == false)
|| (target->IsImported() == true)))
{
outName = target->GetLocation( config );
}
return outName;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmLocalGenerator::AddSharedFlags(std::string& flags, void cmLocalGenerator::AddSharedFlags(std::string& flags,
const char* lang, const char* lang,

View File

@ -168,11 +168,6 @@ public:
bool GetRealDependency(const char* name, const char* config, bool GetRealDependency(const char* name, const char* config,
std::string& dep); std::string& dep);
/** Translate a command as given in CMake code to the location of the
executable if the command is the name of a CMake executable target.
If that's not the case, just return the original name. */
std::string GetRealLocation(const char* inName, const char* config);
///! for existing files convert to output path and short path if spaces ///! for existing files convert to output path and short path if spaces
std::string ConvertToOutputForExisting(const char* remote, std::string ConvertToOutputForExisting(const char* remote,
RelativeRoot local = START_OUTPUT); RelativeRoot local = START_OUTPUT);

View File

@ -19,6 +19,7 @@
#include "cmake.h" #include "cmake.h"
#include "cmVersion.h" #include "cmVersion.h"
#include "cmFileTimeComparison.h" #include "cmFileTimeComparison.h"
#include "cmCustomCommandGenerator.h"
// Include dependency scanners for supported languages. Only the // Include dependency scanners for supported languages. Only the
// C/C++ scanner is needed for bootstrapping CMake. // C/C++ scanner is needed for bootstrapping CMake.
@ -961,18 +962,15 @@ cmLocalUnixMakefileGenerator3
{ {
*content << dir; *content << dir;
} }
bool escapeOldStyle = cc.GetEscapeOldStyle(); cmCustomCommandGenerator ccg(cc, this->ConfigurationName.c_str(),
bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars(); this->Makefile);
// Add each command line to the set of commands. // Add each command line to the set of commands.
std::vector<std::string> commands1; std::vector<std::string> commands1;
for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin(); for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
cl != cc.GetCommandLines().end(); ++cl)
{ {
// Build the command line in a single string. // Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl; std::string cmd = ccg.GetCommand(c);
std::string cmd = GetRealLocation(commandLine[0].c_str(),
this->ConfigurationName.c_str());
if (cmd.size()) if (cmd.size())
{ {
// Use "call " before any invocations of .bat or .cmd files // Use "call " before any invocations of .bat or .cmd files
@ -1025,19 +1023,8 @@ cmLocalUnixMakefileGenerator3
std::string launcher = std::string launcher =
this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT); this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT);
cmd = launcher + this->Convert(cmd.c_str(),NONE,SHELL); cmd = launcher + this->Convert(cmd.c_str(),NONE,SHELL);
for(unsigned int j=1; j < commandLine.size(); ++j)
{ ccg.AppendArguments(c, cmd);
cmd += " ";
if(escapeOldStyle)
{
cmd += this->EscapeForShellOldStyle(commandLine[j].c_str());
}
else
{
cmd += this->EscapeForShell(commandLine[j].c_str(),
escapeAllowMakeVars);
}
}
if(content) if(content)
{ {
// Rule content does not include the launcher. // Rule content does not include the launcher.

View File

@ -65,13 +65,7 @@ public:
{ {
this->Code += "\\\n\t"; this->Code += "\\\n\t";
} }
this->Code += this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t");
this->LG->ConstructScript(cc.GetCommandLines(),
cc.GetWorkingDirectory(),
this->Config,
cc.GetEscapeOldStyle(),
cc.GetEscapeAllowMakeVars(),
"\\\n\t");
} }
private: private:
cmLocalVisualStudio6Generator* LG; cmLocalVisualStudio6Generator* LG;
@ -659,12 +653,7 @@ cmLocalVisualStudio6Generator
{ {
std::string config = this->GetConfigName(*i); std::string config = this->GetConfigName(*i);
std::string script = std::string script =
this->ConstructScript(command.GetCommandLines(), this->ConstructScript(command, config.c_str(), "\\\n\t");
command.GetWorkingDirectory(),
config.c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars(),
"\\\n\t");
if (i == this->Configurations.begin()) if (i == this->Configurations.begin())
{ {

View File

@ -546,12 +546,7 @@ public:
{ {
this->Stream << this->LG->EscapeForXML("\n"); this->Stream << this->LG->EscapeForXML("\n");
} }
std::string script = std::string script = this->LG->ConstructScript(cc, this->Config);
this->LG->ConstructScript(cc.GetCommandLines(),
cc.GetWorkingDirectory(),
this->Config,
cc.GetEscapeOldStyle(),
cc.GetEscapeAllowMakeVars());
this->Stream << this->LG->EscapeForXML(script.c_str()); this->Stream << this->LG->EscapeForXML(script.c_str());
} }
private: private:
@ -1591,12 +1586,7 @@ WriteCustomRule(std::ostream& fout,
<< this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n"; << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
} }
std::string script = std::string script = this->ConstructScript(command, i->c_str());
this->ConstructScript(command.GetCommandLines(),
command.GetWorkingDirectory(),
i->c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars());
fout << "\t\t\t\t\t<Tool\n" fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << customTool << "\"\n" << "\t\t\t\t\tName=\"" << customTool << "\"\n"
<< "\t\t\t\t\tDescription=\"" << "\t\t\t\t\tDescription=\""

View File

@ -14,6 +14,7 @@
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmCustomCommandGenerator.h"
#include "windows.h" #include "windows.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -163,13 +164,15 @@ std::string cmLocalVisualStudioGenerator::GetCheckForErrorLine()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string std::string
cmLocalVisualStudioGenerator cmLocalVisualStudioGenerator
::ConstructScript(const cmCustomCommandLines& commandLines, ::ConstructScript(cmCustomCommand const& cc,
const char* workingDirectory,
const char* configName, const char* configName,
bool escapeOldStyle,
bool escapeAllowMakeVars,
const char* newline_text) const char* newline_text)
{ {
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. // Avoid leading or trailing newlines.
const char* newline = ""; const char* newline = "";
@ -208,40 +211,16 @@ cmLocalVisualStudioGenerator
} }
} }
// Write each command on a single line. // Write each command on a single line.
for(cmCustomCommandLines::const_iterator cl = commandLines.begin(); for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
cl != commandLines.end(); ++cl)
{ {
// Start a new line. // Start a new line.
script += newline; script += newline;
newline = newline_text; newline = newline_text;
// Start with the command name. // Add this command line.
const cmCustomCommandLine& commandLine = *cl; std::string cmd = ccg.GetCommand(c);
std::string commandName = this->GetRealLocation(commandLine[0].c_str(), script += this->Convert(cmd.c_str(), relativeRoot, SHELL);
configName); ccg.AppendArguments(c, script);
if(!workingDirectory)
{
script += this->Convert(commandName.c_str(),START_OUTPUT,SHELL);
}
else
{
script += this->Convert(commandName.c_str(),NONE,SHELL);
}
// Add the arguments.
for(unsigned int j=1;j < commandLine.size(); ++j)
{
script += " ";
if(escapeOldStyle)
{
script += this->EscapeForShellOldStyle(commandLine[j].c_str());
}
else
{
script += this->EscapeForShell(commandLine[j].c_str(),
escapeAllowMakeVars);
}
}
// After each custom command, check for an error result. // After each custom command, check for an error result.
// If there was an error, jump to the VCReportError label, // If there was an error, jump to the VCReportError label,

View File

@ -18,6 +18,7 @@
class cmSourceFile; class cmSourceFile;
class cmSourceGroup; class cmSourceGroup;
class cmCustomCommand;
/** \class cmLocalVisualStudioGenerator /** \class cmLocalVisualStudioGenerator
* \brief Base class for Visual Studio generators. * \brief Base class for Visual Studio generators.
@ -32,11 +33,8 @@ public:
virtual ~cmLocalVisualStudioGenerator(); virtual ~cmLocalVisualStudioGenerator();
/** Construct a script from the given list of command lines. */ /** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines, std::string ConstructScript(cmCustomCommand const& cc,
const char* workingDirectory,
const char* configName, const char* configName,
bool escapeOldStyle,
bool escapeAllowMakeVars,
const char* newline = "\n"); const char* newline = "\n");
/** Line of batch file text that skips to the end after /** Line of batch file text that skips to the end after

View File

@ -376,13 +376,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
i != configs->end(); ++i) i != configs->end(); ++i)
{ {
std::string script = std::string script =
cmVS10EscapeXML( cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
lg->ConstructScript(command.GetCommandLines(),
command.GetWorkingDirectory(),
i->c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars())
);
this->WritePlatformConfigTag("Message",i->c_str(), 3); this->WritePlatformConfigTag("Message",i->c_str(), 3);
(*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n"; (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
this->WritePlatformConfigTag("Command", i->c_str(), 3); this->WritePlatformConfigTag("Command", i->c_str(), 3);
@ -1469,13 +1463,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
script += pre; script += pre;
pre = "\n"; pre = "\n";
script += script +=
cmVS10EscapeXML( cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
lg->ConstructScript(command.GetCommandLines(),
command.GetWorkingDirectory(),
configName.c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars())
);
} }
comment = cmVS10EscapeComment(comment); comment = cmVS10EscapeComment(comment);
this->WriteString("<Message>",3); this->WriteString("<Message>",3);

View File

@ -215,6 +215,7 @@ CMAKE_CXX_SOURCES="\
cmTarget \ cmTarget \
cmTest \ cmTest \
cmCustomCommand \ cmCustomCommand \
cmCustomCommandGenerator \
cmDocumentVariables \ cmDocumentVariables \
cmCacheManager \ cmCacheManager \
cmListFileCache \ cmListFileCache \