ENH: Updated implementation of custom commands. Multiple command lines are now supported effectively allowing entire scripts to be written. Also removed extra variable expansions and cleaned up passing of commands through to the generators. The command and individual arguments are now kept separate all the way until the generator writes them out. This cleans up alot of escaping issues.

This commit is contained in:
Brad King 2005-02-22 10:32:44 -05:00
parent 4d30cb309c
commit 39af9ee1e4
27 changed files with 938 additions and 945 deletions

View File

@ -15,6 +15,7 @@
=========================================================================*/ =========================================================================*/
#include "cmAddCustomCommandCommand.h" #include "cmAddCustomCommandCommand.h"
#include "cmTarget.h" #include "cmTarget.h"
// cmAddCustomCommandCommand // cmAddCustomCommandCommand
@ -30,8 +31,14 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
return false; return false;
} }
std::string source, command, target, comment, output, main_dependency; std::string source, target, comment, output, main_dependency;
std::vector<std::string> command_args, depends, outputs; std::vector<std::string> depends, outputs;
// Accumulate one command line at a time.
cmCustomCommandLine currentLine;
// Save all command lines.
cmCustomCommandLines commandLines;
cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD; cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
@ -39,7 +46,6 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
doing_source, doing_source,
doing_command, doing_command,
doing_target, doing_target,
doing_args,
doing_depends, doing_depends,
doing_main_dependency, doing_main_dependency,
doing_output, doing_output,
@ -61,6 +67,13 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
else if(copy == "COMMAND") else if(copy == "COMMAND")
{ {
doing = doing_command; doing = doing_command;
// Save the current command before starting the next command.
if(!currentLine.empty())
{
commandLines.push_back(currentLine);
currentLine.clear();
}
} }
else if(copy == "PRE_BUILD") else if(copy == "PRE_BUILD")
{ {
@ -80,7 +93,7 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
} }
else if(copy == "ARGS") else if(copy == "ARGS")
{ {
doing = doing_args; // Ignore this old keyword.
} }
else if (copy == "DEPENDS") else if (copy == "DEPENDS")
{ {
@ -116,14 +129,11 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
main_dependency = copy; main_dependency = copy;
break; break;
case doing_command: case doing_command:
command = copy; currentLine.push_back(copy);
break; break;
case doing_target: case doing_target:
target = copy; target = copy;
break; break;
case doing_args:
command_args.push_back(copy);
break;
case doing_depends: case doing_depends:
depends.push_back(copy); depends.push_back(copy);
break; break;
@ -140,58 +150,49 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
} }
} }
/* At this point we could complain about the lack of arguments. // Store the last command line finished.
For the moment, let's say that COMMAND, TARGET are always if(!currentLine.empty())
required. {
*/ commandLines.push_back(currentLine);
if (output.empty() && target.empty()) currentLine.clear();
}
// At this point we could complain about the lack of arguments. For
// the moment, let's say that COMMAND, TARGET are always required.
if(output.empty() && target.empty())
{ {
this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified."); this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
return false; return false;
} }
if (source.empty() if(source.empty() && !target.empty() && !output.empty())
&& !target.empty()
&& !output.empty())
{ {
this->SetError("Wrong syntax. A TARGET and OUTPUT can not both be specified."); this->SetError("Wrong syntax. A TARGET and OUTPUT can not both be specified.");
return false; return false;
} }
// If source is empty, use the target // Choose which mode of the command to use.
if(source.empty() && output.empty()) if(source.empty() && output.empty())
{ {
m_Makefile->AddCustomCommandToTarget(target.c_str(), // Source is empty, use the target.
command.c_str(), std::vector<std::string> no_depends;
command_args, m_Makefile->AddCustomCommandToTarget(target.c_str(), no_depends,
cctype, commandLines, cctype,
comment.c_str()); comment.c_str());
return true;
} }
else if(target.empty())
// If target is empty, use the output
if(target.empty())
{ {
m_Makefile->AddCustomCommandToOutput(output.c_str(), // Target is empty, use the output.
command.c_str(), m_Makefile->AddCustomCommandToOutput(output.c_str(), depends,
command_args,
main_dependency.c_str(), main_dependency.c_str(),
depends, commandLines, comment.c_str());
comment.c_str()); }
return true; else
{
// Use the old-style mode for backward compatibility.
m_Makefile->AddCustomCommandOldStyle(target.c_str(), outputs, depends,
source.c_str(), commandLines,
comment.c_str());
} }
// otherwise backwards compatiblity mode
m_Makefile->AddCustomCommand(source.c_str(),
command.c_str(),
command_args,
depends,
outputs,
target.c_str(),
comment.c_str());
return true; return true;
} }

View File

@ -65,10 +65,10 @@ public:
return return
"There are two main signatures for ADD_CUSTOM_COMMAND " "There are two main signatures for ADD_CUSTOM_COMMAND "
"The first signature is for adding a custom command " "The first signature is for adding a custom command "
"to produce an output.\n" "to produce an output.\n"
" ADD_CUSTOM_COMMAND(OUTPUT result\n" " ADD_CUSTOM_COMMAND(OUTPUT result\n"
" COMMAND command\n" " COMMAND command1 [ARGS] [args1...]\n"
" [ARGS [args...]]\n" " [COMMAND command2 [ARGS] [args2...] ...]\n"
" [MAIN_DEPENDENCY depend]\n" " [MAIN_DEPENDENCY depend]\n"
" [DEPENDS [depends...]]\n" " [DEPENDS [depends...]]\n"
" [COMMENT comment])\n" " [COMMENT comment])\n"
@ -78,14 +78,17 @@ public:
"custom command. In makefile terms this creates a new target in the " "custom command. In makefile terms this creates a new target in the "
"following form:\n" "following form:\n"
" OUTPUT: MAIN_DEPENDENCY DEPENDS\n" " OUTPUT: MAIN_DEPENDENCY DEPENDS\n"
" COMMAND ARGS\n" " COMMAND\n"
"If more than one command is specified they will be executed in order. "
"The optional ARGS argument is for backward compatibility and will be "
"ignored.\n"
"The second signature adds a custom command to a target " "The second signature adds a custom command to a target "
"such as a library or executable. This is useful for " "such as a library or executable. This is useful for "
"performing an operation before or after building the target:\n" "performing an operation before or after building the target:\n"
" ADD_CUSTOM_COMMAND(TARGET target\n" " ADD_CUSTOM_COMMAND(TARGET target\n"
" PRE_BUILD | PRE_LINK | POST_BUILD\n" " PRE_BUILD | PRE_LINK | POST_BUILD\n"
" COMMAND command\n" " COMMAND command1 [ARGS] [args1...]\n"
" [ARGS [args...]]\n" " [COMMAND command2 [ARGS] [args2...] ...]\n"
" [COMMENT comment])\n" " [COMMENT comment])\n"
"This defines a new command that will be associated with " "This defines a new command that will be associated with "
"building the specified target. When the command will " "building the specified target. When the command will "

View File

@ -19,52 +19,88 @@
// cmAddCustomTargetCommand // cmAddCustomTargetCommand
bool cmAddCustomTargetCommand::InitialPass(std::vector<std::string> const& args) bool cmAddCustomTargetCommand::InitialPass(std::vector<std::string> const& args)
{ {
bool all = false;
if(args.size() < 1 ) if(args.size() < 1 )
{ {
this->SetError("called with incorrect number of arguments"); this->SetError("called with incorrect number of arguments");
return false; return false;
} }
// all target option // Accumulate one command line at a time.
std::string arguments; cmCustomCommandLine currentLine;
std::vector<std::string>::const_iterator s = args.begin();
++s; // move past args[0] as it is already to be used // Save all command lines.
if (args.size() >= 2) cmCustomCommandLines commandLines;
// Accumulate dependencies.
std::vector<std::string> depends;
// Keep track of parser state.
enum tdoing {
doing_command,
doing_depends
};
tdoing doing = doing_command;
// Look for the ALL option.
bool all = false;
unsigned int start = 1;
if(args.size() > 1)
{ {
if (args[1] == "ALL") if(args[1] == "ALL")
{ {
all = true; all = true;
++s; // skip all start = 2;
} }
} }
std::string command;
if(s != args.end() && *s != "DEPENDS") // Parse the rest of the arguments.
for(unsigned int j = start; j < args.size(); ++j)
{ {
command = *s; std::string const& copy = args[j];
++s;
if(copy == "DEPENDS")
{
doing = doing_depends;
}
else if(copy == "COMMAND")
{
doing = doing_command;
// Save the current command before starting the next command.
if(!currentLine.empty())
{
commandLines.push_back(currentLine);
currentLine.clear();
}
}
else
{
switch (doing)
{
case doing_command:
currentLine.push_back(copy);
break;
case doing_depends:
depends.push_back(copy);
break;
default:
this->SetError("Wrong syntax. Unknown type of argument.");
return false;
}
}
} }
for (;s != args.end() && *s != "DEPENDS"; ++s)
// Store the last command line finished.
if(!currentLine.empty())
{ {
arguments += cmSystemTools::EscapeSpaces(s->c_str()); commandLines.push_back(currentLine);
arguments += " "; currentLine.clear();
} }
std::vector<std::string> depends;
// skip depends keyword // Add the utility target to the makefile.
if (s != args.end()) const char* no_output = 0;
{ m_Makefile->AddUtilityCommand(args[0].c_str(), all, no_output, depends,
++s; commandLines);
}
while (s != args.end())
{
depends.push_back(*s);
++s;
}
m_Makefile->AddUtilityCommand(args[0].c_str(),
command.c_str(),
arguments.c_str(), all, depends);
return true; return true;
} }

View File

@ -63,9 +63,10 @@ public:
virtual const char* GetFullDocumentation() virtual const char* GetFullDocumentation()
{ {
return return
" ADD_CUSTOM_TARGET(Name [ALL] [ command arg arg arg ... ]\n" " ADD_CUSTOM_TARGET(Name [ALL] [command1 [args1...]]\n"
" [COMMAND command2 [args2...] ...]\n"
" [DEPENDS depend depend depend ... ])\n" " [DEPENDS depend depend depend ... ])\n"
"Adds a target with the given name that executes the given command " "Adds a target with the given name that executes the given commands "
"every time the target is built. If the ALL option is specified " "every time the target is built. If the ALL option is specified "
"it indicates that this target should be added to the default build " "it indicates that this target should be added to the default build "
"target so that it will be run every time. " "target so that it will be run every time. "

View File

@ -203,20 +203,44 @@ void cmAddUtilityCommand(void *arg, const char* utilityName,
int numOutputs, int numOutputs,
const char **outputs) const char **outputs)
{ {
cmMakefile *mf = static_cast<cmMakefile *>(arg); // Get the makefile instance. Perform an extra variable expansion
// now because the API caller expects it.
cmMakefile* mf = static_cast<cmMakefile*>(arg);
// Construct the command line for the command.
cmCustomCommandLine commandLine;
std::string expand = command;
commandLine.push_back(mf->ExpandVariablesInString(expand));
if(arguments && arguments[0])
{
// TODO: Parse arguments!
expand = arguments;
commandLine.push_back(mf->ExpandVariablesInString(expand));
}
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
// Accumulate the list of dependencies.
std::vector<std::string> depends2; std::vector<std::string> depends2;
int i; for(int i = 0; i < numDepends; ++i)
for (i = 0; i < numDepends; ++i)
{ {
depends2.push_back(depends[i]); expand = depends[i];
depends2.push_back(mf->ExpandVariablesInString(expand));
} }
std::vector<std::string> outputs2;
for (i = 0; i < numOutputs; ++i) // Only one output is allowed.
const char* output = 0;
std::string outputStr;
if(numOutputs > 0)
{ {
outputs2.push_back(outputs[i]); expand = outputs[0];
outputStr = mf->ExpandVariablesInString(expand);
output = outputStr.c_str();
} }
mf->AddUtilityCommand(utilityName,command,arguments, (all ? true : false),
depends2, outputs2); // Pass the call to the makefile instance.
mf->AddUtilityCommand(utilityName, (all ? true : false),
output, depends2, commandLines);
} }
void cmAddCustomCommand(void *arg, const char* source, void cmAddCustomCommand(void *arg, const char* source,
const char* command, const char* command,
@ -225,24 +249,42 @@ void cmAddCustomCommand(void *arg, const char* source,
int numOutputs, const char **outputs, int numOutputs, const char **outputs,
const char *target) const char *target)
{ {
cmMakefile *mf = static_cast<cmMakefile *>(arg); // Get the makefile instance. Perform an extra variable expansion
int i; // now because the API caller expects it.
std::vector<std::string> args2; cmMakefile* mf = static_cast<cmMakefile*>(arg);
for (i = 0; i < numArgs; ++i)
// Construct the command line for the command.
cmCustomCommandLine commandLine;
std::string expand = command;
commandLine.push_back(mf->ExpandVariablesInString(expand));
for(int i=0; i < numArgs; ++i)
{ {
args2.push_back(args[i]); expand = args[i];
commandLine.push_back(mf->ExpandVariablesInString(expand));
} }
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
// Accumulate the list of dependencies.
std::vector<std::string> depends2; std::vector<std::string> depends2;
for (i = 0; i < numDepends; ++i) for(int i = 0; i < numDepends; ++i)
{ {
depends2.push_back(depends[i]); expand = depends[i];
depends2.push_back(mf->ExpandVariablesInString(expand));
} }
// Accumulate the list of outputs.
std::vector<std::string> outputs2; std::vector<std::string> outputs2;
for (i = 0; i < numOutputs; ++i) for(int i = 0; i < numOutputs; ++i)
{ {
outputs2.push_back(outputs[i]); expand = outputs[i];
outputs2.push_back(mf->ExpandVariablesInString(expand));
} }
mf->AddCustomCommand(source, command, args2, depends2, outputs2, target);
// Pass the call to the makefile instance.
const char* no_comment = 0;
mf->AddCustomCommandOldStyle(target, outputs2, depends2, source,
commandLines, no_comment);
} }
void cmAddCustomCommandToOutput(void *arg, const char* output, void cmAddCustomCommandToOutput(void *arg, const char* output,
@ -251,20 +293,34 @@ void cmAddCustomCommandToOutput(void *arg, const char* output,
const char* main_dependency, const char* main_dependency,
int numDepends, const char **depends) int numDepends, const char **depends)
{ {
cmMakefile *mf = static_cast<cmMakefile *>(arg); // Get the makefile instance. Perform an extra variable expansion
int i; // now because the API caller expects it.
std::vector<std::string> args2; cmMakefile* mf = static_cast<cmMakefile*>(arg);
for (i = 0; i < numArgs; ++i)
// Construct the command line for the command.
cmCustomCommandLine commandLine;
std::string expand = command;
commandLine.push_back(mf->ExpandVariablesInString(expand));
for(int i=0; i < numArgs; ++i)
{ {
args2.push_back(args[i]); expand = args[i];
commandLine.push_back(mf->ExpandVariablesInString(expand));
} }
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
// Accumulate the list of dependencies.
std::vector<std::string> depends2; std::vector<std::string> depends2;
for (i = 0; i < numDepends; ++i) for(int i = 0; i < numDepends; ++i)
{ {
depends2.push_back(depends[i]); expand = depends[i];
depends2.push_back(mf->ExpandVariablesInString(expand));
} }
mf->AddCustomCommandToOutput(output, command, args2, main_dependency,
depends2); // Pass the call to the makefile instance.
const char* no_comment = 0;
mf->AddCustomCommandToOutput(output, depends2, main_dependency,
commandLines, no_comment);
} }
void cmAddCustomCommandToTarget(void *arg, const char* target, void cmAddCustomCommandToTarget(void *arg, const char* target,
@ -272,28 +328,42 @@ void cmAddCustomCommandToTarget(void *arg, const char* target,
int numArgs, const char **args, int numArgs, const char **args,
int commandType) int commandType)
{ {
cmMakefile *mf = static_cast<cmMakefile *>(arg); // Get the makefile instance.
int i; cmMakefile* mf = static_cast<cmMakefile*>(arg);
std::vector<std::string> args2;
for (i = 0; i < numArgs; ++i) // Construct the command line for the command. Perform an extra
// variable expansion now because the API caller expects it.
cmCustomCommandLine commandLine;
std::string expand = command;
commandLine.push_back(mf->ExpandVariablesInString(expand));
for(int i=0; i < numArgs; ++i)
{ {
args2.push_back(args[i]); expand = args[i];
commandLine.push_back(mf->ExpandVariablesInString(expand));
} }
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
// Select the command type.
cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
switch (commandType) switch (commandType)
{ {
case CM_PRE_BUILD: case CM_PRE_BUILD:
mf->AddCustomCommandToTarget(target, command, args2, cctype = cmTarget::PRE_BUILD;
cmTarget::PRE_BUILD);
break; break;
case CM_PRE_LINK: case CM_PRE_LINK:
mf->AddCustomCommandToTarget(target, command, args2, cctype = cmTarget::PRE_LINK;
cmTarget::PRE_LINK);
break; break;
case CM_POST_BUILD: case CM_POST_BUILD:
mf->AddCustomCommandToTarget(target, command, args2, cctype = cmTarget::POST_BUILD;
cmTarget::POST_BUILD);
break; break;
} }
// Pass the call to the makefile instance.
std::vector<std::string> no_depends;
const char* no_comment = 0;
mf->AddCustomCommandToTarget(target, no_depends, commandLines,
cctype, no_comment);
} }
void cmAddLinkLibraryForTarget(void *arg, const char *tgt, const char*value, void cmAddLinkLibraryForTarget(void *arg, const char *tgt, const char*value,

View File

@ -9,74 +9,59 @@
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
#include "cmCustomCommand.h" #include "cmCustomCommand.h"
#include "cmMakefile.h"
/** //----------------------------------------------------------------------------
* The constructor cmCustomCommand::cmCustomCommand()
*/
cmCustomCommand::cmCustomCommand(const char *command,
const char* arguments,
std::vector<std::string> dep,
const char *out):
m_Command(command),
m_Arguments(arguments),
m_Depends(dep)
{
if (out)
{
m_Output = out;
}
}
cmCustomCommand::cmCustomCommand(const char *command,
const char* arguments):
m_Command(command),
m_Arguments(arguments)
{ {
} }
/** //----------------------------------------------------------------------------
* Copy constructor.
*/
cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
m_Command(r.m_Command),
m_Arguments(r.m_Arguments),
m_Comment(r.m_Comment),
m_Output(r.m_Output), m_Output(r.m_Output),
m_Depends(r.m_Depends) m_Depends(r.m_Depends),
m_CommandLines(r.m_CommandLines),
m_Comment(r.m_Comment)
{ {
} }
void cmCustomCommand::ExpandVariables(const cmMakefile &mf) //----------------------------------------------------------------------------
cmCustomCommand::cmCustomCommand(const char* output,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
const char* comment):
m_Output(output?output:""),
m_Depends(depends),
m_CommandLines(commandLines),
m_Comment(comment?comment:"")
{ {
mf.ExpandVariablesInString(m_Command);
mf.ExpandVariablesInString(m_Arguments);
mf.ExpandVariablesInString(m_Output);
for (std::vector<std::string>::iterator i = m_Depends.begin();
i != m_Depends.end(); ++i)
{
mf.ExpandVariablesInString(*i);
}
} }
//----------------------------------------------------------------------------
bool cmCustomCommand::IsEquivalent(const char* command, const char* cmCustomCommand::GetOutput() const
const char* args)
{ {
if(m_Command != command) return m_Output.c_str();
{ }
return false;
} //----------------------------------------------------------------------------
if(m_Arguments != args) const std::vector<std::string>& cmCustomCommand::GetDepends() const
{ {
return false; return m_Depends;
} }
return true;
//----------------------------------------------------------------------------
const cmCustomCommandLines& cmCustomCommand::GetCommandLines() const
{
return m_CommandLines;
}
//----------------------------------------------------------------------------
const char* cmCustomCommand::GetComment() const
{
return m_Comment.c_str();
} }

View File

@ -9,8 +9,8 @@
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
@ -18,7 +18,6 @@
#define cmCustomCommand_h #define cmCustomCommand_h
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
class cmMakefile;
/** \class cmCustomCommand /** \class cmCustomCommand
* \brief A class to encapsulate a custom command * \brief A class to encapsulate a custom command
@ -28,57 +27,33 @@ class cmMakefile;
class cmCustomCommand class cmCustomCommand
{ {
public: public:
cmCustomCommand(const char *command, /** Default and copy constructors for STL containers. */
const char* arguments, cmCustomCommand();
std::vector<std::string> dep,
const char *out);
cmCustomCommand(const char *command,
const char* arguments);
cmCustomCommand() {};
cmCustomCommand(const cmCustomCommand& r); cmCustomCommand(const cmCustomCommand& r);
/**
* Use the cmMakefile's Expand commands to expand any variables in
* this objects members.
*/
void ExpandVariables(const cmMakefile &);
///! Return the command to execute with arguments /** Main constructor specifies all information for the command. */
std::string GetCommandAndArguments() const cmCustomCommand(const char* output,
{return m_Command + " " + m_Arguments;} const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
///! Return the command to execute const char* comment);
const std::string &GetCommand() const {return m_Command;}
void SetCommand(const char *cmd) {m_Command = cmd;}
///! Return the output /** Get the output file produced by the command. */
const std::string &GetOutput() const {return m_Output;} const char* GetOutput() const;
void SetOutput(const char *cm) {m_Output = cm;}
///! Return the comment /** Get the vector that holds the list of dependencies. */
const std::string &GetComment() const {return m_Comment;} const std::vector<std::string>& GetDepends() const;
void SetComment(const char *cm) {m_Comment = cm;}
/** Get the list of command lines. */
const cmCustomCommandLines& GetCommandLines() const;
/** Get the comment string for the command. */
const char* GetComment() const;
///! Return the commands arguments
const std::string &GetArguments() const {return m_Arguments;}
void SetArguments(const char *arg) {m_Arguments = arg;}
/**
* Return the vector that holds the list of dependencies
*/
const std::vector<std::string> &GetDepends() const {return m_Depends;}
std::vector<std::string> &GetDepends() {return m_Depends;}
///! Return true if the command and args are equal to the ones here.
bool IsEquivalent(const char* command,
const char* args);
private: private:
std::string m_Command;
std::string m_Arguments;
std::string m_Comment;
std::string m_Output; std::string m_Output;
std::vector<std::string> m_Depends; std::vector<std::string> m_Depends;
cmCustomCommandLines m_CommandLines;
std::string m_Comment;
}; };
#endif #endif

View File

@ -29,7 +29,8 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args)
// what is the current source dir // what is the current source dir
std::string cdir = m_Makefile->GetCurrentDirectory(); std::string cdir = m_Makefile->GetCurrentDirectory();
std::string fluid_exe = "${FLTK_FLUID_EXECUTABLE}"; const char* fluid_exe =
m_Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE");
// get parameter for the command // get parameter for the command
m_Target = args[0]; // Target that will use the generated files m_Target = args[0]; // Target that will use the generated files
@ -66,28 +67,28 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args)
std::string cxxres = outputDirectory.c_str(); std::string cxxres = outputDirectory.c_str();
cxxres += "/" + srcName; cxxres += "/" + srcName;
cxxres += ".cxx"; cxxres += ".cxx";
std::vector<std::string> cxxargs; cmCustomCommandLine commandLine;
cxxargs.push_back("-c"); // instructs Fluid to run in command line commandLine.push_back(fluid_exe);
cxxargs.push_back("-h"); // optionally rename .h files commandLine.push_back("-c"); // instructs Fluid to run in command line
cxxargs.push_back(hname); commandLine.push_back("-h"); // optionally rename .h files
cxxargs.push_back("-o"); // optionally rename .cxx files commandLine.push_back(hname);
cxxargs.push_back(cxxres); commandLine.push_back("-o"); // optionally rename .cxx files
cxxargs.push_back(origname);// name of the GUI fluid file commandLine.push_back(cxxres);
commandLine.push_back(origname);// name of the GUI fluid file
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
// Add command for generating the .h and .cxx files // Add command for generating the .h and .cxx files
const char* no_main_dependency = 0;
const char* no_comment = 0;
m_Makefile->AddCustomCommandToOutput(cxxres.c_str(), m_Makefile->AddCustomCommandToOutput(cxxres.c_str(),
fluid_exe.c_str(), depends, no_main_dependency,
cxxargs, commandLines, no_comment);
0,
depends);
m_Makefile->AddCustomCommandToOutput(hname.c_str(), m_Makefile->AddCustomCommandToOutput(hname.c_str(),
fluid_exe.c_str(), depends, no_main_dependency,
cxxargs, commandLines, no_comment);
0,
depends);
cmSourceFile *sf = m_Makefile->GetSource(cxxres.c_str()); cmSourceFile *sf = m_Makefile->GetSource(cxxres.c_str());
sf->GetDepends().push_back(hname); sf->GetDepends().push_back(hname);
sf->GetDepends().push_back(origname); sf->GetDepends().push_back(origname);

View File

@ -169,8 +169,9 @@ cmLocalGenerator *cmGlobalVisualStudio6Generator::CreateLocalGenerator()
void cmGlobalVisualStudio6Generator::Generate() void cmGlobalVisualStudio6Generator::Generate()
{ {
// add a special target that depends on ALL projects for easy build // add a special target that depends on ALL projects for easy build
// of one configuration only. // of one configuration only.
std::vector<std::string> srcs; const char* no_output = 0;
std::vector<std::string> no_depends;
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it) for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it)
{ {
@ -179,12 +180,14 @@ void cmGlobalVisualStudio6Generator::Generate()
if(gen.size()) if(gen.size())
{ {
gen[0]->GetMakefile()-> gen[0]->GetMakefile()->
AddUtilityCommand("ALL_BUILD", "echo","\"Build all projects\"",false,srcs); AddUtilityCommand("ALL_BUILD", false, no_output, no_depends,
"echo", "Build all projects");
std::string cmake_command = std::string cmake_command =
m_LocalGenerators[0]->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"); m_LocalGenerators[0]->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND");
gen[0]->GetMakefile()-> gen[0]->GetMakefile()->
AddUtilityCommand("INSTALL", cmake_command.c_str(), AddUtilityCommand("INSTALL", false, no_output, no_depends,
"-DBUILD_TYPE=$(IntDir) -P cmake_install.cmake",false,srcs); cmake_command.c_str(),
"-DBUILD_TYPE=$(IntDir)", "-P", "cmake_install.cmake");
} }
} }
@ -277,8 +280,9 @@ void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout,
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
std::string project = cc.GetCommand(); const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string location = cc.GetArguments(); std::string project = cmds[0][0];
std::string location = cmds[0][1];
this->WriteExternalProject(fout, project.c_str(), location.c_str(), cc.GetDepends()); this->WriteExternalProject(fout, project.c_str(), location.c_str(), cc.GetDepends());
} }
else else
@ -417,7 +421,8 @@ void cmGlobalVisualStudio6Generator::SetupTests()
// If the file doesn't exist, then ENABLE_TESTING hasn't been run // If the file doesn't exist, then ENABLE_TESTING hasn't been run
if (cmSystemTools::FileExists(fname.c_str())) if (cmSystemTools::FileExists(fname.c_str()))
{ {
std::vector<std::string> srcs; const char* no_output = 0;
std::vector<std::string> no_depends;
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it) for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it)
{ {
@ -426,7 +431,8 @@ void cmGlobalVisualStudio6Generator::SetupTests()
if(gen.size()) if(gen.size())
{ {
gen[0]->GetMakefile()-> gen[0]->GetMakefile()->
AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-C $(IntDir)",false,srcs); AddUtilityCommand("RUN_TESTS", false, no_output, no_depends,
ctest.c_str(), "-C", "$(IntDir)");
} }
} }
} }

View File

@ -120,11 +120,10 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(std::ostream& fout,
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project = cc.GetCommand(); std::string project = cmds[0][0];
std::string location = cc.GetArguments(); std::string location = cmds[0][1];
this->WriteExternalProject(fout, project.c_str(), this->WriteExternalProject(fout, project.c_str(), location.c_str(), cc.GetDepends());
location.c_str(), cc.GetDepends());
} }
else else
{ {
@ -204,8 +203,8 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(std::ostream& fout,
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
std::string project = cc.GetCommand(); const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project = cmds[0][0];
this->WriteProjectConfigurations(fout, project.c_str(), l->second.IsInAll()); this->WriteProjectConfigurations(fout, project.c_str(), l->second.IsInAll());
} }
else if ((l->second.GetType() != cmTarget::INSTALL_FILES) else if ((l->second.GetType() != cmTarget::INSTALL_FILES)

View File

@ -167,7 +167,8 @@ void cmGlobalVisualStudio7Generator::SetupTests()
// If the file doesn't exist, then ENABLE_TESTING hasn't been run // If the file doesn't exist, then ENABLE_TESTING hasn't been run
if (cmSystemTools::FileExists(fname.c_str())) if (cmSystemTools::FileExists(fname.c_str()))
{ {
std::vector<std::string> srcs; const char* no_output = 0;
std::vector<std::string> no_depends;
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it) for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it)
{ {
@ -176,7 +177,8 @@ void cmGlobalVisualStudio7Generator::SetupTests()
if(gen.size()) if(gen.size())
{ {
gen[0]->GetMakefile()-> gen[0]->GetMakefile()->
AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-C $(IntDir)",false,srcs); AddUtilityCommand("RUN_TESTS", false, no_output, no_depends,
ctest.c_str(), "-C", "$(IntDir)");
} }
} }
} }
@ -254,8 +256,9 @@ void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
void cmGlobalVisualStudio7Generator::Generate() void cmGlobalVisualStudio7Generator::Generate()
{ {
// add a special target that depends on ALL projects for easy build // add a special target that depends on ALL projects for easy build
// of Debug only // of one configuration only.
std::vector<std::string> srcs; const char* no_output = 0;
std::vector<std::string> no_depends;
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it) for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it)
{ {
@ -264,12 +267,14 @@ void cmGlobalVisualStudio7Generator::Generate()
if(gen.size()) if(gen.size())
{ {
gen[0]->GetMakefile()-> gen[0]->GetMakefile()->
AddUtilityCommand("ALL_BUILD", "echo","\"Build all projects\"",false,srcs); AddUtilityCommand("ALL_BUILD", false, no_output, no_depends,
"echo", "Build all projects");
std::string cmake_command = std::string cmake_command =
m_LocalGenerators[0]->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"); m_LocalGenerators[0]->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND");
gen[0]->GetMakefile()-> gen[0]->GetMakefile()->
AddUtilityCommand("INSTALL", cmake_command.c_str(), AddUtilityCommand("INSTALL", false, no_output, no_depends,
"-DBUILD_TYPE=$(IntDir) -P cmake_install.cmake",false,srcs); cmake_command.c_str(),
"-DBUILD_TYPE=$(IntDir)", "-P", "cmake_install.cmake");
} }
} }
@ -394,11 +399,10 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout,
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project_name = cc.GetCommand(); std::string project = cmds[0][0];
std::string location = cc.GetArguments(); std::string location = cmds[0][1];
this->WriteExternalProject(fout, project_name.c_str(), this->WriteExternalProject(fout, project.c_str(), location.c_str(), cc.GetDepends());
location.c_str(), cc.GetDepends());
} }
else else
{ {
@ -481,7 +485,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout,
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
std::string name = cc.GetCommand(); const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string name = cmds[0][0];
std::vector<std::string> depends = cc.GetDepends(); std::vector<std::string> depends = cc.GetDepends();
std::vector<std::string>::iterator iter; std::vector<std::string>::iterator iter;
int depcount = 0; int depcount = 0;
@ -522,7 +527,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout,
if(strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if(strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
std::string name = cc.GetCommand(); const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string name = cmds[0][0];
this->WriteProjectConfigurations(fout, name.c_str(), l->second.IsInAll()); this->WriteProjectConfigurations(fout, name.c_str(), l->second.IsInAll());
} }
else if ((l->second.GetType() != cmTarget::INSTALL_FILES) else if ((l->second.GetType() != cmTarget::INSTALL_FILES)

View File

@ -207,16 +207,18 @@ void
cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& gens) std::vector<cmLocalGenerator*>& gens)
{ {
std::vector<std::string> srcs; // dummy list
cmMakefile* mf = root->GetMakefile(); cmMakefile* mf = root->GetMakefile();
// Add ALL_BUILD // Add ALL_BUILD
mf->AddUtilityCommand("ALL_BUILD", "echo", const char* no_output = 0;
"\"Build all projects\"",false,srcs); std::vector<std::string> no_depends;
mf->AddUtilityCommand("ALL_BUILD", false, no_output, no_depends,
"echo", "Build all projects");
cmTarget* allbuild = mf->FindTarget("ALL_BUILD"); cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
// ADD install // ADD install
std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND"); std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND");
mf->AddUtilityCommand("install", cmake_command.c_str(), mf->AddUtilityCommand("install", false, no_output, no_depends,
"-P cmake_install.cmake",false,srcs); cmake_command.c_str(),
"-P", "cmake_install.cmake");
// Add RUN_TESTS target if testing has been enabled // Add RUN_TESTS target if testing has been enabled
std::string fname; std::string fname;
fname = mf->GetStartOutputDirectory(); fname = mf->GetStartOutputDirectory();
@ -226,11 +228,9 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
{ {
std::string ctest_command = std::string ctest_command =
mf->GetRequiredDefinition("CMAKE_CTEST_COMMAND"); mf->GetRequiredDefinition("CMAKE_CTEST_COMMAND");
mf->AddUtilityCommand("RUN_TESTS", ctest_command.c_str(), "",false,srcs); mf->AddUtilityCommand("RUN_TESTS", false, no_output, no_depends,
ctest_command.c_str());
} }
// Add install
mf->AddUtilityCommand("install", cmake_command.c_str(),
"-P cmake_install.cmake", false, srcs);
// Add XCODE depend helper // Add XCODE depend helper
std::string dir = mf->GetCurrentOutputDirectory(); std::string dir = mf->GetCurrentOutputDirectory();
m_CurrentXCodeHackMakefile = dir; m_CurrentXCodeHackMakefile = dir;
@ -242,9 +242,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
makecommand += " -f "; makecommand += " -f ";
makecommand += this->ConvertToRelativeOutputPath( makecommand += this->ConvertToRelativeOutputPath(
m_CurrentXCodeHackMakefile.c_str()); m_CurrentXCodeHackMakefile.c_str());
mf->AddUtilityCommand("XCODE_DEPEND_HELPER", makecommand.c_str(), mf->AddUtilityCommand("XCODE_DEPEND_HELPER", false, no_output, no_depends,
"", makecommand.c_str());
false,srcs);
// now make the allbuild depend on all the non-utility targets // now make the allbuild depend on all the non-utility targets
// in the project // in the project
for(std::vector<cmLocalGenerator*>::iterator i = gens.begin(); for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
@ -656,12 +655,12 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
i != commands.end(); ++i) i != commands.end(); ++i)
{ {
cmCustomCommand const& cc = *i; cmCustomCommand const& cc = *i;
if(cc.GetCommand().size()) if(!cc.GetCommandLines().empty())
{ {
if(cc.GetOutput().size()) if(cc.GetOutput()[0])
{ {
makefileStream << "\\\n\t" << this-> makefileStream << "\\\n\t" << this->
ConvertToRelativeOutputPath(cc.GetOutput().c_str()); ConvertToRelativeOutputPath(cc.GetOutput());
} }
else else
{ {
@ -677,15 +676,15 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
i != commands.end(); ++i) i != commands.end(); ++i)
{ {
cmCustomCommand const& cc = *i; cmCustomCommand const& cc = *i;
if(cc.GetCommand().size()) if(!cc.GetCommandLines().empty())
{ {
makefileStream << "\n#" << "Custom command rule: " << makefileStream << "\n#" << "Custom command rule: " <<
cc.GetComment() << "\n"; cc.GetComment() << "\n";
if(cc.GetOutput().size()) if(cc.GetOutput()[0])
{ {
makefileStream << this makefileStream << this
->ConvertToRelativeOutputPath(cc.GetOutput().c_str()) << ": "; ->ConvertToRelativeOutputPath(cc.GetOutput()) << ": ";
} }
else else
{ {
@ -707,8 +706,23 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
} }
} }
makefileStream << "\n"; makefileStream << "\n";
makefileStream << "\t" << cc.GetCommand() << " "
<< cc.GetArguments() << "\n"; // Add each command line to the set of commands.
for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin();
cl != cc.GetCommandLines().end(); ++cl)
{
// Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl;
std::string cmd = commandLine[0];
cmSystemTools::ReplaceString(cmd, "/./", "/");
cmd = this->ConvertToRelativeOutputPath(cmd.c_str());
for(unsigned int j=1; j < commandLine.size(); ++j)
{
cmd += " ";
cmd += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
}
makefileStream << "\t" << cmd.c_str() << "\n";
}
} }
} }
std::string cdir = m_CurrentMakefile->GetCurrentOutputDirectory(); std::string cdir = m_CurrentMakefile->GetCurrentOutputDirectory();

View File

@ -104,23 +104,24 @@ bool cmITKWrapTclCommand::CreateCableRule(const char* configFile)
{ {
depends.push_back(command); depends.push_back(command);
} }
std::vector<std::string> commandArgs; cmCustomCommandLine commandLine;
commandArgs.push_back(inFile); commandLine.push_back(command);
commandArgs.push_back("-tcl"); commandLine.push_back(inFile);
commandLine.push_back("-tcl");
std::string tmp = tclFile+".cxx"; std::string tmp = tclFile+".cxx";
commandArgs.push_back(tmp); commandLine.push_back(tmp);
#if !defined(_WIN32) || defined(__CYGWIN__) #if !defined(_WIN32) || defined(__CYGWIN__)
tmp = "${CMAKE_CXX_COMPILER}"; tmp = "${CMAKE_CXX_COMPILER}";
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
if(tmp.length() > 0) if(tmp.length() > 0)
{ {
commandArgs.push_back("--gccxml-compiler"); commandLine.push_back("--gccxml-compiler");
commandArgs.push_back(tmp); commandLine.push_back(tmp);
tmp = "${CMAKE_CXX_FLAGS}"; tmp = "${CMAKE_CXX_FLAGS}";
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
commandArgs.push_back("--gccxml-cxxflags"); commandLine.push_back("--gccxml-cxxflags");
commandArgs.push_back(tmp); commandLine.push_back(tmp);
} }
#else #else
const char* genName = m_Makefile->GetDefinition("CMAKE_GENERATOR"); const char* genName = m_Makefile->GetDefinition("CMAKE_GENERATOR");
@ -129,44 +130,44 @@ bool cmITKWrapTclCommand::CreateCableRule(const char* configFile)
std::string gen = genName; std::string gen = genName;
if(gen == "Visual Studio 6") if(gen == "Visual Studio 6")
{ {
commandArgs.push_back("--gccxml-compiler"); commandLine.push_back("--gccxml-compiler");
commandArgs.push_back("msvc6"); commandLine.push_back("msvc6");
tmp = "${CMAKE_CXX_FLAGS}"; tmp = "${CMAKE_CXX_FLAGS}";
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
commandArgs.push_back("--gccxml-cxxflags"); commandLine.push_back("--gccxml-cxxflags");
commandArgs.push_back(tmp); commandLine.push_back(tmp);
} }
else if(gen == "Visual Studio 7") else if(gen == "Visual Studio 7")
{ {
commandArgs.push_back("--gccxml-compiler"); commandLine.push_back("--gccxml-compiler");
commandArgs.push_back("msvc7"); commandLine.push_back("msvc7");
tmp = "${CMAKE_CXX_FLAGS}"; tmp = "${CMAKE_CXX_FLAGS}";
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
commandArgs.push_back("--gccxml-cxxflags"); commandLine.push_back("--gccxml-cxxflags");
commandArgs.push_back(tmp); commandLine.push_back(tmp);
} }
else if(gen == "NMake Makefiles") else if(gen == "NMake Makefiles")
{ {
tmp = "${CMAKE_CXX_COMPILER}"; tmp = "${CMAKE_CXX_COMPILER}";
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
commandArgs.push_back("--gccxml-compiler"); commandLine.push_back("--gccxml-compiler");
commandArgs.push_back(tmp); commandLine.push_back(tmp);
tmp = "${CMAKE_CXX_FLAGS}"; tmp = "${CMAKE_CXX_FLAGS}";
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
commandArgs.push_back("--gccxml-cxxflags"); commandLine.push_back("--gccxml-cxxflags");
commandArgs.push_back(tmp); commandLine.push_back(tmp);
} }
} }
#endif #endif
const char* gccxml = m_Makefile->GetDefinition("ITK_GCCXML_EXECUTABLE"); const char* gccxml = m_Makefile->GetDefinition("ITK_GCCXML_EXECUTABLE");
if(gccxml) if(gccxml)
{ {
commandArgs.push_back("--gccxml"); commandLine.push_back("--gccxml");
commandArgs.push_back(gccxml); commandLine.push_back(gccxml);
} }
tmp = "-I"; tmp = "-I";
tmp += m_Makefile->GetStartDirectory(); tmp += m_Makefile->GetStartDirectory();
commandArgs.push_back(tmp); commandLine.push_back(tmp);
const std::vector<std::string>& includes = const std::vector<std::string>& includes =
m_Makefile->GetIncludeDirectories(); m_Makefile->GetIncludeDirectories();
for(std::vector<std::string>::const_iterator i = includes.begin(); for(std::vector<std::string>::const_iterator i = includes.begin();
@ -175,7 +176,7 @@ bool cmITKWrapTclCommand::CreateCableRule(const char* configFile)
tmp = "-I"; tmp = "-I";
tmp += i->c_str(); tmp += i->c_str();
m_Makefile->ExpandVariablesInString(tmp); m_Makefile->ExpandVariablesInString(tmp);
commandArgs.push_back(tmp); commandLine.push_back(tmp);
} }
// Get the dependencies. // Get the dependencies.
@ -198,11 +199,12 @@ bool cmITKWrapTclCommand::CreateCableRule(const char* configFile)
file.GetDepends().push_back("CableTclFacility/ctCalls.h"); file.GetDepends().push_back("CableTclFacility/ctCalls.h");
m_Makefile->AddSource(file); m_Makefile->AddSource(file);
m_Makefile->AddCustomCommandToOutput(output.c_str(), const char* no_comment = 0;
command.c_str(), cmCustomCommandLines commandLines;
commandArgs, commandLines.push_back(commandLine);
inFile.c_str(), m_Makefile->AddCustomCommandToOutput(output.c_str(), depends,
depends); inFile.c_str(), commandLines,
no_comment);
// Add the generated source to the package's source list. // Add the generated source to the package's source list.
m_Target->GetSourceLists().push_back(output); m_Target->GetSourceLists().push_back(output);

View File

@ -42,9 +42,11 @@ bool cmIncludeExternalMSProjectCommand::InitialPass(std::vector<std::string> con
std::string utility_name("INCLUDE_EXTERNAL_MSPROJECT"); std::string utility_name("INCLUDE_EXTERNAL_MSPROJECT");
utility_name += "_"; utility_name += "_";
utility_name += args[0]; utility_name += args[0];
m_Makefile->AddUtilityCommand(utility_name.c_str(), args[0].c_str(), args[1].c_str(), const char* no_output = 0;
true, depends); m_Makefile->AddUtilityCommand(utility_name.c_str(), true,
no_output, depends,
args[0].c_str(), args[1].c_str());
} }
#endif #endif

View File

@ -509,6 +509,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
sourceAndDeps.push_back(this->ConvertToRelativeOutputPath(i->c_str())); sourceAndDeps.push_back(this->ConvertToRelativeOutputPath(i->c_str()));
} }
} }
#if 0
std::string command; std::string command;
std::string args; std::string args;
cmSystemTools::SplitProgramFromArgs(commands[0].c_str(), command, args); cmSystemTools::SplitProgramFromArgs(commands[0].c_str(), command, args);
@ -520,6 +521,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
source.GetFullPath().c_str(), source.GetFullPath().c_str(),
sourceAndDeps, sourceAndDeps,
"build from source"); "build from source");
#endif
} }
void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
@ -577,13 +579,16 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
0, // target so name, 0, // target so name,
linkFlags.c_str() // link flags linkFlags.c_str() // link flags
); );
#if 0
std::string command; std::string command;
std::string args; std::string args;
cmSystemTools::SplitProgramFromArgs(rule.c_str(), command, args); cmSystemTools::SplitProgramFromArgs(rule.c_str(), command, args);
// Just like ADD_CUSTOM_TARGET(foo ALL DEPENDS a.o b.o) // Just like ADD_CUSTOM_TARGET(foo ALL DEPENDS a.o b.o)
// Add a custom command for generating each .o file // Add a custom command for generating each .o file
cmCustomCommand cc(command.c_str(), args.c_str(), objVector, targetName.c_str()); cmCustomCommand cc(command.c_str(), args.c_str(), objVector,
targetName.c_str(), 0);
target.GetPostBuildCommands().push_back(cc); target.GetPostBuildCommands().push_back(cc);
#endif
} }
@ -1342,3 +1347,31 @@ void cmLocalGenerator::AppendFlags(std::string& flags,
} }
} }
//----------------------------------------------------------------------------
std::string
cmLocalGenerator::ConstructScript(const cmCustomCommandLines& commandLines,
const char* newline)
{
// Store the script in a string.
std::string script;
// Write each command on a single line.
for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
cl != commandLines.end(); ++cl)
{
// Start with the command name.
const cmCustomCommandLine& commandLine = *cl;
script += this->ConvertToRelativeOutputPath(commandLine[0].c_str());
// Add the arguments.
for(unsigned int j=1;j < commandLine.size(); ++j)
{
script += " ";
script += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
}
// End the line.
script += newline;
}
return script;
}

View File

@ -105,6 +105,9 @@ public:
protected: protected:
/** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines,
const char* newline = "\n");
///! Fill out these strings for the given target. Libraries to link, flags, and linkflags. ///! Fill out these strings for the given target. Libraries to link, flags, and linkflags.
void GetTargetFlags(std::string& linkLibs, void GetTargetFlags(std::string& linkLibs,

View File

@ -663,8 +663,6 @@ std::string cmLocalUnixMakefileGenerator::CreatePreBuildRules(
target.GetPreBuildCommands().begin(); target.GetPreBuildCommands().begin();
cr != target.GetPreBuildCommands().end(); ++cr) cr != target.GetPreBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if(initNext) if(initNext)
{ {
customRuleCode += "\n\t"; customRuleCode += "\n\t";
@ -673,8 +671,7 @@ std::string cmLocalUnixMakefileGenerator::CreatePreBuildRules(
{ {
initNext = true; initNext = true;
} }
std::string command = this->ConvertToRelativeOutputPath(cc.GetCommand().c_str()); customRuleCode += this->ConstructScript(cr->GetCommandLines(), "\n\t");
customRuleCode += command + " " + cc.GetArguments();
} }
return customRuleCode; return customRuleCode;
} }
@ -688,8 +685,6 @@ std::string cmLocalUnixMakefileGenerator::CreatePreLinkRules(
target.GetPreLinkCommands().begin(); target.GetPreLinkCommands().begin();
cr != target.GetPreLinkCommands().end(); ++cr) cr != target.GetPreLinkCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if(initNext) if(initNext)
{ {
customRuleCode += "\n\t"; customRuleCode += "\n\t";
@ -698,8 +693,7 @@ std::string cmLocalUnixMakefileGenerator::CreatePreLinkRules(
{ {
initNext = true; initNext = true;
} }
std::string command = this->ConvertToRelativeOutputPath(cc.GetCommand().c_str()); customRuleCode += this->ConstructScript(cr->GetCommandLines(), "\n\t");
customRuleCode += command + " " + cc.GetArguments();
} }
return customRuleCode; return customRuleCode;
} }
@ -713,8 +707,6 @@ std::string cmLocalUnixMakefileGenerator::CreatePostBuildRules(
target.GetPostBuildCommands().begin(); target.GetPostBuildCommands().begin();
cr != target.GetPostBuildCommands().end(); ++cr) cr != target.GetPostBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if(initNext) if(initNext)
{ {
customRuleCode += "\n\t"; customRuleCode += "\n\t";
@ -723,8 +715,7 @@ std::string cmLocalUnixMakefileGenerator::CreatePostBuildRules(
{ {
initNext = true; initNext = true;
} }
std::string command = this->ConvertToRelativeOutputPath(cc.GetCommand().c_str()); customRuleCode += this->ConstructScript(cr->GetCommandLines(), "\n\t");
customRuleCode += command + " " + cc.GetArguments();
} }
return customRuleCode; return customRuleCode;
} }
@ -2025,12 +2016,24 @@ void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
// escape spaces and convert to native slashes path for // escape spaces and convert to native slashes path for
// the command // the command
std::string comment = c->GetComment(); std::string comment = c->GetComment();
std::string command = c->GetCommand(); std::vector<std::string> commands;
cmSystemTools::ReplaceString(command, "/./", "/");
command = this->ConvertToRelativeOutputPath(command.c_str()); // Add each command line to the set of commands.
command += " "; for(cmCustomCommandLines::const_iterator cl = c->GetCommandLines().begin();
// now add the arguments cl != c->GetCommandLines().end(); ++cl)
command += c->GetArguments(); {
// Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl;
std::string cmd = commandLine[0];
cmSystemTools::ReplaceString(cmd, "/./", "/");
cmd = this->ConvertToRelativeOutputPath(cmd.c_str());
for(unsigned int j=1; j < commandLine.size(); ++j)
{
cmd += " ";
cmd += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
}
commands.push_back(cmd);
}
std::vector<std::string> depends; std::vector<std::string> depends;
// Collect out all the dependencies for this rule. // Collect out all the dependencies for this rule.
for(std::vector<std::string>::const_iterator d = for(std::vector<std::string>::const_iterator d =
@ -2066,15 +2069,15 @@ void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
{ {
this->OutputMakeRule(fout, this->OutputMakeRule(fout,
(comment.size()?comment.c_str():"Custom command"), (comment.size()?comment.c_str():"Custom command"),
c->GetOutput().c_str(), c->GetOutput(),
depends, depends,
command.c_str()); commands);
processedOutputs.insert(c->GetOutput()); processedOutputs.insert(c->GetOutput());
} }
else else
{ {
cmSystemTools::Error("An output was found with multiple rules on how to build it for output: ", cmSystemTools::Error("An output was found with multiple rules on how to build it for output: ",
c->GetOutput().c_str()); c->GetOutput());
} }
} }
} }

View File

@ -670,7 +670,7 @@ cmLocalUnixMakefileGenerator2
if(m_CustomRuleFiles.find(ruleFileName) != m_CustomRuleFiles.end()) if(m_CustomRuleFiles.find(ruleFileName) != m_CustomRuleFiles.end())
{ {
cmSystemTools::Error("An output was found with multiple rules on how to build it for output: ", cmSystemTools::Error("An output was found with multiple rules on how to build it for output: ",
cc.GetOutput().c_str()); cc.GetOutput());
return; return;
} }
m_CustomRuleFiles.insert(ruleFileName); m_CustomRuleFiles.insert(ruleFileName);
@ -704,15 +704,15 @@ cmLocalUnixMakefileGenerator2
// Write the rule. // Write the rule.
const char* comment = 0; const char* comment = 0;
if(cc.GetComment().size()) if(cc.GetComment() && *cc.GetComment())
{ {
comment = cc.GetComment().c_str(); comment = cc.GetComment();
} }
std::string preEcho = "Generating "; std::string preEcho = "Generating ";
preEcho += customName; preEcho += customName;
preEcho += "..."; preEcho += "...";
this->WriteMakeRule(ruleFileStream, comment, preEcho.c_str(), this->WriteMakeRule(ruleFileStream, comment, preEcho.c_str(),
cc.GetOutput().c_str(), depends, commands); cc.GetOutput(), depends, commands);
// Write the clean rule for this custom command. // Write the clean rule for this custom command.
std::string cleanTarget = customName; std::string cleanTarget = customName;
@ -720,7 +720,7 @@ cmLocalUnixMakefileGenerator2
commands.clear(); commands.clear();
depends.clear(); depends.clear();
std::vector<std::string> cleanFiles; std::vector<std::string> cleanFiles;
cleanFiles.push_back(cc.GetOutput().c_str()); cleanFiles.push_back(cc.GetOutput());
this->AppendCleanCommand(commands, cleanFiles); this->AppendCleanCommand(commands, cleanFiles);
this->WriteMakeRule(ruleFileStream, this->WriteMakeRule(ruleFileStream,
"Clean the output of this custom command.", 0, "Clean the output of this custom command.", 0,
@ -2282,18 +2282,18 @@ cmLocalUnixMakefileGenerator2
// the custom file. Otherwise, we will use just the filename // the custom file. Otherwise, we will use just the filename
// portion. // portion.
std::string customName; std::string customName;
if(cmSystemTools::FileIsFullPath(cc.GetOutput().c_str()) && if(cmSystemTools::FileIsFullPath(cc.GetOutput()) &&
(cc.GetOutput().find(m_Makefile->GetStartOutputDirectory()) == 0)) (std::string(cc.GetOutput()).find(m_Makefile->GetStartOutputDirectory()) == 0))
{ {
// Use the relative path but convert it to a valid file name. // Use the relative path but convert it to a valid file name.
customName = customName =
cmSystemTools::RelativePath(m_Makefile->GetStartOutputDirectory(), cmSystemTools::RelativePath(m_Makefile->GetStartOutputDirectory(),
cc.GetOutput().c_str()); cc.GetOutput());
cmSystemTools::ReplaceString(customName, "/", "_"); cmSystemTools::ReplaceString(customName, "/", "_");
} }
else else
{ {
customName = cmSystemTools::GetFilenameName(cc.GetOutput().c_str()); customName = cmSystemTools::GetFilenameName(cc.GetOutput());
} }
return customName; return customName;
} }
@ -2734,16 +2734,22 @@ cmLocalUnixMakefileGenerator2
{ {
// TODO: Convert outputs/dependencies (arguments?) to relative paths. // TODO: Convert outputs/dependencies (arguments?) to relative paths.
// Build the command line in a single string. // Add each command line to the set of commands.
std::string cmd = cc.GetCommand(); for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin();
cmSystemTools::ReplaceString(cmd, "/./", "/"); cl != cc.GetCommandLines().end(); ++cl)
cmd = this->ConvertToRelativeOutputPath(cmd.c_str());
if(cc.GetArguments().size() > 0)
{ {
cmd += " "; // Build the command line in a single string.
cmd += cc.GetArguments(); const cmCustomCommandLine& commandLine = *cl;
std::string cmd = commandLine[0];
cmSystemTools::ReplaceString(cmd, "/./", "/");
cmd = this->ConvertToRelativeOutputPath(cmd.c_str());
for(unsigned int j=1; j < commandLine.size(); ++j)
{
cmd += " ";
cmd += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
}
commands.push_back(cmd);
} }
commands.push_back(cmd);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -81,9 +81,6 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
// clear project names // clear project names
m_CreatedProjectNames.clear(); m_CreatedProjectNames.clear();
// expand vars for custom commands
m_Makefile->ExpandVariablesInCustomCommands();
// build any targets // build any targets
cmTargets &tgts = m_Makefile->GetTargets(); cmTargets &tgts = m_Makefile->GetTargets();
for(cmTargets::iterator l = tgts.begin(); for(cmTargets::iterator l = tgts.begin();
@ -170,11 +167,10 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule()
makefileIn += "/"; makefileIn += "/";
makefileIn += "CMakeLists.txt"; makefileIn += "CMakeLists.txt";
makefileIn = this->ConvertToRelativeOutputPath(makefileIn.c_str()); makefileIn = this->ConvertToRelativeOutputPath(makefileIn.c_str());
std::string dsprule = "${CMAKE_COMMAND}"; const char* dsprule = m_Makefile->GetRequiredDefinition("CMAKE_COMMAND");
m_Makefile->ExpandVariablesInString(dsprule); cmCustomCommandLine commandLine;
dsprule = this->ConvertToRelativeOutputPath(dsprule.c_str()); commandLine.push_back(dsprule);
std::vector<std::string> argv; commandLine.push_back(makefileIn);
argv.push_back(makefileIn);
makefileIn = m_Makefile->GetStartDirectory(); makefileIn = m_Makefile->GetStartDirectory();
makefileIn += "/"; makefileIn += "/";
makefileIn += "CMakeLists.txt"; makefileIn += "CMakeLists.txt";
@ -182,11 +178,11 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule()
args = "-H"; args = "-H";
args += args +=
this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory()); this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory());
argv.push_back(args); commandLine.push_back(args);
args = "-B"; args = "-B";
args += args +=
this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory()); this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory());
argv.push_back(args); commandLine.push_back(args);
std::string configFile = std::string configFile =
m_Makefile->GetRequiredDefinition("CMAKE_ROOT"); m_Makefile->GetRequiredDefinition("CMAKE_ROOT");
@ -205,9 +201,12 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule()
{ {
listFiles.push_back(configFile); listFiles.push_back(configFile);
} }
m_Makefile->AddCustomCommandToOutput(dspname.c_str(), dsprule.c_str(),
argv, makefileIn.c_str(), listFiles, cmCustomCommandLines commandLines;
NULL, true); commandLines.push_back(commandLine);
const char* no_comment = 0;
m_Makefile->AddCustomCommandToOutput(dspname.c_str(), listFiles, makefileIn.c_str(),
commandLines, no_comment, true);
} }
@ -234,26 +233,19 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
target.GetPostBuildCommands().begin(); target.GetPostBuildCommands().begin();
cr != target.GetPostBuildCommands().end(); ++cr) cr != target.GetPostBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
char *output = new char [ char *output = new char [
strlen(m_Makefile->GetStartOutputDirectory()) + strlen(m_Makefile->GetStartOutputDirectory()) +
strlen(libName) + 30]; strlen(libName) + 30];
sprintf(output,"%s/%s_force_%i", sprintf(output,"%s/%s_force_%i",
m_Makefile->GetStartOutputDirectory(), m_Makefile->GetStartOutputDirectory(),
libName, count); libName, count);
std::vector<std::string> args; const char* no_main_dependency = 0;
// This is a hack to fix a problem with cmCustomCommand const char* no_comment = 0;
// The cmCustomCommand should store the arguments as a vector m_Makefile->AddCustomCommandToOutput(output,
// and not a string, and the cmAddCustomTargetCommand should cr->GetDepends(),
// not EscapeSpaces. no_main_dependency,
args.push_back("This is really a single argument do not escape spaces"); cr->GetCommandLines(),
args.push_back(cc.GetArguments()); no_comment);
m_Makefile->AddCustomCommandToOutput(output,
cc.GetCommand().c_str(),
args,
0,
cc.GetDepends());
cmSourceFile* outsf = cmSourceFile* outsf =
m_Makefile->GetSourceFileWithOutput(output); m_Makefile->GetSourceFileWithOutput(output);
target.GetSourceFiles().push_back(outsf); target.GetSourceFiles().push_back(outsf);
@ -380,18 +372,13 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
} }
if (command) if (command)
{ {
std::string totalCommandStr; std::string script = this->ConstructScript(command->GetCommandLines());
totalCommandStr = const char* comment = command->GetComment();
this->ConvertToRelativeOutputPath(command->GetCommand().c_str());
totalCommandStr += " ";
totalCommandStr += command->GetArguments();
totalCommandStr += "\n";
const char* comment = command->GetComment().c_str();
const char* flags = compileFlags.size() ? compileFlags.c_str(): 0; const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(), this->WriteCustomRule(fout, source.c_str(), script.c_str(),
(*comment?comment:"Custom Rule"), (*comment?comment:"Custom Rule"),
command->GetDepends(), command->GetDepends(),
command->GetOutput().c_str(), flags); command->GetOutput(), flags);
} }
else if(compileFlags.size()) else if(compileFlags.size())
{ {
@ -635,8 +622,6 @@ cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
target.GetPreBuildCommands().begin(); target.GetPreBuildCommands().begin();
cr != target.GetPreBuildCommands().end(); ++cr) cr != target.GetPreBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if (!init) if (!init)
{ {
// header stuff // header stuff
@ -647,15 +632,13 @@ cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
{ {
customRuleCode += "\\\n\t"; customRuleCode += "\\\n\t";
} }
customRuleCode += this->ConvertToRelativeOutputPath(cc.GetCommand().c_str()) + " " + cc.GetArguments(); customRuleCode += this->ConstructScript(cr->GetCommandLines(), "\\\n\t");
} }
for (std::vector<cmCustomCommand>::const_iterator cr = for (std::vector<cmCustomCommand>::const_iterator cr =
target.GetPreLinkCommands().begin(); target.GetPreLinkCommands().begin();
cr != target.GetPreLinkCommands().end(); ++cr) cr != target.GetPreLinkCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if (!init) if (!init)
{ {
// header stuff // header stuff
@ -666,7 +649,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
{ {
customRuleCode += "\\\n\t"; customRuleCode += "\\\n\t";
} }
customRuleCode += this->ConvertToRelativeOutputPath(cc.GetCommand().c_str()) + " " + cc.GetArguments(); customRuleCode += this->ConstructScript(cr->GetCommandLines(), "\\\n\t");
} }
// do the post build rules // do the post build rules
@ -675,8 +658,6 @@ cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
target.GetPostBuildCommands().begin(); target.GetPostBuildCommands().begin();
cr != target.GetPostBuildCommands().end(); ++cr) cr != target.GetPostBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if (!init) if (!init)
{ {
// header stuff // header stuff
@ -687,9 +668,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
{ {
customRuleCode += "\\\n\t"; customRuleCode += "\\\n\t";
} }
customRuleCode += customRuleCode += this->ConstructScript(cr->GetCommandLines(), "\\\n\t");
this->ConvertToRelativeOutputPath(cc.GetCommand().c_str()) +
" " + cc.GetArguments();
} }
customRuleCode += "\n# End Special Build Tool\n"; customRuleCode += "\n# End Special Build Tool\n";

View File

@ -89,9 +89,6 @@ void cmLocalVisualStudio7Generator::OutputVCProjFile()
// clear project names // clear project names
m_CreatedProjectNames.clear(); m_CreatedProjectNames.clear();
// expand vars for custom commands
m_Makefile->ExpandVariablesInCustomCommands();
// build any targets // build any targets
cmTargets &tgts = m_Makefile->GetTargets(); cmTargets &tgts = m_Makefile->GetTargets();
for(cmTargets::iterator l = tgts.begin(); for(cmTargets::iterator l = tgts.begin();
@ -142,11 +139,10 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule()
makefileIn += "/"; makefileIn += "/";
makefileIn += "CMakeLists.txt"; makefileIn += "CMakeLists.txt";
makefileIn = this->ConvertToRelativeOutputPath(makefileIn.c_str()); makefileIn = this->ConvertToRelativeOutputPath(makefileIn.c_str());
std::string dsprule = "${CMAKE_COMMAND}"; const char* dsprule = m_Makefile->GetRequiredDefinition("CMAKE_COMMAND");
m_Makefile->ExpandVariablesInString(dsprule); cmCustomCommandLine commandLine;
dsprule = this->ConvertToRelativeOutputPath(dsprule.c_str()); commandLine.push_back(dsprule);
std::vector<std::string> argv; commandLine.push_back(makefileIn);
argv.push_back(makefileIn);
makefileIn = m_Makefile->GetStartDirectory(); makefileIn = m_Makefile->GetStartDirectory();
makefileIn += "/"; makefileIn += "/";
makefileIn += "CMakeLists.txt"; makefileIn += "CMakeLists.txt";
@ -154,11 +150,11 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule()
args = "-H"; args = "-H";
args += args +=
this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory()); this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory());
argv.push_back(args); commandLine.push_back(args);
args = "-B"; args = "-B";
args += args +=
this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory()); this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory());
argv.push_back(args); commandLine.push_back(args);
std::string configFile = std::string configFile =
m_Makefile->GetRequiredDefinition("CMAKE_ROOT"); m_Makefile->GetRequiredDefinition("CMAKE_ROOT");
@ -177,9 +173,12 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule()
{ {
listFiles.push_back(configFile); listFiles.push_back(configFile);
} }
m_Makefile->AddCustomCommandToOutput(dspname.c_str(), dsprule.c_str(),
argv, makefileIn.c_str(), listFiles, cmCustomCommandLines commandLines;
NULL, true); commandLines.push_back(commandLine);
const char* no_comment = 0;
m_Makefile->AddCustomCommandToOutput(dspname.c_str(), listFiles, makefileIn.c_str(),
commandLines, no_comment, true);
} }
@ -1031,18 +1030,14 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n"; fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
if (command) if (command)
{ {
std::string totalCommandStr; // Construct the entire set of commands in one string.
totalCommandStr = std::string script = this->ConstructScript(command->GetCommandLines());
this->ConvertToRelativeOutputPath(command->GetCommand().c_str()); const char* comment = command->GetComment();
totalCommandStr += " ";
totalCommandStr += command->GetArguments();
totalCommandStr += "\n";
const char* comment = command->GetComment().c_str();
const char* flags = compileFlags.size() ? compileFlags.c_str(): 0; const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(), this->WriteCustomRule(fout, source.c_str(), script.c_str(),
(*comment?comment:"Custom Rule"), (*comment?comment:"Custom Rule"),
command->GetDepends(), command->GetDepends(),
command->GetOutput().c_str(), flags); command->GetOutput(), flags);
} }
else if(compileFlags.size() || additionalDeps.length()) else if(compileFlags.size() || additionalDeps.length())
{ {
@ -1210,17 +1205,13 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(std::ostream& fout,
target.GetPreBuildCommands().begin(); target.GetPreBuildCommands().begin();
cr != target.GetPreBuildCommands().end(); ++cr) cr != target.GetPreBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if(!init) if(!init)
{ {
fout << "\nCommandLine=\""; fout << "\nCommandLine=\"";
init = true; init = true;
} }
std::string args = cc.GetArguments(); std::string script = this->ConstructScript(cr->GetCommandLines());
cmSystemTools::ReplaceString(args, "\"", "&quot;"); fout << this->EscapeForXML(script.c_str()).c_str();
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " <<
args << "\n";
} }
if (init) if (init)
{ {
@ -1235,17 +1226,13 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(std::ostream& fout,
target.GetPreLinkCommands().begin(); target.GetPreLinkCommands().begin();
cr != target.GetPreLinkCommands().end(); ++cr) cr != target.GetPreLinkCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if(!init) if(!init)
{ {
fout << "\nCommandLine=\""; fout << "\nCommandLine=\"";
init = true; init = true;
} }
std::string args = cc.GetArguments(); std::string script = this->ConstructScript(cr->GetCommandLines());
cmSystemTools::ReplaceString(args, "\"", "&quot;"); fout << this->EscapeForXML(script.c_str()).c_str();
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " <<
args << "\n";
} }
if (init) if (init)
{ {
@ -1260,17 +1247,13 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(std::ostream& fout,
target.GetPostBuildCommands().begin(); target.GetPostBuildCommands().begin();
cr != target.GetPostBuildCommands().end(); ++cr) cr != target.GetPostBuildCommands().end(); ++cr)
{ {
cmCustomCommand cc(*cr);
cc.ExpandVariables(*m_Makefile);
if(!init) if(!init)
{ {
fout << "\nCommandLine=\""; fout << "\nCommandLine=\"";
init = true; init = true;
} }
std::string args = cc.GetArguments(); std::string script = this->ConstructScript(cr->GetCommandLines());
cmSystemTools::ReplaceString(args, "\"", "&quot;"); fout << this->EscapeForXML(script.c_str()).c_str();
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " <<
args << "\n";
} }
if (init) if (init)
{ {
@ -1364,7 +1347,8 @@ void cmLocalVisualStudio7Generator::ConfigureFinalPass()
if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0) if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
{ {
cmCustomCommand cc = l->second.GetPostBuildCommands()[0]; cmCustomCommand cc = l->second.GetPostBuildCommands()[0];
std::string project_name = cc.GetCommand(); const cmCustomCommandLines& cmds = cc.GetCommandLines();
std::string project_name = cmds[0][0];
gg->CreateGUID(project_name.c_str()); gg->CreateGUID(project_name.c_str());
} }
else else

View File

@ -496,278 +496,253 @@ void cmMakefile::ConfigureFinalPass()
} }
} }
//----------------------------------------------------------------------------
// this is the old style signature, we convert to new style void
void cmMakefile::AddCustomCommand(const char* source, cmMakefile::AddCustomCommandToTarget(const char* target,
const char* command, const std::vector<std::string>& depends,
const std::vector<std::string>& commandArgs, const cmCustomCommandLines& commandLines,
const std::vector<std::string>& depends, cmTarget::CustomCommandType type,
const std::vector<std::string>& outputs, const char* comment)
const char *target,
const char *comment)
{ {
if (strcmp(source,target)) // Find the target to which to add the custom command.
cmTargets::iterator ti = m_Targets.find(target);
if(ti != m_Targets.end())
{ {
// what a pain, for backwards compatibility we will try to // Add the command to the appropriate build step for the target.
// convert this to an output based rule... so for each output.. const char* no_output = 0;
for(std::vector<std::string>::const_iterator d = outputs.begin(); cmCustomCommand cc(no_output, depends, commandLines, comment);
d != outputs.end(); ++d) switch(type)
{ {
// if this looks like a real file then use is as the main depend case cmTarget::PRE_BUILD:
cmsys::RegularExpression SourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"); ti->second.GetPreBuildCommands().push_back(cc);
if (SourceFiles.find(source)) break;
case cmTarget::PRE_LINK:
ti->second.GetPreLinkCommands().push_back(cc);
break;
case cmTarget::POST_BUILD:
ti->second.GetPostBuildCommands().push_back(cc);
break;
}
// Add dependencies on commands CMake knows how to build.
for(cmCustomCommandLines::const_iterator cli = commandLines.begin();
cli != commandLines.end(); ++cli)
{
std::string cacheCommand = *cli->begin();
if(const char* knownTarget =
this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
{ {
this->AddCustomCommandToOutput(d->c_str(), command, commandArgs, ti->second.AddUtility(knownTarget);
source, depends, comment);
}
// otherwise do not use a main depend
else
{
std::vector<std::string> depends2 = depends;
depends2.push_back(source);
this->AddCustomCommandToOutput(d->c_str(), command, commandArgs,
0, depends2, comment);
}
// add the output to the target?
std::string sname = *d;
sname += ".rule";
this->ExpandVariablesInString(sname);
// if the rule was added to the source,
// then add the source to the target
if (!this->GetSource(sname.c_str()))
{
if (m_Targets.find(target) != m_Targets.end())
{
m_Targets[target].GetSourceLists().push_back(source);
}
else
{
cmSystemTools::Error("Attempt to add a custom rule to a target that does not exist yet for target ", target);
return;
}
} }
} }
} }
else
{
this->AddCustomCommandToTarget(target, command, commandArgs,
cmTarget::POST_BUILD, comment, depends);
}
} }
void cmMakefile::AddCustomCommand(const char* source, //----------------------------------------------------------------------------
const char* command, void
const std::vector<std::string>& commandArgs, cmMakefile::AddCustomCommandToOutput(const char* output,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
const char* output, const char* main_dependency,
const char *target) const cmCustomCommandLines& commandLines,
const char* comment,
bool replace)
{ {
std::vector<std::string> outputs; // Choose a source file on which to store the custom command.
outputs.push_back(output); cmSourceFile* file = 0;
this->AddCustomCommand(source, command, commandArgs, depends, if(main_dependency && main_dependency[0])
outputs, target);
}
void cmMakefile::
AddCustomCommandToOutput(const char* outputIn,
const char* inCommand,
const std::vector<std::string>& commandArgs,
const char *main_dependency,
const std::vector<std::string>& depends,
const char *comment,
bool replace)
{
std::string expandC;
std::string combinedArgs;
std::string command = inCommand;
// process the command's string
this->ExpandVariablesInString(command);
command = cmSystemTools::EscapeSpaces(command.c_str());
unsigned int i;
bool escapeSpaces = true;
for (i = 0; i < commandArgs.size(); ++i)
{ {
expandC = commandArgs[i].c_str(); // The main dependency was specified. Use it unless a different
// This is a hack to fix a problem with cmCustomCommand // custom command already used it.
// The cmCustomCommand should store the arguments as a vector file = this->GetSource(main_dependency);
// and not a string, and the cmAddCustomTargetCommand should if(file && file->GetCustomCommand() && !replace)
// not EscapeSpaces.
if(expandC == "This is really a single argument do not escape spaces")
{ {
escapeSpaces = false; // The main dependency already has a custom command.
} if(commandLines == file->GetCustomCommand()->GetCommandLines())
else
{
this->ExpandVariablesInString(expandC);
if(escapeSpaces)
{
combinedArgs += cmSystemTools::EscapeSpaces(expandC.c_str());
}
else
{
combinedArgs += expandC;
}
combinedArgs += " ";
}
}
cmSourceFile *file = 0;
// setup the output name and make sure we expand any variables
std::string output = outputIn;
this->ExpandVariablesInString(output);
std::string outName = output;
outName += ".rule";
// setup the main dependency name and expand vars of course
std::string mainDepend;
if (main_dependency && main_dependency[0] != '\0')
{
mainDepend = main_dependency;
this->ExpandVariablesInString(mainDepend);
}
// OK this rule will be placed on a generated output file unless the main
// depednency was specified.
if (main_dependency && main_dependency[0] != '\0')
{
file = this->GetSource(mainDepend.c_str());
if (file && file->GetCustomCommand() && !replace)
{
cmCustomCommand* cc = file->GetCustomCommand();
// if the command and args are the same
// as the command already there, then silently skip
// this add command
if(cc->IsEquivalent(command.c_str(), combinedArgs.c_str()))
{ {
// The existing custom command is identical. Silently ignore
// the duplicate.
return; return;
} }
// generate a source instead else
file = 0; {
// The existing custom command is different. We need to
// generate a rule file for this new command.
file = 0;
}
} }
else else
{ {
file = this->GetOrCreateSource(mainDepend.c_str()); // The main dependency does not have a custom command or we are
// allowed to replace it. Use it to store the command.
file = this->GetOrCreateSource(main_dependency);
} }
} }
if (!file) // Generate a rule file if the main dependency is not available.
if(!file)
{ {
// Construct a rule file associated with the output produced.
std::string outName = output;
outName += ".rule";
// Check if the rule file already exists.
file = this->GetSource(outName.c_str()); file = this->GetSource(outName.c_str());
if (file && file->GetCustomCommand() && !replace) if(file && file->GetCustomCommand() && !replace)
{ {
cmCustomCommand* cc = file->GetCustomCommand(); // The rule file already exists.
// if the command and args are the same if(commandLines != file->GetCustomCommand()->GetCommandLines())
// as the command already there, then silently skip
// this add command
if(cc->IsEquivalent(command.c_str(), combinedArgs.c_str()))
{ {
return; cmSystemTools::Error("Attempt to add a custom rule to output \"",
output, "\" which already has a custom rule.");
} }
// produce error if two different commands are given to produce
// the same output
cmSystemTools::Error("Attempt to add a custom rule to an output that already"
" has a custom rule. For output: ", outputIn);
return; return;
} }
// create a cmSourceFile for the output
// Create a cmSourceFile for the rule file.
file = this->GetOrCreateSource(outName.c_str(), true); file = this->GetOrCreateSource(outName.c_str(), true);
if(file)
{
// always mark as generated
file->SetProperty("GENERATED","1");
}
} }
// always create the output and mark it generated // Always create the output and mark it generated.
if(cmSourceFile *out = this->GetOrCreateSource(output.c_str(), true)) if(cmSourceFile* out = this->GetOrCreateSource(output, true))
{ {
out->SetProperty("GENERATED","1"); out->SetProperty("GENERATED", "1");
} }
// Construct a complete list of dependencies.
std::vector<std::string> depends2(depends); std::vector<std::string> depends2(depends);
if (main_dependency && main_dependency[0] != '\0') if(main_dependency && main_dependency[0])
{ {
depends2.push_back(mainDepend.c_str()); depends2.push_back(main_dependency);
}
cmCustomCommand *cc =
new cmCustomCommand(command.c_str(),combinedArgs.c_str(),depends2,
output.c_str());
if ( comment && comment[0] )
{
cc->SetComment(comment);
} }
// Attach the custom command to the file.
if(file) if(file)
{ {
cmCustomCommand* cc =
new cmCustomCommand(output, depends2, commandLines, comment);
file->SetCustomCommand(cc); file->SetCustomCommand(cc);
} }
} }
void cmMakefile:: //----------------------------------------------------------------------------
AddCustomCommandToTarget(const char* target, const char* command, void
const std::vector<std::string>& commandArgs, cmMakefile::AddCustomCommandOldStyle(const char* target,
cmTarget::CustomCommandType type, const std::vector<std::string>& outputs,
const char *comment) const std::vector<std::string>& depends,
const char* source,
const cmCustomCommandLines& commandLines,
const char* comment)
{ {
std::vector<std::string> empty; // Translate the old-style signature to one of the new-style
this->AddCustomCommandToTarget(target,command,commandArgs,type, // signatures.
comment, empty); if(strcmp(source, target) == 0)
}
void cmMakefile::
AddCustomCommandToTarget(const char* target, const char* command,
const std::vector<std::string>& commandArgs,
cmTarget::CustomCommandType type,
const char *comment,
const std::vector<std::string>& depends)
{
// find the target,
if (m_Targets.find(target) != m_Targets.end())
{ {
std::string expandC = command; // In the old-style signature if the source and target were the
this->ExpandVariablesInString(expandC); // same then it added a post-build rule to the target. Preserve
std::string c = cmSystemTools::EscapeSpaces(expandC.c_str()); // this behavior.
this->AddCustomCommandToTarget(target, depends, commandLines,
std::string combinedArgs; cmTarget::POST_BUILD, comment);
unsigned int i; return;
}
for (i = 0; i < commandArgs.size(); ++i)
// Each output must get its own copy of this rule.
cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
"rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
"hm|hpp|hxx|in|txx|inl)$");
for(std::vector<std::string>::const_iterator oi = outputs.begin();
oi != outputs.end(); ++oi)
{
// Get the name of this output.
const char* output = oi->c_str();
// Choose whether to use a main dependency.
if(sourceFiles.find(source))
{ {
expandC = commandArgs[i].c_str(); // The source looks like a real file. Use it as the main dependency.
this->ExpandVariablesInString(expandC); this->AddCustomCommandToOutput(output, depends, source,
combinedArgs += cmSystemTools::EscapeSpaces(expandC.c_str()); commandLines, comment);
combinedArgs += " ";
} }
else
cmCustomCommand cc(c.c_str(),combinedArgs.c_str(),depends,0);
if ( comment && comment[0] )
{ {
cc.SetComment(comment); // The source may not be a real file. Do not use a main dependency.
const char* no_main_dependency = 0;
std::vector<std::string> depends2 = depends;
depends2.push_back(source);
this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
commandLines, comment);
} }
switch (type)
// If the rule was added to the source (and not a .rule file),
// then add the source to the target to make sure the rule is
// included.
std::string sname = output;
sname += ".rule";
if(!this->GetSource(sname.c_str()))
{ {
case cmTarget::PRE_BUILD: if (m_Targets.find(target) != m_Targets.end())
m_Targets[target].GetPreBuildCommands().push_back(cc); {
break; m_Targets[target].GetSourceLists().push_back(source);
case cmTarget::PRE_LINK: }
m_Targets[target].GetPreLinkCommands().push_back(cc); else
break; {
case cmTarget::POST_BUILD: cmSystemTools::Error("Attempt to add a custom rule to a target "
m_Targets[target].GetPostBuildCommands().push_back(cc); "that does not exist yet for target ", target);
break; return;
} }
std::string cacheCommand = command;
this->ExpandVariablesInString(cacheCommand);
if(this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
{
m_Targets[target].AddUtility(
this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()));
} }
} }
} }
//----------------------------------------------------------------------------
void cmMakefile::AddUtilityCommand(const char* utilityName, bool all,
const char* output,
const std::vector<std::string>& depends,
const char* command,
const char* arg1,
const char* arg2,
const char* arg3)
{
// Construct the command line for the custom command.
cmCustomCommandLine commandLine;
commandLine.push_back(command);
if(arg1)
{
commandLine.push_back(arg1);
}
if(arg2)
{
commandLine.push_back(arg2);
}
if(arg3)
{
commandLine.push_back(arg3);
}
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
// Call the real signature of this method.
this->AddUtilityCommand(utilityName, all, output, depends, commandLines);
}
//----------------------------------------------------------------------------
void cmMakefile::AddUtilityCommand(const char* utilityName, bool all,
const char* output,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines)
{
// Create a target instance for this utility.
cmTarget target;
target.SetType(cmTarget::UTILITY, utilityName);
target.SetInAll(all);
// Store the custom command in the target.
cmCustomCommand cc(output, depends, commandLines, 0);
target.GetPostBuildCommands().push_back(cc);
// Add the target to the set of targets.
m_Targets.insert(cmTargets::value_type(utilityName, target));
}
void cmMakefile::AddDefineFlag(const char* flag) void cmMakefile::AddDefineFlag(const char* flag)
{ {
m_DefineFlags += " "; m_DefineFlags += " ";
@ -1128,48 +1103,6 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
return &it->second; return &it->second;
} }
void cmMakefile::AddUtilityCommand(const char* utilityName,
const char* command,
const char* arguments,
bool all,
const std::vector<std::string> &depends)
{
std::vector<std::string> empty;
this->AddUtilityCommand(utilityName,command,arguments,all,
depends, empty);
}
void cmMakefile::AddUtilityCommand(const char* utilityName,
const char* command,
const char* arguments,
bool all,
const std::vector<std::string> &dep,
const std::vector<std::string> &out)
{
cmTarget target;
target.SetType(cmTarget::UTILITY, utilityName);
target.SetInAll(all);
if (out.size() > 1)
{
cmSystemTools::Error(
"Utility targets can only have one output. For utilityNamed: ",
utilityName);
return;
}
if (out.size())
{
cmCustomCommand cc(command, arguments, dep, out[0].c_str());
target.GetPostBuildCommands().push_back(cc);
}
else
{
cmCustomCommand cc(command, arguments, dep, (const char *)0);
target.GetPostBuildCommands().push_back(cc);
}
m_Targets.insert(cmTargets::value_type(utilityName,target));
}
cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname) cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
{ {
std::string name = cname; std::string name = cname;
@ -1323,42 +1256,6 @@ void cmMakefile::ExpandVariables()
} }
} }
void cmMakefile::ExpandVariablesInCustomCommands()
{
// do source files
for(std::vector<cmSourceFile*>::iterator i = m_SourceFiles.begin();
i != m_SourceFiles.end(); ++i)
{
cmCustomCommand *cc = (*i)->GetCustomCommand();
if (cc)
{
cc->ExpandVariables(*this);
}
}
// now do targets
std::vector<cmCustomCommand>::iterator ic;
for (cmTargets::iterator l = m_Targets.begin();
l != m_Targets.end(); l++)
{
for (ic = l->second.GetPreBuildCommands().begin();
ic != l->second.GetPreBuildCommands().end(); ++ic)
{
ic->ExpandVariables(*this);
}
for (ic = l->second.GetPreLinkCommands().begin();
ic != l->second.GetPreLinkCommands().end(); ++ic)
{
ic->ExpandVariables(*this);
}
for (ic = l->second.GetPostBuildCommands().begin();
ic != l->second.GetPostBuildCommands().end(); ++ic)
{
ic->ExpandVariables(*this);
}
}
}
bool cmMakefile::IsOn(const char* name) const bool cmMakefile::IsOn(const char* name) const
{ {
const char* value = this->GetDefinition(name); const char* value = this->GetDefinition(name);

View File

@ -130,47 +130,26 @@ public:
* Print the object state to std::cout. * Print the object state to std::cout.
*/ */
void Print() const; void Print() const;
/**
* Add a custom command to the build.
*/
void AddCustomCommandToOutput(const char* output,
const char* command,
const std::vector<std::string>& commandArgs,
const char *main_dependency,
const std::vector<std::string>& depends,
const char *comment = 0,
bool replace = false);
void AddCustomCommandToTarget(const char* target,
const char* command,
const std::vector<std::string>& commandArgs,
cmTarget::CustomCommandType type,
const char *comment = 0);
void AddCustomCommandToTarget(const char* target,
const char* command,
const std::vector<std::string>& commandArgs,
cmTarget::CustomCommandType type,
const char *comment,
const std::vector<std::string>& depends);
/**
* Add a custom command to the build.
*/
void AddCustomCommand(const char* source,
const char* command,
const std::vector<std::string>& commandArgs,
const std::vector<std::string>& depends,
const std::vector<std::string>& outputs,
const char *target,
const char *comment = 0);
void AddCustomCommand(const char* source, /** Add a custom command to the build. */
const char* command, void AddCustomCommandToTarget(const char* target,
const std::vector<std::string>& commandArgs, const std::vector<std::string>& depends,
const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines,
const char* output, cmTarget::CustomCommandType type,
const char* target); const char* comment);
void AddCustomCommandToOutput(const char* output,
const std::vector<std::string>& depends,
const char* main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment,
bool replace = false);
void AddCustomCommandOldStyle(const char* target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
const char* source,
const cmCustomCommandLines& commandLines,
const char* comment);
/** /**
* Add a define flag to the build. * Add a define flag to the build.
*/ */
@ -184,20 +163,20 @@ public:
const std::vector<std::string> &srcs); const std::vector<std::string> &srcs);
/** /**
* Add a utility to the build. A utiltity target is * Add a utility to the build. A utiltity target is a command that
* a command that is run every time a target is built. * is run every time the target is built.
*/ */
void AddUtilityCommand(const char* utilityName, void AddUtilityCommand(const char* utilityName, bool all,
const char* output,
const std::vector<std::string>& depends,
const char* command, const char* command,
const char* arguments, const char* arg1=0,
bool all, const char* arg2=0,
const std::vector<std::string> &depends); const char* arg3=0);
void AddUtilityCommand(const char* utilityName, void AddUtilityCommand(const char* utilityName, bool all,
const char* command, const char* output,
const char* arguments, const std::vector<std::string>& depends,
bool all, const cmCustomCommandLines& commandLines);
const std::vector<std::string> &depends,
const std::vector<std::string> &outputs);
/** /**
* Add a link library to the build. * Add a link library to the build.
@ -577,7 +556,6 @@ public:
* Expand variables in the makefiles ivars such as link directories etc * Expand variables in the makefiles ivars such as link directories etc
*/ */
void ExpandVariables(); void ExpandVariables();
void ExpandVariablesInCustomCommands();
/** /**
* Replace variables and #cmakedefine lines in the given string. * Replace variables and #cmakedefine lines in the given string.

View File

@ -99,19 +99,11 @@ void cmQTWrapCPPCommand::FinalPass()
// first we add the rules for all the .h to Moc files // first we add the rules for all the .h to Moc files
size_t lastClass = m_WrapClasses.size(); size_t lastClass = m_WrapClasses.size();
std::vector<std::string> depends; std::vector<std::string> depends;
std::string moc_exe = "${QT_MOC_EXECUTABLE}"; const char* moc_exe = m_Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// wrap all the .h files // wrap all the .h files
depends.push_back(moc_exe); depends.push_back(moc_exe);
const char * GENERATED_QT_FILES_value=
m_Makefile->GetDefinition("GENERATED_QT_FILES");
std::string moc_list("");
if (GENERATED_QT_FILES_value!=0)
{
moc_list=moc_list+GENERATED_QT_FILES_value;
}
for(size_t classNum = 0; classNum < lastClass; classNum++) for(size_t classNum = 0; classNum < lastClass; classNum++)
{ {
// Add output to build list // Add output to build list
@ -122,28 +114,23 @@ void cmQTWrapCPPCommand::FinalPass()
res += "/"; res += "/";
res += m_WrapClasses[classNum].GetSourceName() + ".cxx"; res += m_WrapClasses[classNum].GetSourceName() + ".cxx";
moc_list = moc_list + " " + res; cmCustomCommandLine commandLine;
commandLine.push_back(moc_exe);
std::vector<std::string> args; commandLine.push_back("-o");
args.push_back("-o"); commandLine.push_back(res);
args.push_back(res); commandLine.push_back(m_WrapHeaders[classNum]);
args.push_back(m_WrapHeaders[classNum]);
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
std::vector<std::string> realdepends = depends; std::vector<std::string> realdepends = depends;
realdepends.push_back(m_WrapHeaders[classNum]); realdepends.push_back(m_WrapHeaders[classNum]);
m_Makefile->AddCustomCommandToOutput( const char* no_main_dependency = 0;
res.c_str(), m_Makefile->AddCustomCommandToOutput(res.c_str(),
moc_exe.c_str(), realdepends,
args, no_main_dependency,
0, commandLines,
realdepends, "QT Wrapped File");
"QT Wrapped File",
0);
} }
m_Makefile->AddDefinition("GENERATED_QT_FILES",moc_list.c_str());
} }

View File

@ -125,25 +125,15 @@ void cmQTWrapUICommand::FinalPass()
// first we add the rules for all the .ui to .h and .cxx files // first we add the rules for all the .ui to .h and .cxx files
size_t lastHeadersClass = m_WrapHeadersClasses.size(); size_t lastHeadersClass = m_WrapHeadersClasses.size();
std::vector<std::string> depends; std::vector<std::string> depends;
std::string uic_exe = "${QT_UIC_EXECUTABLE}"; const char* uic_exe = m_Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE");
std::string moc_exe = "${QT_MOC_EXECUTABLE}"; const char* moc_exe = m_Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// wrap all the .h files // wrap all the .h files
depends.push_back(uic_exe); depends.push_back(uic_exe);
const char * GENERATED_QT_FILES_value=
m_Makefile->GetDefinition("GENERATED_QT_FILES");
std::string ui_list("");
if (GENERATED_QT_FILES_value!=0)
{
ui_list=ui_list+GENERATED_QT_FILES_value;
}
for(size_t classNum = 0; classNum < lastHeadersClass; classNum++) for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
{ {
// set up .ui to .h and .cxx command // set up .ui to .h and .cxx command
std::string hres = m_Makefile->GetCurrentOutputDirectory(); std::string hres = m_Makefile->GetCurrentOutputDirectory();
hres += "/"; hres += "/";
hres += m_WrapHeadersClasses[classNum].GetSourceName() + "." + hres += m_WrapHeadersClasses[classNum].GetSourceName() + "." +
@ -159,52 +149,58 @@ void cmQTWrapUICommand::FinalPass()
mocres += m_WrapMocClasses[classNum].GetSourceName() + "." + mocres += m_WrapMocClasses[classNum].GetSourceName() + "." +
m_WrapMocClasses[classNum].GetSourceExtension(); m_WrapMocClasses[classNum].GetSourceExtension();
ui_list = ui_list + " " + hres + " " + cxxres + " " + mocres; cmCustomCommandLine hCommand;
hCommand.push_back(uic_exe);
std::vector<std::string> hargs; hCommand.push_back("-o");
hargs.push_back("-o"); hCommand.push_back(hres);
hargs.push_back(hres); hCommand.push_back(m_WrapUserInterface[classNum]);
hargs.push_back(m_WrapUserInterface[classNum]); cmCustomCommandLines hCommandLines;
hCommandLines.push_back(hCommand);
std::vector<std::string> cxxargs; cmCustomCommandLine cxxCommand;
cxxargs.push_back("-impl"); cxxCommand.push_back(uic_exe);
cxxargs.push_back(hres); cxxCommand.push_back("-impl");
cxxargs.push_back("-o"); cxxCommand.push_back(hres);
cxxargs.push_back(cxxres); cxxCommand.push_back("-o");
cxxargs.push_back(m_WrapUserInterface[classNum]); cxxCommand.push_back(cxxres);
cxxCommand.push_back(m_WrapUserInterface[classNum]);
cmCustomCommandLines cxxCommandLines;
cxxCommandLines.push_back(cxxCommand);
std::vector<std::string> mocargs; std::vector<std::string> mocargs;
mocargs.push_back("-o"); cmCustomCommandLine mocCommand;
mocargs.push_back(mocres); mocCommand.push_back(moc_exe);
mocargs.push_back(hres); mocCommand.push_back("-o");
mocCommand.push_back(mocres);
mocCommand.push_back(hres);
cmCustomCommandLines mocCommandLines;
mocCommandLines.push_back(mocCommand);
depends.clear(); depends.clear();
depends.push_back(m_WrapUserInterface[classNum]); depends.push_back(m_WrapUserInterface[classNum]);
m_Makefile->AddCustomCommandToOutput( const char* no_main_dependency = 0;
hres.c_str(), const char* no_comment = 0;
uic_exe.c_str(), hargs, 0, m_Makefile->AddCustomCommandToOutput(hres.c_str(),
depends); depends,
no_main_dependency,
hCommandLines,
no_comment);
depends.push_back(hres); depends.push_back(hres);
m_Makefile->AddCustomCommandToOutput( m_Makefile->AddCustomCommandToOutput(cxxres.c_str(),
cxxres.c_str(), depends,
uic_exe.c_str(), cxxargs, 0, depends); no_main_dependency,
cxxCommandLines,
no_comment);
depends.clear(); depends.clear();
depends.push_back(hres); depends.push_back(hres);
m_Makefile->AddCustomCommandToOutput( m_Makefile->AddCustomCommandToOutput(mocres.c_str(),
mocres.c_str(), depends,
moc_exe.c_str(), mocargs, 0, depends); no_main_dependency,
mocCommandLines,
no_comment);
} }
m_Makefile->AddDefinition("GENERATED_QT_FILES",ui_list.c_str());
} }

View File

@ -49,7 +49,7 @@ bool cmVTKWrapJavaCommand::InitialPass(std::vector<std::string> const& argsIn)
} }
// Prepare java dependency file // Prepare java dependency file
std::string resultDirectory = "${VTK_JAVA_HOME}"; const char* resultDirectory = m_Makefile->GetRequiredDefinition("VTK_JAVA_HOME");
std::string res = m_Makefile->GetCurrentOutputDirectory(); std::string res = m_Makefile->GetCurrentOutputDirectory();
std::string depFileName = res + "/JavaDependencies.cmake"; std::string depFileName = res + "/JavaDependencies.cmake";
std::ofstream depFile(depFileName.c_str()); std::ofstream depFile(depFileName.c_str());
@ -88,7 +88,10 @@ bool cmVTKWrapJavaCommand::InitialPass(std::vector<std::string> const& argsIn)
sourceListValue += newName + ".cxx"; sourceListValue += newName + ".cxx";
// Write file to java dependency file // Write file to java dependency file
std::string jafaFile = resultDirectory + "/" + srcName + ".java"; std::string jafaFile = resultDirectory;
jafaFile += "/";
jafaFile += srcName;
jafaFile += ".java";
depFile << " " << jafaFile << std::endl; depFile << " " << jafaFile << std::endl;
} }
} }
@ -107,18 +110,15 @@ void cmVTKWrapJavaCommand::FinalPass()
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> depends2; std::vector<std::string> depends2;
std::vector<std::string> alldepends; std::vector<std::string> alldepends;
std::vector<std::string> empty; const char* wjava = m_Makefile->GetRequiredDefinition("VTK_WRAP_JAVA_EXE");
std::string wjava = "${VTK_WRAP_JAVA_EXE}"; const char* pjava = m_Makefile->GetRequiredDefinition("VTK_PARSE_JAVA_EXE");
std::string pjava = "${VTK_PARSE_JAVA_EXE}"; const char* hints = m_Makefile->GetDefinition("VTK_WRAP_HINTS");
std::string hints = "${VTK_WRAP_HINTS}"; const char* resultDirectory = m_Makefile->GetRequiredDefinition("VTK_JAVA_HOME");
std::string resultDirectory = "${VTK_JAVA_HOME}";
m_Makefile->ExpandVariablesInString(hints);
// wrap all the .h files // wrap all the .h files
depends.push_back(wjava); depends.push_back(wjava);
depends2.push_back(pjava); depends2.push_back(pjava);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) if(hints)
{ {
depends.push_back(hints); depends.push_back(hints);
depends2.push_back(hints); depends2.push_back(hints);
@ -131,45 +131,57 @@ void cmVTKWrapJavaCommand::FinalPass()
std::string res = m_Makefile->GetCurrentOutputDirectory(); std::string res = m_Makefile->GetCurrentOutputDirectory();
res += "/"; res += "/";
res += m_WrapClasses[classNum].GetSourceName() + ".cxx"; res += m_WrapClasses[classNum].GetSourceName() + ".cxx";
std::string res2 = resultDirectory + "/" + std::string res2 = resultDirectory;
m_OriginalNames[classNum] + ".java"; res2 += "/";
res2 += m_OriginalNames[classNum];
res2 += ".java";
std::vector<std::string> args; cmCustomCommandLine commandLineW;
args.push_back(m_WrapHeaders[classNum]); commandLineW.push_back(wjava);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) commandLineW.push_back(m_WrapHeaders[classNum]);
if(hints)
{ {
args.push_back(hints); commandLineW.push_back(hints);
} }
args.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1")); commandLineW.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1"));
args.push_back(res); commandLineW.push_back(res);
m_Makefile->AddCustomCommand(m_WrapHeaders[classNum].c_str(), cmCustomCommandLines commandLines;
wjava.c_str(), args, depends, commandLines.push_back(commandLineW);
res.c_str(), m_LibraryName.c_str()); std::vector<std::string> outputs;
outputs.push_back(res);
const char* no_comment = 0;
m_Makefile->AddCustomCommandOldStyle(m_LibraryName.c_str(),
outputs,
depends,
m_WrapHeaders[classNum].c_str(),
commandLines,
no_comment);
std::vector<std::string> args2; cmCustomCommandLine commandLineP;
args2.push_back(m_WrapHeaders[classNum]); commandLineP.push_back(pjava);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) commandLineP.push_back(m_WrapHeaders[classNum]);
if(hints)
{ {
args2.push_back(hints); commandLineP.push_back(hints);
} }
args2.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1")); commandLineP.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1"));
args2.push_back(res2); commandLineP.push_back(res2);
m_Makefile->AddCustomCommand(m_WrapHeaders[classNum].c_str(), cmCustomCommandLines commandLines2;
pjava.c_str(), args2, depends2, commandLines2.push_back(commandLineP);
res2.c_str(), m_LibraryName.c_str()); std::vector<std::string> outputs2;
outputs2.push_back(res2);
m_Makefile->AddCustomCommandOldStyle(m_LibraryName.c_str(),
outputs2,
depends2,
m_WrapHeaders[classNum].c_str(),
commandLines2,
no_comment);
alldepends.push_back(res2); alldepends.push_back(res2);
} }
const char* no_output = 0;
m_Makefile->AddUtilityCommand((m_LibraryName+"JavaClasses").c_str(), m_Makefile->AddUtilityCommand((m_LibraryName+"JavaClasses").c_str(),
"", true, no_output, alldepends, "");
"",
true,
alldepends,
empty);
} }

View File

@ -102,14 +102,12 @@ void cmVTKWrapPythonCommand::FinalPass()
// first we add the rules for all the .h to Python.cxx files // first we add the rules for all the .h to Python.cxx files
size_t lastClass = m_WrapClasses.size(); size_t lastClass = m_WrapClasses.size();
std::vector<std::string> depends; std::vector<std::string> depends;
std::string wpython = "${VTK_WRAP_PYTHON_EXE}"; const char* wpython = m_Makefile->GetRequiredDefinition("VTK_WRAP_PYTHON_EXE");
std::string hints = "${VTK_WRAP_HINTS}"; const char* hints = m_Makefile->GetDefinition("VTK_WRAP_HINTS");
m_Makefile->ExpandVariablesInString(hints);
// wrap all the .h files // wrap all the .h files
depends.push_back(wpython); depends.push_back(wpython);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) if(hints)
{ {
depends.push_back(hints); depends.push_back(hints);
} }
@ -119,18 +117,27 @@ void cmVTKWrapPythonCommand::FinalPass()
std::string res = m_Makefile->GetCurrentOutputDirectory(); std::string res = m_Makefile->GetCurrentOutputDirectory();
res += "/"; res += "/";
res += m_WrapClasses[classNum].GetSourceName() + ".cxx"; res += m_WrapClasses[classNum].GetSourceName() + ".cxx";
std::vector<std::string> args; cmCustomCommandLine commandLine;
args.push_back(m_WrapHeaders[classNum]); commandLine.push_back(wpython);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) commandLine.push_back(m_WrapHeaders[classNum]);
if(hints)
{ {
args.push_back(hints); commandLine.push_back(hints);
} }
args.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1")); commandLine.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1"));
args.push_back(res); commandLine.push_back(res);
m_Makefile->AddCustomCommand(m_WrapHeaders[classNum].c_str(), cmCustomCommandLines commandLines;
wpython.c_str(), args, depends, commandLines.push_back(commandLine);
res.c_str(), m_LibraryName.c_str()); std::vector<std::string> outputs;
outputs.push_back(res);
const char* no_comment = 0;
m_Makefile->AddCustomCommandOldStyle(m_LibraryName.c_str(),
outputs,
depends,
m_WrapHeaders[classNum].c_str(),
commandLines,
no_comment);
} }
} }

View File

@ -144,35 +144,42 @@ void cmVTKWrapTclCommand::FinalPass()
// first we add the rules for all the .h to Tcl.cxx files // first we add the rules for all the .h to Tcl.cxx files
size_t lastClass = m_WrapClasses.size(); size_t lastClass = m_WrapClasses.size();
std::vector<std::string> depends; std::vector<std::string> depends;
std::string wtcl = "${VTK_WRAP_TCL_EXE}"; const char* wtcl = m_Makefile->GetRequiredDefinition("VTK_WRAP_TCL_EXE");
std::string hints = "${VTK_WRAP_HINTS}"; const char* hints = m_Makefile->GetDefinition("VTK_WRAP_HINTS");
m_Makefile->ExpandVariablesInString(hints);
// wrap all the .h files // wrap all the .h files
depends.push_back(wtcl); depends.push_back(wtcl);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) if(hints)
{ {
depends.push_back(hints); depends.push_back(hints);
} }
for(size_t classNum = 0; classNum < lastClass; classNum++) for(size_t classNum = 0; classNum < lastClass; classNum++)
{ {
m_Makefile->AddSource(m_WrapClasses[classNum]); m_Makefile->AddSource(m_WrapClasses[classNum]);
std::vector<std::string> args; cmCustomCommandLine commandLine;
args.push_back(m_WrapHeaders[classNum]); commandLine.push_back(wtcl);
if (strcmp("${VTK_WRAP_HINTS}",hints.c_str())) commandLine.push_back(m_WrapHeaders[classNum]);
if(hints)
{ {
args.push_back(hints); commandLine.push_back(hints);
} }
args.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1")); commandLine.push_back((m_WrapClasses[classNum].GetPropertyAsBool("ABSTRACT") ? "0" : "1"));
std::string res = m_Makefile->GetCurrentOutputDirectory(); std::string res = m_Makefile->GetCurrentOutputDirectory();
res += "/"; res += "/";
res += m_WrapClasses[classNum].GetSourceName() + ".cxx"; res += m_WrapClasses[classNum].GetSourceName() + ".cxx";
args.push_back(res); commandLine.push_back(res);
m_Makefile->AddCustomCommand(m_WrapHeaders[classNum].c_str(), cmCustomCommandLines commandLines;
wtcl.c_str(), args, depends, commandLines.push_back(commandLine);
res.c_str(), m_LibraryName.c_str()); std::vector<std::string> outputs;
outputs.push_back(res);
const char* no_comment = 0;
m_Makefile->AddCustomCommandOldStyle(m_LibraryName.c_str(),
outputs,
depends,
m_WrapHeaders[classNum].c_str(),
commandLines,
no_comment);
} }
} }