yikes added new custom command support
This commit is contained in:
parent
4f55e4870d
commit
ba68f771b3
|
@ -159,6 +159,12 @@ IF(BUILD_TESTING)
|
||||||
ADD_TEST(DumpDocumentation ${EXECUTABLE_OUTPUT_PATH}/DumpDocumentation
|
ADD_TEST(DumpDocumentation ${EXECUTABLE_OUTPUT_PATH}/DumpDocumentation
|
||||||
--all-for-coverage)
|
--all-for-coverage)
|
||||||
|
|
||||||
|
ADD_TEST(CustomCommand ${EXECUTABLE_OUTPUT_PATH}/cmaketest
|
||||||
|
${CMake_SOURCE_DIR}/Tests/CustomCommand
|
||||||
|
${CMake_BINARY_DIR}/Tests/CustomCommand
|
||||||
|
CustomCommand
|
||||||
|
${CMake_BINARY_DIR}/Tests/CustomCommand/bin)
|
||||||
|
|
||||||
ADD_TEST(SystemInformation ${EXECUTABLE_OUTPUT_PATH}/cmaketest
|
ADD_TEST(SystemInformation ${EXECUTABLE_OUTPUT_PATH}/cmaketest
|
||||||
${CMake_SOURCE_DIR}/Tests/SystemInformation
|
${CMake_SOURCE_DIR}/Tests/SystemInformation
|
||||||
${CMake_BINARY_DIR}/Tests/SystemInformation
|
${CMake_BINARY_DIR}/Tests/SystemInformation
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
|
|
||||||
=========================================================================*/
|
=========================================================================*/
|
||||||
#include "cmAddCustomCommandCommand.h"
|
#include "cmAddCustomCommandCommand.h"
|
||||||
|
#include "cmTarget.h"
|
||||||
|
|
||||||
// cmAddCustomCommandCommand
|
// cmAddCustomCommandCommand
|
||||||
bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args)
|
bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args)
|
||||||
{
|
{
|
||||||
/* Let's complain at the end of this function about the lack of a particular
|
/* Let's complain at the end of this function about the lack of a particular
|
||||||
arg. For the moment, let's say that COMMAND, TARGET are always
|
arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
|
||||||
required.
|
are required.
|
||||||
*/
|
*/
|
||||||
if (args.size() < 4)
|
if (args.size() < 4)
|
||||||
{
|
{
|
||||||
|
@ -30,15 +30,19 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string source, command, target, comment;
|
std::string source, command, target, comment, output, main_dependency;
|
||||||
std::vector<std::string> command_args, depends, outputs;
|
std::vector<std::string> command_args, depends, outputs;
|
||||||
|
|
||||||
|
cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
|
||||||
|
|
||||||
enum tdoing {
|
enum tdoing {
|
||||||
doing_source,
|
doing_source,
|
||||||
doing_command,
|
doing_command,
|
||||||
doing_target,
|
doing_target,
|
||||||
doing_args,
|
doing_args,
|
||||||
doing_depends,
|
doing_depends,
|
||||||
|
doing_main_dependency,
|
||||||
|
doing_output,
|
||||||
doing_outputs,
|
doing_outputs,
|
||||||
doing_comment,
|
doing_comment,
|
||||||
doing_nothing
|
doing_nothing
|
||||||
|
@ -58,6 +62,18 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
|
||||||
{
|
{
|
||||||
doing = doing_command;
|
doing = doing_command;
|
||||||
}
|
}
|
||||||
|
else if(copy == "PRE_BUILD")
|
||||||
|
{
|
||||||
|
cctype = cmTarget::PRE_BUILD;
|
||||||
|
}
|
||||||
|
else if(copy == "PRE_LINK")
|
||||||
|
{
|
||||||
|
cctype = cmTarget::PRE_LINK;
|
||||||
|
}
|
||||||
|
else if(copy == "POST_BUILD")
|
||||||
|
{
|
||||||
|
cctype = cmTarget::POST_BUILD;
|
||||||
|
}
|
||||||
else if(copy == "TARGET")
|
else if(copy == "TARGET")
|
||||||
{
|
{
|
||||||
doing = doing_target;
|
doing = doing_target;
|
||||||
|
@ -74,6 +90,14 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
|
||||||
{
|
{
|
||||||
doing = doing_outputs;
|
doing = doing_outputs;
|
||||||
}
|
}
|
||||||
|
else if (copy == "OUTPUT")
|
||||||
|
{
|
||||||
|
doing = doing_output;
|
||||||
|
}
|
||||||
|
else if (copy == "MAIN_DEPENDENCY")
|
||||||
|
{
|
||||||
|
doing = doing_main_dependency;
|
||||||
|
}
|
||||||
else if (copy == "COMMENT")
|
else if (copy == "COMMENT")
|
||||||
{
|
{
|
||||||
doing = doing_comment;
|
doing = doing_comment;
|
||||||
|
@ -85,6 +109,12 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
|
||||||
case doing_source:
|
case doing_source:
|
||||||
source = copy;
|
source = copy;
|
||||||
break;
|
break;
|
||||||
|
case doing_output:
|
||||||
|
output = copy;
|
||||||
|
break;
|
||||||
|
case doing_main_dependency:
|
||||||
|
main_dependency = copy;
|
||||||
|
break;
|
||||||
case doing_command:
|
case doing_command:
|
||||||
command = copy;
|
command = copy;
|
||||||
break;
|
break;
|
||||||
|
@ -114,21 +144,36 @@ bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args
|
||||||
For the moment, let's say that COMMAND, TARGET are always
|
For the moment, let's say that COMMAND, TARGET are always
|
||||||
required.
|
required.
|
||||||
*/
|
*/
|
||||||
|
if (output.empty() && target.empty())
|
||||||
if(target.empty())
|
|
||||||
{
|
{
|
||||||
this->SetError("Wrong syntax. Empty TARGET.");
|
this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If source is empty, use target as source, so that this command
|
// If source is empty, use the target
|
||||||
// can be used to just attach a commmand to a target
|
if(source.empty() && output.empty())
|
||||||
|
|
||||||
if(source.empty())
|
|
||||||
{
|
{
|
||||||
source = target;
|
m_Makefile->AddCustomCommandToTarget(target.c_str(),
|
||||||
|
command.c_str(),
|
||||||
|
command_args,
|
||||||
|
cctype,
|
||||||
|
comment.c_str());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If target is empty, use the output
|
||||||
|
if(target.empty())
|
||||||
|
{
|
||||||
|
m_Makefile->AddCustomCommandToOutput(output.c_str(),
|
||||||
|
command.c_str(),
|
||||||
|
command_args,
|
||||||
|
main_dependency.c_str(),
|
||||||
|
depends,
|
||||||
|
comment.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise backwards compatiblity mode
|
||||||
m_Makefile->AddCustomCommand(source.c_str(),
|
m_Makefile->AddCustomCommand(source.c_str(),
|
||||||
command.c_str(),
|
command.c_str(),
|
||||||
command_args,
|
command_args,
|
||||||
|
|
|
@ -86,42 +86,69 @@ public:
|
||||||
virtual const char* GetFullDocumentation()
|
virtual const char* GetFullDocumentation()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
" ADD_CUSTOM_COMMAND(TARGET target\n"
|
"There are two main signatures for ADD_CUSTOM_COMMAND "
|
||||||
" [SOURCE source]\n"
|
"The first signature is for adding a custom command "
|
||||||
" [COMMAND command]\n"
|
"to a source file.\n"
|
||||||
|
" ADD_CUSTOM_COMMAND(OUTPUT result\n"
|
||||||
|
" COMMAND command\n"
|
||||||
" [ARGS [args...]]\n"
|
" [ARGS [args...]]\n"
|
||||||
|
" [MAIN_DEPENDENCY depend]\n"
|
||||||
" [DEPENDS [depends...]]\n"
|
" [DEPENDS [depends...]]\n"
|
||||||
" [OUTPUTS [outputs...]]\n"
|
|
||||||
" [COMMENT comment])\n"
|
" [COMMENT comment])\n"
|
||||||
"This defines a new command that can be executed during the build "
|
"This defines a new command that can be executed during the build "
|
||||||
"process. In makefile terms this creates a new target in the "
|
"process. In makefile terms this creates a new target in the "
|
||||||
"following form:\n"
|
"following form:\n"
|
||||||
" OUTPUT1: SOURCE DEPENDS\n"
|
" OUTPUT: MAIN_DEPENDENCY DEPENDS\n"
|
||||||
" COMAND ARGS\n"
|
" COMMAND ARGS\n"
|
||||||
" OUTPUT2: SOURCE DEPENDS\n"
|
"\n"
|
||||||
" COMAND ARGS\n"
|
"The second signature adds a custom command to a target "
|
||||||
"The TARGET must be specified, but it is not the make target of the "
|
"such as a library or executable. This is useful for "
|
||||||
"build rule. It is the target (library, executable, or custom target) "
|
"performing an operation before or after building the target "
|
||||||
"that will use the output generated from this rule. This is necessary "
|
"\n"
|
||||||
"to choose a project file in which to generate the rule for Visual "
|
" ADD_CUSTOM_COMMAND(TARGET target\n"
|
||||||
"Studio.\n"
|
" PRE_BUILD | PRE_LINK | POST_BUILD\n"
|
||||||
"Example of usage:\n"
|
" COMMAND command\n"
|
||||||
" ADD_CUSTOM_COMMAND(\n"
|
" [ARGS [args...]]\n"
|
||||||
" TARGET tiff\n"
|
" [COMMENT comment])\n"
|
||||||
" SOURCE ${TIFF_FAX_EXE}\n"
|
"This defines a new command that will be associated with "
|
||||||
" COMMAND ${TIFF_FAX_EXE}\n"
|
"building the specified target. When the command will "
|
||||||
" ARGS -c const ${TIFF_BINARY_DIR}/tif_fax3sm.c\n"
|
"happen is determined by whether you specify\n"
|
||||||
" OUTPUTS ${TIFF_BINARY_DIR}/tif_fax3sm.c\n"
|
"PRE_BUILD - run before all other dependencies\n"
|
||||||
" )\n"
|
"PRE_LINK - run after other dependencies\n"
|
||||||
"This will create custom target which will generate file tif_fax3sm.c "
|
"POST_BUILD - run after the target has been built\n";
|
||||||
"using command ${TIFF_FAX_EXE}. The rule will be executed as part of "
|
|
||||||
"building the tiff library because it includes tif_fax3sm.c as a "
|
|
||||||
"source file with the GENERATED property.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTypeMacro(cmAddCustomCommandCommand, cmCommand);
|
cmTypeMacro(cmAddCustomCommandCommand, cmCommand);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
target: normal depends
|
||||||
|
pre rules
|
||||||
|
normal rules
|
||||||
|
post rules
|
||||||
|
|
||||||
|
output1: source other depends
|
||||||
|
rule
|
||||||
|
|
||||||
|
output2: source other dpeends
|
||||||
|
rule
|
||||||
|
|
||||||
|
|
||||||
|
another option is
|
||||||
|
|
||||||
|
output1: depends
|
||||||
|
rule
|
||||||
|
|
||||||
|
output2: depends
|
||||||
|
rule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use case1 - an executable that depending on args create diff output files
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,14 +45,25 @@ bool cmAddCustomTargetCommand::InitialPass(std::vector<std::string> const& args)
|
||||||
command = *s;
|
command = *s;
|
||||||
++s;
|
++s;
|
||||||
}
|
}
|
||||||
for (;s != args.end(); ++s)
|
for (;s != args.end() && *s != "DEPENDS"; ++s)
|
||||||
{
|
{
|
||||||
arguments += cmSystemTools::EscapeSpaces(s->c_str());
|
arguments += cmSystemTools::EscapeSpaces(s->c_str());
|
||||||
arguments += " ";
|
arguments += " ";
|
||||||
}
|
}
|
||||||
|
std::vector<std::string> depends;
|
||||||
|
// skip depends keyword
|
||||||
|
if (s != args.end())
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
while (s != args.end())
|
||||||
|
{
|
||||||
|
depends.push_back(*s);
|
||||||
|
++s;
|
||||||
|
}
|
||||||
m_Makefile->AddUtilityCommand(args[0].c_str(),
|
m_Makefile->AddUtilityCommand(args[0].c_str(),
|
||||||
command.c_str(),
|
command.c_str(),
|
||||||
arguments.c_str(), all);
|
arguments.c_str(), all, depends);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,8 @@ 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] [ command arg arg arg ... ] "
|
||||||
|
" [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 command "
|
||||||
"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 "
|
||||||
|
|
|
@ -239,6 +239,56 @@ void cmAddCustomCommand(void *arg, const char* source,
|
||||||
mf->AddCustomCommand(source, command, args2, depends2, outputs2, target);
|
mf->AddCustomCommand(source, command, args2, depends2, outputs2, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmAddCustomCommandToOutput(void *arg, const char* output,
|
||||||
|
const char* command,
|
||||||
|
int numArgs, const char **args,
|
||||||
|
const char* main_dependency,
|
||||||
|
int numDepends, const char **depends)
|
||||||
|
{
|
||||||
|
cmMakefile *mf = static_cast<cmMakefile *>(arg);
|
||||||
|
int i;
|
||||||
|
std::vector<std::string> args2;
|
||||||
|
for (i = 0; i < numArgs; ++i)
|
||||||
|
{
|
||||||
|
args2.push_back(args[i]);
|
||||||
|
}
|
||||||
|
std::vector<std::string> depends2;
|
||||||
|
for (i = 0; i < numDepends; ++i)
|
||||||
|
{
|
||||||
|
depends2.push_back(depends[i]);
|
||||||
|
}
|
||||||
|
mf->AddCustomCommandToOutput(output, command, args2, main_dependency,
|
||||||
|
depends2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmAddCustomCommandToTarget(void *arg, const char* target,
|
||||||
|
const char* command,
|
||||||
|
int numArgs, const char **args,
|
||||||
|
int commandType)
|
||||||
|
{
|
||||||
|
cmMakefile *mf = static_cast<cmMakefile *>(arg);
|
||||||
|
int i;
|
||||||
|
std::vector<std::string> args2;
|
||||||
|
for (i = 0; i < numArgs; ++i)
|
||||||
|
{
|
||||||
|
args2.push_back(args[i]);
|
||||||
|
}
|
||||||
|
switch (commandType)
|
||||||
|
{
|
||||||
|
case CM_PRE_BUILD:
|
||||||
|
mf->AddCustomCommandToTarget(target, command, args2,
|
||||||
|
cmTarget::PRE_BUILD);
|
||||||
|
break;
|
||||||
|
case CM_PRE_LINK:
|
||||||
|
mf->AddCustomCommandToTarget(target, command, args2,
|
||||||
|
cmTarget::PRE_LINK);
|
||||||
|
break;
|
||||||
|
case CM_POST_BUILD:
|
||||||
|
mf->AddCustomCommandToTarget(target, command, args2,
|
||||||
|
cmTarget::POST_BUILD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cmAddLinkLibraryForTarget(void *arg, const char *tgt, const char*value,
|
void cmAddLinkLibraryForTarget(void *arg, const char *tgt, const char*value,
|
||||||
int libtype)
|
int libtype)
|
||||||
|
@ -546,5 +596,8 @@ cmCAPI cmStaticCAPI =
|
||||||
cmGetFilenamePath,
|
cmGetFilenamePath,
|
||||||
cmRemoveFile,
|
cmRemoveFile,
|
||||||
cmFree,
|
cmFree,
|
||||||
|
|
||||||
|
cmAddCustomCommandToOutput,
|
||||||
|
cmAddCustomCommandToTarget,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,19 @@ typedef struct
|
||||||
void (*RemoveFile)(const char *f1);
|
void (*RemoveFile)(const char *f1);
|
||||||
void (*Free)(void *);
|
void (*Free)(void *);
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
The following are new functions added after 1.6
|
||||||
|
=========================================================================*/
|
||||||
|
void (*AddCustomCommandToOutput) (void *mf, const char* output,
|
||||||
|
const char* command,
|
||||||
|
int numArgs, const char **args,
|
||||||
|
const char* main_dependency,
|
||||||
|
int numDepends, const char **depends);
|
||||||
|
void (*AddCustomCommandToTarget) (void *mf, const char* target,
|
||||||
|
const char* command,
|
||||||
|
int numArgs, const char **args,
|
||||||
|
int commandType);
|
||||||
|
|
||||||
/* this is the end of the C function stub API structure */
|
/* this is the end of the C function stub API structure */
|
||||||
} cmCAPI;
|
} cmCAPI;
|
||||||
|
|
||||||
|
@ -176,6 +189,12 @@ define the different types of compiles a library may be
|
||||||
#define CM_LIBRARY_DEBUG 1
|
#define CM_LIBRARY_DEBUG 1
|
||||||
#define CM_LIBRARY_OPTIMIZED 2
|
#define CM_LIBRARY_OPTIMIZED 2
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
define the different types of custom commands for a target
|
||||||
|
=========================================================================*/
|
||||||
|
#define CM_PRE_BUILD 0
|
||||||
|
#define CM_PRE_LINK 1
|
||||||
|
#define CM_POST_BUILD 2
|
||||||
|
|
||||||
/*=========================================================================
|
/*=========================================================================
|
||||||
Finally we define the key data structures and function prototypes
|
Finally we define the key data structures and function prototypes
|
||||||
|
|
|
@ -20,47 +20,48 @@
|
||||||
/**
|
/**
|
||||||
* The constructor
|
* The constructor
|
||||||
*/
|
*/
|
||||||
cmCustomCommand::cmCustomCommand(const char *src, const char *command,
|
cmCustomCommand::cmCustomCommand(const char *command,
|
||||||
const char* arguments,
|
const char* arguments,
|
||||||
std::vector<std::string> dep,
|
std::vector<std::string> dep,
|
||||||
std::vector<std::string> out):
|
const char *out):
|
||||||
m_Source(src),
|
|
||||||
m_Command(command),
|
m_Command(command),
|
||||||
m_Arguments(arguments),
|
m_Arguments(arguments),
|
||||||
m_Depends(dep),
|
m_Depends(dep)
|
||||||
m_Outputs(out)
|
|
||||||
{
|
{
|
||||||
|
if (out)
|
||||||
|
{
|
||||||
|
m_Output = out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmCustomCommand::cmCustomCommand(const char *command,
|
||||||
|
const char* arguments):
|
||||||
|
m_Command(command),
|
||||||
|
m_Arguments(arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy constructor.
|
* Copy constructor.
|
||||||
*/
|
*/
|
||||||
cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
|
cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
|
||||||
m_Source(r.m_Source),
|
|
||||||
m_Command(r.m_Command),
|
m_Command(r.m_Command),
|
||||||
m_Arguments(r.m_Arguments),
|
m_Arguments(r.m_Arguments),
|
||||||
m_Comment(r.m_Comment),
|
m_Comment(r.m_Comment),
|
||||||
m_Depends(r.m_Depends),
|
m_Depends(r.m_Depends),
|
||||||
m_Outputs(r.m_Outputs)
|
m_Output(r.m_Output)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmCustomCommand::ExpandVariables(const cmMakefile &mf)
|
void cmCustomCommand::ExpandVariables(const cmMakefile &mf)
|
||||||
{
|
{
|
||||||
mf.ExpandVariablesInString(m_Source);
|
|
||||||
mf.ExpandVariablesInString(m_Command);
|
mf.ExpandVariablesInString(m_Command);
|
||||||
mf.ExpandVariablesInString(m_Arguments);
|
mf.ExpandVariablesInString(m_Arguments);
|
||||||
|
mf.ExpandVariablesInString(m_Output);
|
||||||
|
|
||||||
for (std::vector<std::string>::iterator i = m_Depends.begin();
|
for (std::vector<std::string>::iterator i = m_Depends.begin();
|
||||||
i != m_Depends.end(); ++i)
|
i != m_Depends.end(); ++i)
|
||||||
{
|
{
|
||||||
mf.ExpandVariablesInString(*i);
|
mf.ExpandVariablesInString(*i);
|
||||||
}
|
}
|
||||||
for (std::vector<std::string>::iterator i = m_Outputs.begin();
|
|
||||||
i != m_Outputs.end(); ++i)
|
|
||||||
{
|
|
||||||
mf.ExpandVariablesInString(*i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,13 @@ class cmMakefile;
|
||||||
class cmCustomCommand
|
class cmCustomCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmCustomCommand(const char *src, const char *command,
|
cmCustomCommand(const char *command,
|
||||||
const char* arguments,
|
const char* arguments,
|
||||||
std::vector<std::string> dep,
|
std::vector<std::string> dep,
|
||||||
std::vector<std::string> out);
|
const char *out);
|
||||||
|
cmCustomCommand(const char *command,
|
||||||
|
const char* arguments);
|
||||||
|
cmCustomCommand() {};
|
||||||
cmCustomCommand(const cmCustomCommand& r);
|
cmCustomCommand(const cmCustomCommand& r);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,12 +43,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void ExpandVariables(const cmMakefile &);
|
void ExpandVariables(const cmMakefile &);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the name of the source file. I'm not sure if this is a full path or not.
|
|
||||||
*/
|
|
||||||
std::string GetSourceName() const {return m_Source;}
|
|
||||||
void SetSourceName(const char *name) {m_Source = name;}
|
|
||||||
|
|
||||||
///! Return the command to execute with arguments
|
///! Return the command to execute with arguments
|
||||||
std::string GetCommandAndArguments() const
|
std::string GetCommandAndArguments() const
|
||||||
{return m_Command + " " + m_Arguments;}
|
{return m_Command + " " + m_Arguments;}
|
||||||
|
@ -54,7 +51,11 @@ public:
|
||||||
std::string GetCommand() const {return m_Command;}
|
std::string GetCommand() const {return m_Command;}
|
||||||
void SetCommand(const char *cmd) {m_Command = cmd;}
|
void SetCommand(const char *cmd) {m_Command = cmd;}
|
||||||
|
|
||||||
///! Return the command to execute
|
///! Return the output
|
||||||
|
std::string GetOutput() const {return m_Output;}
|
||||||
|
void SetOutput(const char *cm) {m_Output = cm;}
|
||||||
|
|
||||||
|
///! Return the comment
|
||||||
std::string GetComment() const {return m_Comment;}
|
std::string GetComment() const {return m_Comment;}
|
||||||
void SetComment(const char *cm) {m_Comment = cm;}
|
void SetComment(const char *cm) {m_Comment = cm;}
|
||||||
|
|
||||||
|
@ -68,19 +69,12 @@ public:
|
||||||
const std::vector<std::string> &GetDepends() const {return m_Depends;}
|
const std::vector<std::string> &GetDepends() const {return m_Depends;}
|
||||||
std::vector<std::string> &GetDepends() {return m_Depends;}
|
std::vector<std::string> &GetDepends() {return m_Depends;}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the vector that holds the list of outputs of this command
|
|
||||||
*/
|
|
||||||
const std::vector<std::string> &GetOutputs() const {return m_Outputs;}
|
|
||||||
std::vector<std::string> &GetOutputs() {return m_Outputs;}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_Source;
|
|
||||||
std::string m_Command;
|
std::string m_Command;
|
||||||
std::string m_Arguments;
|
std::string m_Arguments;
|
||||||
std::string m_Comment;
|
std::string m_Comment;
|
||||||
|
std::string m_Output;
|
||||||
std::vector<std::string> m_Depends;
|
std::vector<std::string> m_Depends;
|
||||||
std::vector<std::string> m_Outputs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -146,8 +146,9 @@ 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 Debug only
|
// of Debug only
|
||||||
|
std::vector<std::string> srcs;
|
||||||
m_LocalGenerators[0]->GetMakefile()->
|
m_LocalGenerators[0]->GetMakefile()->
|
||||||
AddUtilityCommand("ALL_BUILD", "echo","\"Build all projects\"",false);
|
AddUtilityCommand("ALL_BUILD", "echo","\"Build all projects\"",false,srcs);
|
||||||
|
|
||||||
// add the Run Tests command
|
// add the Run Tests command
|
||||||
this->SetupTests();
|
this->SetupTests();
|
||||||
|
@ -235,8 +236,9 @@ 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;
|
||||||
m_LocalGenerators[0]->GetMakefile()->
|
m_LocalGenerators[0]->GetMakefile()->
|
||||||
AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-D $(IntDir)",false);
|
AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-D $(IntDir)",false,srcs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,12 +312,13 @@ void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout)
|
||||||
// Write the project into the DSW file
|
// Write the project into the DSW file
|
||||||
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.GetCustomCommands()[0];
|
cmCustomCommand cc = l->second.GetPreLinkCommands()[0];
|
||||||
|
|
||||||
// dodgy use of the cmCustomCommand's members to store the
|
// dodgy use of the cmCustomCommand's members to store the
|
||||||
// arguments from the INCLUDE_EXTERNAL_MSPROJECT command
|
// arguments from the INCLUDE_EXTERNAL_MSPROJECT command
|
||||||
std::vector<std::string> stuff = cc.GetDepends();
|
std::vector<std::string> stuff = cc.GetDepends();
|
||||||
std::vector<std::string> depends = cc.GetOutputs();
|
std::vector<std::string> depends;
|
||||||
|
depends.push_back(cc.GetOutput());
|
||||||
this->WriteExternalProject(fout, stuff[0].c_str(), stuff[1].c_str(), depends);
|
this->WriteExternalProject(fout, stuff[0].c_str(), stuff[1].c_str(), depends);
|
||||||
++si;
|
++si;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,12 +109,13 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(std::ostream& fout)
|
||||||
// Write the project into the SLN file
|
// Write the project into the SLN file
|
||||||
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.GetCustomCommands()[0];
|
cmCustomCommand cc = l->second.GetPreLinkCommands()[0];
|
||||||
|
|
||||||
// dodgy use of the cmCustomCommand's members to store the
|
// dodgy use of the cmCustomCommand's members to store the
|
||||||
// arguments from the INCLUDE_EXTERNAL_MSPROJECT command
|
// arguments from the INCLUDE_EXTERNAL_MSPROJECT command
|
||||||
std::vector<std::string> stuff = cc.GetDepends();
|
std::vector<std::string> stuff = cc.GetDepends();
|
||||||
std::vector<std::string> depends = cc.GetOutputs();
|
std::vector<std::string> depends;
|
||||||
|
depends.push_back(cc.GetOutput());
|
||||||
this->WriteExternalProject(fout, stuff[0].c_str(),
|
this->WriteExternalProject(fout, stuff[0].c_str(),
|
||||||
stuff[1].c_str(), depends);
|
stuff[1].c_str(), depends);
|
||||||
++si;
|
++si;
|
||||||
|
|
|
@ -145,8 +145,9 @@ 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;
|
||||||
m_LocalGenerators[0]->GetMakefile()->
|
m_LocalGenerators[0]->GetMakefile()->
|
||||||
AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-D $(IntDir)",false);
|
AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-D $(IntDir)",false, srcs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,8 +224,9 @@ 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 Debug only
|
||||||
|
std::vector<std::string> srcs;
|
||||||
m_LocalGenerators[0]->GetMakefile()->
|
m_LocalGenerators[0]->GetMakefile()->
|
||||||
AddUtilityCommand("ALL_BUILD", "echo","\"Build all projects\"",false);
|
AddUtilityCommand("ALL_BUILD", "echo","\"Build all projects\"",false, srcs);
|
||||||
|
|
||||||
// add the Run Tests command
|
// add the Run Tests command
|
||||||
this->SetupTests();
|
this->SetupTests();
|
||||||
|
@ -340,12 +342,13 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout)
|
||||||
// Write the project into the SLN file
|
// Write the project into the SLN file
|
||||||
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.GetCustomCommands()[0];
|
cmCustomCommand cc = l->second.GetPreLinkCommands()[0];
|
||||||
|
|
||||||
// dodgy use of the cmCustomCommand's members to store the
|
// dodgy use of the cmCustomCommand's members to store the
|
||||||
// arguments from the INCLUDE_EXTERNAL_MSPROJECT command
|
// arguments from the INCLUDE_EXTERNAL_MSPROJECT command
|
||||||
std::vector<std::string> stuff = cc.GetDepends();
|
std::vector<std::string> stuff = cc.GetDepends();
|
||||||
std::vector<std::string> depends = cc.GetOutputs();
|
std::vector<std::string> depends;
|
||||||
|
depends.push_back(cc.GetOutput());
|
||||||
this->WriteExternalProject(fout, stuff[0].c_str(),
|
this->WriteExternalProject(fout, stuff[0].c_str(),
|
||||||
stuff[1].c_str(), depends);
|
stuff[1].c_str(), depends);
|
||||||
++si;
|
++si;
|
||||||
|
|
|
@ -422,7 +422,8 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
|
||||||
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
|
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
|
||||||
i != classes.end(); i++)
|
i != classes.end(); i++)
|
||||||
{
|
{
|
||||||
if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
|
||||||
|
!(*i)->GetCustomCommand())
|
||||||
{
|
{
|
||||||
std::string outExt(
|
std::string outExt(
|
||||||
this->GetOutputExtension((*i)->GetSourceExtension().c_str()));
|
this->GetOutputExtension((*i)->GetSourceExtension().c_str()));
|
||||||
|
@ -439,7 +440,8 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
|
||||||
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
|
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
|
||||||
i != classes.end(); i++)
|
i != classes.end(); i++)
|
||||||
{
|
{
|
||||||
if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
|
||||||
|
!(*i)->GetCustomCommand())
|
||||||
{
|
{
|
||||||
std::string outExt(this->GetOutputExtension((*i)->GetSourceExtension().c_str()));
|
std::string outExt(this->GetOutputExtension((*i)->GetSourceExtension().c_str()));
|
||||||
if(outExt.size())
|
if(outExt.size())
|
||||||
|
@ -676,31 +678,77 @@ void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string cmLocalUnixMakefileGenerator::CreatePreBuildRules(
|
||||||
std::string cmLocalUnixMakefileGenerator::CreateTargetRules(const cmTarget &target,
|
const cmTarget &target, const char* targetName)
|
||||||
const char* targetName)
|
|
||||||
{
|
{
|
||||||
std::string customRuleCode = "";
|
std::string customRuleCode = "";
|
||||||
bool initNext = false;
|
bool initNext = false;
|
||||||
for (std::vector<cmCustomCommand>::const_iterator cr =
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
target.GetCustomCommands().begin();
|
target.GetPreBuildCommands().begin();
|
||||||
cr != target.GetCustomCommands().end(); ++cr)
|
cr != target.GetPreBuildCommands().end(); ++cr)
|
||||||
{
|
{
|
||||||
cmCustomCommand cc(*cr);
|
cmCustomCommand cc(*cr);
|
||||||
cc.ExpandVariables(*m_Makefile);
|
cc.ExpandVariables(*m_Makefile);
|
||||||
if (cc.GetSourceName() == targetName)
|
if(initNext)
|
||||||
{
|
{
|
||||||
if(initNext)
|
customRuleCode += "\n\t";
|
||||||
{
|
|
||||||
customRuleCode += "\n\t";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
initNext = true;
|
|
||||||
}
|
|
||||||
std::string command = cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str());
|
|
||||||
customRuleCode += command + " " + cc.GetArguments();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initNext = true;
|
||||||
|
}
|
||||||
|
std::string command = cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str());
|
||||||
|
customRuleCode += command + " " + cc.GetArguments();
|
||||||
|
}
|
||||||
|
return customRuleCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cmLocalUnixMakefileGenerator::CreatePreLinkRules(
|
||||||
|
const cmTarget &target, const char* targetName)
|
||||||
|
{
|
||||||
|
std::string customRuleCode = "";
|
||||||
|
bool initNext = false;
|
||||||
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
|
target.GetPreLinkCommands().begin();
|
||||||
|
cr != target.GetPreLinkCommands().end(); ++cr)
|
||||||
|
{
|
||||||
|
cmCustomCommand cc(*cr);
|
||||||
|
cc.ExpandVariables(*m_Makefile);
|
||||||
|
if(initNext)
|
||||||
|
{
|
||||||
|
customRuleCode += "\n\t";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initNext = true;
|
||||||
|
}
|
||||||
|
std::string command = cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str());
|
||||||
|
customRuleCode += command + " " + cc.GetArguments();
|
||||||
|
}
|
||||||
|
return customRuleCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cmLocalUnixMakefileGenerator::CreatePostBuildRules(
|
||||||
|
const cmTarget &target, const char* targetName)
|
||||||
|
{
|
||||||
|
std::string customRuleCode = "";
|
||||||
|
bool initNext = false;
|
||||||
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
|
target.GetPostBuildCommands().begin();
|
||||||
|
cr != target.GetPostBuildCommands().end(); ++cr)
|
||||||
|
{
|
||||||
|
cmCustomCommand cc(*cr);
|
||||||
|
cc.ExpandVariables(*m_Makefile);
|
||||||
|
if(initNext)
|
||||||
|
{
|
||||||
|
customRuleCode += "\n\t";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initNext = true;
|
||||||
|
}
|
||||||
|
std::string command = cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str());
|
||||||
|
customRuleCode += command + " " + cc.GetArguments();
|
||||||
}
|
}
|
||||||
return customRuleCode;
|
return customRuleCode;
|
||||||
}
|
}
|
||||||
|
@ -848,9 +896,21 @@ void cmLocalUnixMakefileGenerator::OutputLibraryRule(std::ostream& fout,
|
||||||
// expand multi-command semi-colon separated lists
|
// expand multi-command semi-colon separated lists
|
||||||
// of commands into separate commands
|
// of commands into separate commands
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
|
// collect custom commands for this target and add them to the list
|
||||||
|
std::string customCommands = this->CreatePreBuildRules(t, name);
|
||||||
|
if(customCommands.size() > 0)
|
||||||
|
{
|
||||||
|
commands.push_back(customCommands);
|
||||||
|
}
|
||||||
|
// collect custom commands for this target and add them to the list
|
||||||
|
customCommands = this->CreatePreLinkRules(t, name);
|
||||||
|
if(customCommands.size() > 0)
|
||||||
|
{
|
||||||
|
commands.push_back(customCommands);
|
||||||
|
}
|
||||||
cmSystemTools::ExpandList(rules, commands);
|
cmSystemTools::ExpandList(rules, commands);
|
||||||
// collect custom commands for this target and add them to the list
|
// collect custom commands for this target and add them to the list
|
||||||
std::string customCommands = this->CreateTargetRules(t, name);
|
customCommands = this->CreatePostBuildRules(t, name);
|
||||||
if(customCommands.size() > 0)
|
if(customCommands.size() > 0)
|
||||||
{
|
{
|
||||||
commands.push_back(customCommands);
|
commands.push_back(customCommands);
|
||||||
|
@ -1072,8 +1132,18 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
|
||||||
std::string comment = "executable";
|
std::string comment = "executable";
|
||||||
|
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
|
std::string customCommands = this->CreatePreBuildRules(t, name);
|
||||||
|
if(customCommands.size() > 0)
|
||||||
|
{
|
||||||
|
commands.push_back(customCommands.c_str());
|
||||||
|
}
|
||||||
|
customCommands = this->CreatePreLinkRules(t, name);
|
||||||
|
if(customCommands.size() > 0)
|
||||||
|
{
|
||||||
|
commands.push_back(customCommands.c_str());
|
||||||
|
}
|
||||||
cmSystemTools::ExpandList(rules, commands);
|
cmSystemTools::ExpandList(rules, commands);
|
||||||
std::string customCommands = this->CreateTargetRules(t, name);
|
customCommands = this->CreatePostBuildRules(t, name);
|
||||||
if(customCommands.size() > 0)
|
if(customCommands.size() > 0)
|
||||||
{
|
{
|
||||||
commands.push_back(customCommands.c_str());
|
commands.push_back(customCommands.c_str());
|
||||||
|
@ -1127,8 +1197,18 @@ void cmLocalUnixMakefileGenerator::OutputUtilityRule(std::ostream& fout,
|
||||||
const char* name,
|
const char* name,
|
||||||
const cmTarget &t)
|
const cmTarget &t)
|
||||||
{
|
{
|
||||||
std::string customCommands = this->CreateTargetRules(t, name);
|
|
||||||
const char* cc = 0;
|
const char* cc = 0;
|
||||||
|
std::string customCommands = this->CreatePreBuildRules(t, name);
|
||||||
|
std::string customCommands2 = this->CreatePreLinkRules(t, name);
|
||||||
|
if(customCommands2.size() > 0)
|
||||||
|
{
|
||||||
|
customCommands += customCommands2;
|
||||||
|
}
|
||||||
|
customCommands2 = this->CreatePostBuildRules(t, name);
|
||||||
|
if(customCommands2.size() > 0)
|
||||||
|
{
|
||||||
|
customCommands += customCommands2;
|
||||||
|
}
|
||||||
if(customCommands.size() > 0)
|
if(customCommands.size() > 0)
|
||||||
{
|
{
|
||||||
cc = customCommands.c_str();
|
cc = customCommands.c_str();
|
||||||
|
@ -1136,7 +1216,7 @@ void cmLocalUnixMakefileGenerator::OutputUtilityRule(std::ostream& fout,
|
||||||
std::string comment = "Utility";
|
std::string comment = "Utility";
|
||||||
std::string depends;
|
std::string depends;
|
||||||
std::string replaceVars;
|
std::string replaceVars;
|
||||||
const std::vector<cmCustomCommand> &ccs = t.GetCustomCommands();
|
const std::vector<cmCustomCommand> &ccs = t.GetPostBuildCommands();
|
||||||
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
|
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
|
||||||
i != ccs.end(); ++i)
|
i != ccs.end(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1513,6 +1593,17 @@ void cmLocalUnixMakefileGenerator::OutputExeDepend(std::ostream& fout,
|
||||||
exepath += cmSystemTools::GetExecutableExtension();
|
exepath += cmSystemTools::GetExecutableExtension();
|
||||||
fout << cmSystemTools::ConvertToOutputPath(exepath.c_str()) << " ";
|
fout << cmSystemTools::ConvertToOutputPath(exepath.c_str()) << " ";
|
||||||
}
|
}
|
||||||
|
// if it isn't in the cache, it might still be a utility target
|
||||||
|
// so check for that
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
|
||||||
|
if (targets.find(name) != targets.end())
|
||||||
|
{
|
||||||
|
fout << name << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1707,9 +1798,6 @@ void cmLocalUnixMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout)
|
||||||
SubDirectories);
|
SubDirectories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Output the depend information for all the classes
|
// Output the depend information for all the classes
|
||||||
// in the makefile. These would have been generated
|
// in the makefile. These would have been generated
|
||||||
// by the class cmMakeDepend GenerateMakefile
|
// by the class cmMakeDepend GenerateMakefile
|
||||||
|
@ -1821,124 +1909,74 @@ void cmLocalUnixMakefileGenerator::OutputCheckDepends(std::ostream& fout)
|
||||||
// (tab) command...
|
// (tab) command...
|
||||||
void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
|
void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
|
||||||
{
|
{
|
||||||
// We may be modifying the source groups temporarily, so make a copy.
|
// we cannot provide multiple rules for a single output
|
||||||
std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
|
// so we will keep track of outputs to make sure we don't write
|
||||||
|
// two rules. First found wins
|
||||||
|
std::set<std::string> processedOutputs;
|
||||||
|
|
||||||
const cmTargets &tgts = m_Makefile->GetTargets();
|
// first output all custom rules
|
||||||
for(cmTargets::const_iterator tgt = tgts.begin();
|
const std::vector<cmSourceFile*>& sources = m_Makefile->GetSourceFiles();
|
||||||
tgt != tgts.end(); ++tgt)
|
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
|
||||||
|
i != sources.end(); ++i)
|
||||||
{
|
{
|
||||||
// add any custom rules to the source groups
|
if ((*i)->GetCustomCommand())
|
||||||
for (std::vector<cmCustomCommand>::const_iterator cr =
|
|
||||||
tgt->second.GetCustomCommands().begin();
|
|
||||||
cr != tgt->second.GetCustomCommands().end(); ++cr)
|
|
||||||
{
|
{
|
||||||
// if the source for the custom command is the same name
|
cmCustomCommand *c = (*i)->GetCustomCommand();
|
||||||
// as the target, then to not create a rule in the makefile for
|
// escape spaces and convert to native slashes path for
|
||||||
// the custom command, as the command will be fired when the other target
|
// the command
|
||||||
// is built.
|
const char* comment = c->GetComment().c_str();
|
||||||
if ( cr->GetSourceName().compare(tgt->first) !=0)
|
std::string command = c->GetCommand();
|
||||||
|
cmSystemTools::ReplaceString(command, "/./", "/");
|
||||||
|
command = cmSystemTools::ConvertToOutputPath(command.c_str());
|
||||||
|
command += " ";
|
||||||
|
// now add the arguments
|
||||||
|
command += c->GetArguments();
|
||||||
|
std::string depends;
|
||||||
|
// Collect out all the dependencies for this rule.
|
||||||
|
for(std::vector<std::string>::const_iterator d =
|
||||||
|
c->GetDepends().begin();
|
||||||
|
d != c->GetDepends().end(); ++d)
|
||||||
{
|
{
|
||||||
cmSourceGroup& sourceGroup =
|
std::string dep = *d;
|
||||||
m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
|
m_Makefile->ExpandVariablesInString(dep);
|
||||||
sourceGroups);
|
|
||||||
cmCustomCommand cc(*cr);
|
// watch for target dependencies,
|
||||||
cc.ExpandVariables(*m_Makefile);
|
std::string libPath = dep + "_CMAKE_PATH";
|
||||||
sourceGroup.AddCustomCommand(cc);
|
const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
|
||||||
|
if (cacheValue)
|
||||||
|
{
|
||||||
|
libPath = cacheValue;
|
||||||
|
if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH") &&
|
||||||
|
m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")[0] != '\0')
|
||||||
|
{
|
||||||
|
libPath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
|
||||||
|
}
|
||||||
|
libPath += "/";
|
||||||
|
libPath += dep;
|
||||||
|
libPath += cmSystemTools::GetExecutableExtension();
|
||||||
|
dep = libPath;
|
||||||
|
}
|
||||||
|
cmSystemTools::ReplaceString(dep, "/./", "/");
|
||||||
|
cmSystemTools::ReplaceString(dep, "/$(IntDir)/", "/");
|
||||||
|
dep = cmSystemTools::ConvertToOutputPath(dep.c_str());
|
||||||
|
depends += " ";
|
||||||
|
depends += dep;
|
||||||
}
|
}
|
||||||
}
|
// output rule
|
||||||
}
|
if (processedOutputs.find(c->GetOutput()) == processedOutputs.end())
|
||||||
|
|
||||||
// Loop through every source group.
|
|
||||||
for(std::vector<cmSourceGroup>::const_iterator sg =
|
|
||||||
sourceGroups.begin(); sg != sourceGroups.end(); ++sg)
|
|
||||||
{
|
|
||||||
const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
|
|
||||||
if(buildRules.empty())
|
|
||||||
{ continue; }
|
|
||||||
|
|
||||||
std::string name = sg->GetName();
|
|
||||||
if(name != "")
|
|
||||||
{
|
|
||||||
fout << "# Start of source group \"" << name.c_str() << "\"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through each source in the source group.
|
|
||||||
for(cmSourceGroup::BuildRules::const_iterator cc =
|
|
||||||
buildRules.begin(); cc != buildRules.end(); ++ cc)
|
|
||||||
{
|
|
||||||
std::string source = cc->first;
|
|
||||||
const cmSourceGroup::Commands& commands = cc->second.m_Commands;
|
|
||||||
// Loop through every command generating code from the current source.
|
|
||||||
for(cmSourceGroup::Commands::const_iterator c = commands.begin();
|
|
||||||
c != commands.end(); ++c)
|
|
||||||
{
|
{
|
||||||
// escape spaces and convert to native slashes path for
|
this->OutputMakeRule(fout,
|
||||||
// the command
|
(*comment?comment:"Custom command"),
|
||||||
const char* comment = c->second.m_Comment.c_str();
|
c->GetOutput().c_str(),
|
||||||
std::string command = c->second.m_Command;
|
depends.c_str(),
|
||||||
cmSystemTools::ReplaceString(command, "/./", "/");
|
command.c_str());
|
||||||
command = cmSystemTools::ConvertToOutputPath(command.c_str());
|
processedOutputs.insert(c->GetOutput());
|
||||||
command += " ";
|
}
|
||||||
// now add the arguments
|
else
|
||||||
command += c->second.m_Arguments;
|
{
|
||||||
const cmSourceGroup::CommandFiles& commandFiles = c->second;
|
cmSystemTools::Error("An output was found with multiple rules on how to build it for output: ",
|
||||||
// if the command has no outputs, then it is a utility command
|
c->GetOutput().c_str());
|
||||||
// with no outputs
|
|
||||||
if(commandFiles.m_Outputs.size() == 0)
|
|
||||||
{
|
|
||||||
std::string depends;
|
|
||||||
// collect out all the dependencies for this rule.
|
|
||||||
for(std::set<std::string>::const_iterator d =
|
|
||||||
commandFiles.m_Depends.begin();
|
|
||||||
d != commandFiles.m_Depends.end(); ++d)
|
|
||||||
{
|
|
||||||
std::string dep = *d;
|
|
||||||
cmSystemTools::ReplaceString(dep, "/./", "/");
|
|
||||||
cmSystemTools::ReplaceString(dep, "/$(IntDir)/", "/");
|
|
||||||
dep = cmSystemTools::ConvertToOutputPath(dep.c_str());
|
|
||||||
depends += " ";
|
|
||||||
depends += dep;
|
|
||||||
}
|
|
||||||
// output rule
|
|
||||||
this->OutputMakeRule(fout,
|
|
||||||
(*comment?comment:"Custom command"),
|
|
||||||
source.c_str(),
|
|
||||||
depends.c_str(),
|
|
||||||
command.c_str());
|
|
||||||
}
|
|
||||||
// Write a rule for every output generated by this command.
|
|
||||||
for(std::set<std::string>::const_iterator output =
|
|
||||||
commandFiles.m_Outputs.begin();
|
|
||||||
output != commandFiles.m_Outputs.end(); ++output)
|
|
||||||
{
|
|
||||||
std::string src = cmSystemTools::ConvertToOutputPath(source.c_str());
|
|
||||||
std::string depends;
|
|
||||||
depends += src;
|
|
||||||
// Collect out all the dependencies for this rule.
|
|
||||||
for(std::set<std::string>::const_iterator d =
|
|
||||||
commandFiles.m_Depends.begin();
|
|
||||||
d != commandFiles.m_Depends.end(); ++d)
|
|
||||||
{
|
|
||||||
std::string dep = *d;
|
|
||||||
cmSystemTools::ReplaceString(dep, "/./", "/");
|
|
||||||
cmSystemTools::ReplaceString(dep, "/$(IntDir)/", "/");
|
|
||||||
dep = cmSystemTools::ConvertToOutputPath(dep.c_str());
|
|
||||||
depends += " ";
|
|
||||||
depends += dep;
|
|
||||||
}
|
|
||||||
// output rule
|
|
||||||
this->OutputMakeRule(fout,
|
|
||||||
(*comment?comment:"Custom command"),
|
|
||||||
output->c_str(),
|
|
||||||
depends.c_str(),
|
|
||||||
command.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(name != "")
|
|
||||||
{
|
|
||||||
fout << "# End of source group \"" << name.c_str() << "\"\n\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2185,7 +2223,7 @@ void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream& fout)
|
||||||
// collect up all the sources
|
// collect up all the sources
|
||||||
std::string allsources;
|
std::string allsources;
|
||||||
std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
|
std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
|
||||||
for(std::map<cmStdString, cmTarget>::const_iterator target = targets.begin();
|
for(std::map<cmStdString,cmTarget>::const_iterator target = targets.begin();
|
||||||
target != targets.end(); ++target)
|
target != targets.end(); ++target)
|
||||||
{
|
{
|
||||||
// Iterate over every source for this target.
|
// Iterate over every source for this target.
|
||||||
|
@ -2501,11 +2539,13 @@ void cmLocalUnixMakefileGenerator::OutputSourceObjectBuildRules(std::ostream& fo
|
||||||
exportsDef = "-D"+ export_symbol;
|
exportsDef = "-D"+ export_symbol;
|
||||||
}
|
}
|
||||||
// Iterate over every source for this target.
|
// Iterate over every source for this target.
|
||||||
const std::vector<cmSourceFile*>& sources = target->second.GetSourceFiles();
|
const std::vector<cmSourceFile*>& sources =
|
||||||
|
target->second.GetSourceFiles();
|
||||||
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
|
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
|
||||||
source != sources.end(); ++source)
|
source != sources.end(); ++source)
|
||||||
{
|
{
|
||||||
if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
|
||||||
|
!(*source)->GetCustomCommand())
|
||||||
{
|
{
|
||||||
std::string shortName;
|
std::string shortName;
|
||||||
std::string sourceName;
|
std::string sourceName;
|
||||||
|
@ -2513,11 +2553,15 @@ void cmLocalUnixMakefileGenerator::OutputSourceObjectBuildRules(std::ostream& fo
|
||||||
// directory, we want to use the relative path for the
|
// directory, we want to use the relative path for the
|
||||||
// filename of the object file. Otherwise, we will use just
|
// filename of the object file. Otherwise, we will use just
|
||||||
// the filename portion.
|
// the filename portion.
|
||||||
if((cmSystemTools::GetFilenamePath((*source)->GetFullPath()).find(m_Makefile->GetCurrentDirectory()) == 0)
|
if((cmSystemTools::GetFilenamePath(
|
||||||
|| (cmSystemTools::GetFilenamePath((*source)->GetFullPath()).find(m_Makefile->
|
(*source)->GetFullPath()).find(
|
||||||
GetCurrentOutputDirectory()) == 0))
|
m_Makefile->GetCurrentDirectory()) == 0)
|
||||||
|
|| (cmSystemTools::GetFilenamePath(
|
||||||
|
(*source)->GetFullPath()).find(
|
||||||
|
m_Makefile->GetCurrentOutputDirectory()) == 0))
|
||||||
{
|
{
|
||||||
sourceName = (*source)->GetSourceName()+"."+(*source)->GetSourceExtension();
|
sourceName = (*source)->GetSourceName()+"."+
|
||||||
|
(*source)->GetSourceExtension();
|
||||||
shortName = (*source)->GetSourceName();
|
shortName = (*source)->GetSourceName();
|
||||||
|
|
||||||
// The path may be relative. See if a directory needs to be
|
// The path may be relative. See if a directory needs to be
|
||||||
|
|
|
@ -187,8 +187,12 @@ protected:
|
||||||
///! return true if the two paths are the same
|
///! return true if the two paths are the same
|
||||||
virtual bool SamePath(const char* path1, const char* path2);
|
virtual bool SamePath(const char* path1, const char* path2);
|
||||||
virtual std::string GetOutputExtension(const char* sourceExtension);
|
virtual std::string GetOutputExtension(const char* sourceExtension);
|
||||||
std::string CreateTargetRules(const cmTarget &target,
|
std::string CreatePreBuildRules(const cmTarget &target,
|
||||||
const char* targetName);
|
const char* targetName);
|
||||||
|
std::string CreatePreLinkRules(const cmTarget &target,
|
||||||
|
const char* targetName);
|
||||||
|
std::string CreatePostBuildRules(const cmTarget &target,
|
||||||
|
const char* targetName);
|
||||||
virtual std::string CreateMakeVariable(const char* s, const char* s2);
|
virtual std::string CreateMakeVariable(const char* s, const char* s2);
|
||||||
|
|
||||||
///! if the OS is case insensitive then return a lower case of the path.
|
///! if the OS is case insensitive then return a lower case of the path.
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
#include "cmCacheManager.h"
|
#include "cmCacheManager.h"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
cmLocalVisualStudio6Generator::cmLocalVisualStudio6Generator()
|
cmLocalVisualStudio6Generator::cmLocalVisualStudio6Generator()
|
||||||
{
|
{
|
||||||
|
@ -74,6 +75,9 @@ 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();
|
||||||
|
@ -154,7 +158,7 @@ void cmLocalVisualStudio6Generator::CreateSingleDSP(const char *lname, cmTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmSourceGroup& sourceGroup)
|
void cmLocalVisualStudio6Generator::AddDSPBuildRule()
|
||||||
{
|
{
|
||||||
std::string dspname = *(m_CreatedProjectNames.end()-1);
|
std::string dspname = *(m_CreatedProjectNames.end()-1);
|
||||||
if(dspname == "ALL_BUILD")
|
if(dspname == "ALL_BUILD")
|
||||||
|
@ -169,20 +173,28 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmSourceGroup& sourceGroup)
|
||||||
std::string dsprule = "${CMAKE_COMMAND}";
|
std::string dsprule = "${CMAKE_COMMAND}";
|
||||||
m_Makefile->ExpandVariablesInString(dsprule);
|
m_Makefile->ExpandVariablesInString(dsprule);
|
||||||
dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());
|
dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());
|
||||||
std::string args = makefileIn;
|
std::vector<std::string> argv;
|
||||||
args += " -H";
|
argv.push_back(makefileIn);
|
||||||
|
makefileIn = m_Makefile->GetStartDirectory();
|
||||||
|
makefileIn += "/";
|
||||||
|
makefileIn += "CMakeLists.txt";
|
||||||
|
std::string args;
|
||||||
|
args = "-H";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());
|
||||||
args += " -S";
|
argv.push_back(args);
|
||||||
|
args = "-S";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());
|
||||||
args += " -O";
|
argv.push_back(args);
|
||||||
|
args = "-O";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());
|
||||||
args += " -B";
|
argv.push_back(args);
|
||||||
|
args = "-B";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());
|
||||||
m_Makefile->ExpandVariablesInString(args);
|
argv.push_back(args);
|
||||||
|
|
||||||
std::string configFile =
|
std::string configFile =
|
||||||
m_Makefile->GetDefinition("CMAKE_ROOT");
|
m_Makefile->GetDefinition("CMAKE_ROOT");
|
||||||
|
@ -201,14 +213,9 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmSourceGroup& sourceGroup)
|
||||||
{
|
{
|
||||||
listFiles.push_back(configFile);
|
listFiles.push_back(configFile);
|
||||||
}
|
}
|
||||||
|
m_Makefile->AddCustomCommandToOutput(dspname.c_str(), dsprule.c_str(),
|
||||||
std::vector<std::string> outputs;
|
argv, makefileIn.c_str(), listFiles,
|
||||||
outputs.push_back(dspname);
|
NULL, true);
|
||||||
cmCustomCommand cc(makefileIn.c_str(), dsprule.c_str(),
|
|
||||||
args.c_str(),
|
|
||||||
listFiles,
|
|
||||||
outputs);
|
|
||||||
sourceGroup.AddCustomCommand(cc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,8 +226,87 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
||||||
// We may be modifying the source groups temporarily, so make a copy.
|
// We may be modifying the source groups temporarily, so make a copy.
|
||||||
std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
|
std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
|
||||||
|
|
||||||
|
// if we should add regen rule then...
|
||||||
|
const char *suppRegenRule =
|
||||||
|
m_Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
|
||||||
|
if (!cmSystemTools::IsOn(suppRegenRule))
|
||||||
|
{
|
||||||
|
this->AddDSPBuildRule();
|
||||||
|
}
|
||||||
|
|
||||||
// get the classes from the source lists then add them to the groups
|
// get the classes from the source lists then add them to the groups
|
||||||
std::vector<cmSourceFile*> classes = target.GetSourceFiles();
|
std::vector<cmSourceFile*> & classes = target.GetSourceFiles();
|
||||||
|
// use a deck to keep track of processed source files
|
||||||
|
std::queue<std::string> srcFilesToProcess;
|
||||||
|
std::string name;
|
||||||
|
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
||||||
|
i != classes.end(); ++i)
|
||||||
|
{
|
||||||
|
name = (*i)->GetSourceName();
|
||||||
|
if ((*i)->GetSourceExtension() != "rule")
|
||||||
|
{
|
||||||
|
name += ".";
|
||||||
|
name += (*i)->GetSourceExtension();
|
||||||
|
}
|
||||||
|
srcFilesToProcess.push(name);
|
||||||
|
}
|
||||||
|
name = libName;
|
||||||
|
name += ".dsp.cmake";
|
||||||
|
srcFilesToProcess.push(name);
|
||||||
|
// add in the library depends for cusotm targets
|
||||||
|
if (target.GetType() == cmTarget::UTILITY)
|
||||||
|
{
|
||||||
|
cmCustomCommand &c = target.GetPostBuildCommands()[0];
|
||||||
|
for (std::vector<std::string>::iterator i = c.GetDepends().begin();
|
||||||
|
i != c.GetDepends().end(); ++i)
|
||||||
|
{
|
||||||
|
srcFilesToProcess.push(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!srcFilesToProcess.empty())
|
||||||
|
{
|
||||||
|
// is this source the output of a custom command
|
||||||
|
cmSourceFile* outsf =
|
||||||
|
m_Makefile->GetSourceFileWithOutput(srcFilesToProcess.front().c_str());
|
||||||
|
if (outsf)
|
||||||
|
{
|
||||||
|
// is it not already in the target?
|
||||||
|
if (std::find(classes.begin(),classes.end(),outsf) == classes.end())
|
||||||
|
{
|
||||||
|
// then add the source to this target and add it to the queue
|
||||||
|
classes.push_back(outsf);
|
||||||
|
std::string name = outsf->GetSourceName();
|
||||||
|
if (outsf->GetSourceExtension() != "rule")
|
||||||
|
{
|
||||||
|
name += ".";
|
||||||
|
name += outsf->GetSourceExtension();
|
||||||
|
}
|
||||||
|
srcFilesToProcess.push(name);
|
||||||
|
}
|
||||||
|
// add its dependencies to the list to check
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < outsf->GetCustomCommand()->GetDepends().size(); ++i)
|
||||||
|
{
|
||||||
|
std::string dep = cmSystemTools::GetFilenameName(
|
||||||
|
outsf->GetCustomCommand()->GetDepends()[i]);
|
||||||
|
// watch for target dependencies,
|
||||||
|
std::string libPath = dep + "_CMAKE_PATH";
|
||||||
|
const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
|
||||||
|
if (cacheValue)
|
||||||
|
{
|
||||||
|
// add the depend as a utility on the target
|
||||||
|
target.AddUtility(dep.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcFilesToProcess.push(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// finished with this SF move to the next
|
||||||
|
srcFilesToProcess.pop();
|
||||||
|
}
|
||||||
|
|
||||||
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
|
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
|
||||||
i != classes.end(); i++)
|
i != classes.end(); i++)
|
||||||
{
|
{
|
||||||
|
@ -231,49 +317,20 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
||||||
sourceGroup.AddSource(source.c_str(), *i);
|
sourceGroup.AddSource(source.c_str(), *i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add any custom rules to the source groups
|
|
||||||
for (std::vector<cmCustomCommand>::const_iterator cr =
|
|
||||||
target.GetCustomCommands().begin();
|
|
||||||
cr != target.GetCustomCommands().end(); ++cr)
|
|
||||||
{
|
|
||||||
cmSourceGroup& sourceGroup =
|
|
||||||
m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
|
|
||||||
sourceGroups);
|
|
||||||
cmCustomCommand cc(*cr);
|
|
||||||
cc.ExpandVariables(*m_Makefile);
|
|
||||||
sourceGroup.AddCustomCommand(cc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the DSP file's header.
|
// Write the DSP file's header.
|
||||||
this->WriteDSPHeader(fout, libName, target, sourceGroups);
|
this->WriteDSPHeader(fout, libName, target, sourceGroups);
|
||||||
|
|
||||||
// if we should add regen rule then...
|
|
||||||
const char *suppRegenRule =
|
|
||||||
m_Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
|
|
||||||
|
|
||||||
// Find the group in which the CMakeLists.txt source belongs, and add
|
|
||||||
// the rule to generate this DSP file.
|
|
||||||
if (!cmSystemTools::IsOn(suppRegenRule))
|
|
||||||
{
|
|
||||||
for(std::vector<cmSourceGroup>::reverse_iterator sg = sourceGroups.rbegin();
|
|
||||||
sg != sourceGroups.rend(); ++sg)
|
|
||||||
{
|
|
||||||
if(sg->Matches("CMakeLists.txt"))
|
|
||||||
{
|
|
||||||
this->AddDSPBuildRule(*sg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through every source group.
|
// Loop through every source group.
|
||||||
for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
|
for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
|
||||||
sg != sourceGroups.end(); ++sg)
|
sg != sourceGroups.end(); ++sg)
|
||||||
{
|
{
|
||||||
const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
|
const std::vector<const cmSourceFile *> &sourceFiles =
|
||||||
|
sg->GetSourceFiles();
|
||||||
// If the group is empty, don't write it at all.
|
// If the group is empty, don't write it at all.
|
||||||
if(buildRules.empty())
|
if(sourceFiles.empty())
|
||||||
{ continue; }
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If the group has a name, write the header.
|
// If the group has a name, write the header.
|
||||||
std::string name = sg->GetName();
|
std::string name = sg->GetName();
|
||||||
|
@ -282,37 +339,32 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
||||||
this->WriteDSPBeginGroup(fout, name.c_str(), "");
|
this->WriteDSPBeginGroup(fout, name.c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through each build rule in the source group.
|
// Loop through each source in the source group.
|
||||||
for(cmSourceGroup::BuildRules::const_iterator cc =
|
for(std::vector<const cmSourceFile *>::const_iterator sf =
|
||||||
buildRules.begin(); cc != buildRules.end(); ++ cc)
|
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
|
||||||
{
|
{
|
||||||
std::string source = cc->first;
|
std::string source = (*sf)->GetFullPath();
|
||||||
const cmSourceGroup::Commands& commands = cc->second.m_Commands;
|
const cmCustomCommand *command =
|
||||||
std::vector<std::string> depends;
|
(*sf)->GetCustomCommand();
|
||||||
std::string compileFlags;
|
std::string compileFlags;
|
||||||
if(cc->second.m_SourceFile)
|
std::vector<std::string> depends;
|
||||||
|
const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS");
|
||||||
|
if(cflags)
|
||||||
{
|
{
|
||||||
// Check for extra compiler flags.
|
compileFlags = cflags;
|
||||||
const char* cflags = cc->second.m_SourceFile->GetProperty("COMPILE_FLAGS");
|
}
|
||||||
if(cflags)
|
if(cmSystemTools::GetFileFormat((*sf)->GetSourceExtension().c_str())
|
||||||
{
|
== cmSystemTools::CXX_FILE_FORMAT)
|
||||||
compileFlags = cflags;
|
{
|
||||||
}
|
// force a C++ file type
|
||||||
if(cmSystemTools::GetFileFormat(
|
compileFlags += " /TP ";
|
||||||
cc->second.m_SourceFile->GetSourceExtension().c_str())
|
}
|
||||||
== cmSystemTools::CXX_FILE_FORMAT)
|
|
||||||
{
|
|
||||||
// force a C++ file type
|
|
||||||
compileFlags += " /TP ";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for extra object-file dependencies.
|
// Check for extra object-file dependencies.
|
||||||
const char* dependsValue =
|
const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS");
|
||||||
cc->second.m_SourceFile->GetProperty("OBJECT_DEPENDS");
|
if(dependsValue)
|
||||||
if(dependsValue)
|
{
|
||||||
{
|
cmSystemTools::ExpandListArgument(dependsValue, depends);
|
||||||
cmSystemTools::ExpandListArgument(dependsValue, depends);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (source != libName || target.GetType() == cmTarget::UTILITY)
|
if (source != libName || target.GetType() == cmTarget::UTILITY)
|
||||||
{
|
{
|
||||||
|
@ -334,18 +386,20 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
||||||
}
|
}
|
||||||
fout << "\n";
|
fout << "\n";
|
||||||
}
|
}
|
||||||
if (!commands.empty())
|
if (command)
|
||||||
{
|
{
|
||||||
cmSourceGroup::CommandFiles totalCommand;
|
|
||||||
std::string totalCommandStr;
|
std::string totalCommandStr;
|
||||||
totalCommandStr = this->CombineCommands(commands, totalCommand,
|
totalCommandStr =
|
||||||
source.c_str());
|
cmSystemTools::ConvertToOutputPath(command->GetCommand().c_str());
|
||||||
const char* comment = totalCommand.m_Comment.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(), totalCommandStr.c_str(),
|
||||||
(*comment?comment:"Custom Rule"),
|
(*comment?comment:"Custom Rule"),
|
||||||
totalCommand.m_Depends,
|
command->GetDepends(),
|
||||||
totalCommand.m_Outputs, flags);
|
command->GetOutput().c_str(), flags);
|
||||||
}
|
}
|
||||||
else if(compileFlags.size())
|
else if(compileFlags.size())
|
||||||
{
|
{
|
||||||
|
@ -384,8 +438,8 @@ void cmLocalVisualStudio6Generator::WriteCustomRule(std::ostream& fout,
|
||||||
const char* source,
|
const char* source,
|
||||||
const char* command,
|
const char* command,
|
||||||
const char* comment,
|
const char* comment,
|
||||||
const std::set<std::string>& depends,
|
const std::vector<std::string>& depends,
|
||||||
const std::set<std::string>& outputs,
|
const char *output,
|
||||||
const char* flags
|
const char* flags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -406,7 +460,7 @@ void cmLocalVisualStudio6Generator::WriteCustomRule(std::ostream& fout,
|
||||||
}
|
}
|
||||||
// Write out the dependencies for the rule.
|
// Write out the dependencies for the rule.
|
||||||
fout << "USERDEP__HACK=";
|
fout << "USERDEP__HACK=";
|
||||||
for(std::set<std::string>::const_iterator d = depends.begin();
|
for(std::vector<std::string>::const_iterator d = depends.begin();
|
||||||
d != depends.end(); ++d)
|
d != depends.end(); ++d)
|
||||||
{
|
{
|
||||||
fout << "\\\n\t" <<
|
fout << "\\\n\t" <<
|
||||||
|
@ -417,21 +471,16 @@ void cmLocalVisualStudio6Generator::WriteCustomRule(std::ostream& fout,
|
||||||
fout << "# PROP Ignore_Default_Tool 1\n";
|
fout << "# PROP Ignore_Default_Tool 1\n";
|
||||||
fout << "# Begin Custom Build - Building " << comment
|
fout << "# Begin Custom Build - Building " << comment
|
||||||
<< " $(InputPath)\n\n";
|
<< " $(InputPath)\n\n";
|
||||||
if(outputs.size() == 0)
|
if(output == 0)
|
||||||
{
|
{
|
||||||
fout << source << "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
|
fout << source << "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
|
||||||
fout << command << "\n\n";
|
fout << command << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a rule for every output generated by this command.
|
// Write a rule for every output generated by this command.
|
||||||
for(std::set<std::string>::const_iterator output = outputs.begin();
|
fout << cmSystemTools::ConvertToOutputPath(output)
|
||||||
output != outputs.end(); ++output)
|
<< " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
|
||||||
{
|
fout << command << "\n\n";
|
||||||
fout << cmSystemTools::ConvertToOutputPath(output->c_str())
|
|
||||||
<< " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
|
|
||||||
fout << command << "\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
fout << "# End Custom Build\n\n";
|
fout << "# End Custom Build\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,46 +593,6 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
|
||||||
cmLocalVisualStudio6Generator::CombineCommands(const cmSourceGroup::Commands &commands,
|
|
||||||
cmSourceGroup::CommandFiles &totalCommand,
|
|
||||||
const char *source)
|
|
||||||
|
|
||||||
{
|
|
||||||
// Loop through every custom command generating code from the
|
|
||||||
// current source.
|
|
||||||
// build up the depends and outputs and commands
|
|
||||||
std::string totalCommandStr = "";
|
|
||||||
std::string temp;
|
|
||||||
for(cmSourceGroup::Commands::const_iterator c = commands.begin();
|
|
||||||
c != commands.end(); ++c)
|
|
||||||
{
|
|
||||||
totalCommandStr += "\n\t";
|
|
||||||
temp= c->second.m_Command;
|
|
||||||
temp = cmSystemTools::ConvertToOutputPath(temp.c_str());
|
|
||||||
totalCommandStr += temp;
|
|
||||||
totalCommandStr += " ";
|
|
||||||
totalCommandStr += c->second.m_Arguments;
|
|
||||||
totalCommand.Merge(c->second);
|
|
||||||
totalCommand.m_Comment = c->second.m_Comment.c_str();
|
|
||||||
}
|
|
||||||
// Create a dummy file with the name of the source if it does
|
|
||||||
// not exist
|
|
||||||
if(totalCommand.m_Outputs.empty())
|
|
||||||
{
|
|
||||||
std::string dummyFile = m_Makefile->GetStartOutputDirectory();
|
|
||||||
dummyFile += "/";
|
|
||||||
dummyFile += source;
|
|
||||||
if(!cmSystemTools::FileExists(dummyFile.c_str()))
|
|
||||||
{
|
|
||||||
std::ofstream fout(dummyFile.c_str());
|
|
||||||
fout << "Dummy file created by cmake as unused source for utility command.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalCommandStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// look for custom rules on a target and collect them together
|
// look for custom rules on a target and collect them together
|
||||||
std::string
|
std::string
|
||||||
cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
|
cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
|
||||||
|
@ -591,39 +600,85 @@ cmLocalVisualStudio6Generator::CreateTargetRules(const cmTarget &target,
|
||||||
{
|
{
|
||||||
std::string customRuleCode = "";
|
std::string customRuleCode = "";
|
||||||
|
|
||||||
if (target.GetType() >= cmTarget::UTILITY)
|
if (target.GetType() > cmTarget::UTILITY)
|
||||||
{
|
{
|
||||||
return customRuleCode;
|
return customRuleCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the group in which the lix exe custom rules belong
|
// are there any rules?
|
||||||
|
if (target.GetPreBuildCommands().size() +
|
||||||
|
target.GetPreLinkCommands().size() +
|
||||||
|
target.GetPostBuildCommands().size() == 0)
|
||||||
|
{
|
||||||
|
return customRuleCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
customRuleCode = "# Begin Special Build Tool\n";
|
||||||
|
|
||||||
|
// Do the PreBuild and PreLink (VS6 does not support both)
|
||||||
bool init = false;
|
bool init = false;
|
||||||
for (std::vector<cmCustomCommand>::const_iterator cr =
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
target.GetCustomCommands().begin();
|
target.GetPreBuildCommands().begin();
|
||||||
cr != target.GetCustomCommands().end(); ++cr)
|
cr != target.GetPreBuildCommands().end(); ++cr)
|
||||||
{
|
{
|
||||||
cmCustomCommand cc(*cr);
|
cmCustomCommand cc(*cr);
|
||||||
cc.ExpandVariables(*m_Makefile);
|
cc.ExpandVariables(*m_Makefile);
|
||||||
if (cc.GetSourceName() == libName)
|
if (!init)
|
||||||
{
|
{
|
||||||
if (!init)
|
// header stuff
|
||||||
{
|
customRuleCode = "PreLink_Cmds=";
|
||||||
// header stuff
|
init = true;
|
||||||
customRuleCode = "# Begin Special Build Tool\nPostBuild_Cmds=";
|
|
||||||
init = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
customRuleCode += "\t";
|
|
||||||
}
|
|
||||||
customRuleCode += cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str()) + " " + cc.GetArguments();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
customRuleCode += "\t";
|
||||||
|
}
|
||||||
|
customRuleCode += cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str()) + " " + cc.GetArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init)
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
|
target.GetPreLinkCommands().begin();
|
||||||
|
cr != target.GetPreLinkCommands().end(); ++cr)
|
||||||
{
|
{
|
||||||
customRuleCode += "\n# End Special Build Tool\n";
|
cmCustomCommand cc(*cr);
|
||||||
|
cc.ExpandVariables(*m_Makefile);
|
||||||
|
if (!init)
|
||||||
|
{
|
||||||
|
// header stuff
|
||||||
|
customRuleCode = "PreLink_Cmds=";
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
customRuleCode += "\t";
|
||||||
|
}
|
||||||
|
customRuleCode += cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str()) + " " + cc.GetArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do the post build rules
|
||||||
|
init = false;
|
||||||
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
|
target.GetPostBuildCommands().begin();
|
||||||
|
cr != target.GetPostBuildCommands().end(); ++cr)
|
||||||
|
{
|
||||||
|
cmCustomCommand cc(*cr);
|
||||||
|
cc.ExpandVariables(*m_Makefile);
|
||||||
|
if (!init)
|
||||||
|
{
|
||||||
|
// header stuff
|
||||||
|
customRuleCode = "PostBuild_Cmds=";
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
customRuleCode += "\t";
|
||||||
|
}
|
||||||
|
customRuleCode +=
|
||||||
|
cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str()) +
|
||||||
|
" " + cc.GetArguments();
|
||||||
|
}
|
||||||
|
|
||||||
|
customRuleCode += "\n# End Special Build Tool\n";
|
||||||
return customRuleCode;
|
return customRuleCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,8 @@
|
||||||
class cmMakeDepend;
|
class cmMakeDepend;
|
||||||
class cmTarget;
|
class cmTarget;
|
||||||
class cmSourceFile;
|
class cmSourceFile;
|
||||||
|
class cmSourceGroup;
|
||||||
// please remove me.... Yuck
|
class cmCustomCommand;
|
||||||
#include "cmSourceGroup.h"
|
|
||||||
|
|
||||||
/** \class cmLocalVisualStudio6Generator
|
/** \class cmLocalVisualStudio6Generator
|
||||||
* \brief Write a LocalUnix makefiles.
|
* \brief Write a LocalUnix makefiles.
|
||||||
|
@ -84,21 +83,17 @@ private:
|
||||||
const cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
|
const cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
|
||||||
|
|
||||||
void WriteDSPFooter(std::ostream& fout);
|
void WriteDSPFooter(std::ostream& fout);
|
||||||
void AddDSPBuildRule(cmSourceGroup&);
|
void AddDSPBuildRule();
|
||||||
void WriteCustomRule(std::ostream& fout,
|
void WriteCustomRule(std::ostream& fout,
|
||||||
const char* source,
|
const char* source,
|
||||||
const char* command,
|
const char* command,
|
||||||
const char* comment,
|
const char* comment,
|
||||||
const std::set<std::string>& depends,
|
const std::vector<std::string>& depends,
|
||||||
const std::set<std::string>& outputs,
|
const char* output,
|
||||||
const char* flags);
|
const char* flags);
|
||||||
|
|
||||||
std::string CreateTargetRules(const cmTarget &target,
|
std::string CreateTargetRules(const cmTarget &target,
|
||||||
const char *libName);
|
const char *libName);
|
||||||
std::string CombineCommands(const cmSourceGroup::Commands &commands,
|
|
||||||
cmSourceGroup::CommandFiles &totalCommand,
|
|
||||||
const char *source);
|
|
||||||
|
|
||||||
std::string m_IncludeOptions;
|
std::string m_IncludeOptions;
|
||||||
std::vector<std::string> m_Configurations;
|
std::vector<std::string> m_Configurations;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
#include "cmCacheManager.h"
|
#include "cmCacheManager.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator()
|
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator()
|
||||||
{
|
{
|
||||||
|
@ -85,6 +86,9 @@ 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();
|
||||||
|
@ -127,7 +131,7 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj(const char *lname, cmTarg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmLocalVisualStudio7Generator::AddVCProjBuildRule(cmSourceGroup& sourceGroup)
|
void cmLocalVisualStudio7Generator::AddVCProjBuildRule()
|
||||||
{
|
{
|
||||||
std::string dspname = *(m_CreatedProjectNames.end()-1);
|
std::string dspname = *(m_CreatedProjectNames.end()-1);
|
||||||
if(dspname == "ALL_BUILD")
|
if(dspname == "ALL_BUILD")
|
||||||
|
@ -142,21 +146,28 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule(cmSourceGroup& sourceGrou
|
||||||
std::string dsprule = "${CMAKE_COMMAND}";
|
std::string dsprule = "${CMAKE_COMMAND}";
|
||||||
m_Makefile->ExpandVariablesInString(dsprule);
|
m_Makefile->ExpandVariablesInString(dsprule);
|
||||||
dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());
|
dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());
|
||||||
std::string args = makefileIn;
|
std::vector<std::string> argv;
|
||||||
args += " -H";
|
argv.push_back(makefileIn);
|
||||||
|
makefileIn = m_Makefile->GetStartDirectory();
|
||||||
|
makefileIn += "/";
|
||||||
|
makefileIn += "CMakeLists.txt";
|
||||||
|
std::string args;
|
||||||
|
args = "-H";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());
|
||||||
args += " -S";
|
argv.push_back(args);
|
||||||
|
args = "-S";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());
|
||||||
args += " -O";
|
argv.push_back(args);
|
||||||
|
args = "-O";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());
|
||||||
args += " -B";
|
argv.push_back(args);
|
||||||
|
args = "-B";
|
||||||
args +=
|
args +=
|
||||||
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());
|
cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());
|
||||||
args += "";
|
argv.push_back(args);
|
||||||
m_Makefile->ExpandVariablesInString(args);
|
|
||||||
|
|
||||||
std::string configFile =
|
std::string configFile =
|
||||||
m_Makefile->GetDefinition("CMAKE_ROOT");
|
m_Makefile->GetDefinition("CMAKE_ROOT");
|
||||||
|
@ -175,14 +186,9 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule(cmSourceGroup& sourceGrou
|
||||||
{
|
{
|
||||||
listFiles.push_back(configFile);
|
listFiles.push_back(configFile);
|
||||||
}
|
}
|
||||||
|
m_Makefile->AddCustomCommandToOutput(dspname.c_str(), dsprule.c_str(),
|
||||||
std::vector<std::string> outputs;
|
argv, makefileIn.c_str(), listFiles,
|
||||||
outputs.push_back(dspname);
|
NULL, true);
|
||||||
cmCustomCommand cc(makefileIn.c_str(), dsprule.c_str(),
|
|
||||||
args.c_str(),
|
|
||||||
listFiles,
|
|
||||||
outputs);
|
|
||||||
sourceGroup.AddCustomCommand(cc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,10 +365,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
||||||
}
|
}
|
||||||
fout << "\"\n/>\n";
|
fout << "\"\n/>\n";
|
||||||
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n";
|
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n";
|
||||||
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"";
|
|
||||||
this->OutputTargetRules(fout, target, libName);
|
this->OutputTargetRules(fout, target, libName);
|
||||||
fout << "/>\n";
|
|
||||||
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n";
|
|
||||||
this->OutputBuildTool(fout, configName, libName, target);
|
this->OutputBuildTool(fout, configName, libName, target);
|
||||||
fout << "\t\t</Configuration>\n";
|
fout << "\t\t</Configuration>\n";
|
||||||
}
|
}
|
||||||
|
@ -635,18 +638,104 @@ void cmLocalVisualStudio7Generator::OutputDefineFlags(std::ostream& fout)
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
const char *libName,
|
const char *libName,
|
||||||
cmTarget &target)
|
cmTarget &target)
|
||||||
{
|
{
|
||||||
// get the configurations
|
// get the configurations
|
||||||
std::vector<std::string> *configs =
|
std::vector<std::string> *configs =
|
||||||
static_cast<cmGlobalVisualStudio7Generator *>(m_GlobalGenerator)->GetConfigurations();
|
static_cast<cmGlobalVisualStudio7Generator *>
|
||||||
|
(m_GlobalGenerator)->GetConfigurations();
|
||||||
|
|
||||||
|
// if we should add regen rule then...
|
||||||
|
const char *suppRegenRule =
|
||||||
|
m_Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
|
||||||
|
if (!cmSystemTools::IsOn(suppRegenRule))
|
||||||
|
{
|
||||||
|
this->AddVCProjBuildRule();
|
||||||
|
}
|
||||||
|
|
||||||
// We may be modifying the source groups temporarily, so make a copy.
|
// We may be modifying the source groups temporarily, so make a copy.
|
||||||
std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
|
std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
|
||||||
|
|
||||||
// get the classes from the source lists then add them to the groups
|
// get the classes from the source lists then add them to the groups
|
||||||
std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();
|
std::vector<cmSourceFile*> & classes = target.GetSourceFiles();
|
||||||
|
// use a deck to keep track of processed source files
|
||||||
|
std::queue<std::string> srcFilesToProcess;
|
||||||
|
std::string name;
|
||||||
|
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
||||||
|
i != classes.end(); ++i)
|
||||||
|
{
|
||||||
|
std::string name = (*i)->GetSourceName();
|
||||||
|
if ((*i)->GetSourceExtension() != "rule")
|
||||||
|
{
|
||||||
|
name += ".";
|
||||||
|
name += (*i)->GetSourceExtension();
|
||||||
|
}
|
||||||
|
srcFilesToProcess.push(name);
|
||||||
|
}
|
||||||
|
// add in the project file itself
|
||||||
|
name = libName;
|
||||||
|
name += ".vcproj.cmake";
|
||||||
|
srcFilesToProcess.push(name);
|
||||||
|
// add in the library depends for cusotm targets
|
||||||
|
if (target.GetType() == cmTarget::UTILITY)
|
||||||
|
{
|
||||||
|
cmCustomCommand &c = target.GetPostBuildCommands()[0];
|
||||||
|
for (std::vector<std::string>::iterator i = c.GetDepends().begin();
|
||||||
|
i != c.GetDepends().end(); ++i)
|
||||||
|
{
|
||||||
|
srcFilesToProcess.push(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!srcFilesToProcess.empty())
|
||||||
|
{
|
||||||
|
// is this source the output of a custom command
|
||||||
|
cmSourceFile* outsf =
|
||||||
|
m_Makefile->GetSourceFileWithOutput(srcFilesToProcess.front().c_str());
|
||||||
|
if (outsf)
|
||||||
|
{
|
||||||
|
// is it not already in the target?
|
||||||
|
if (std::find(classes.begin(),classes.end(),outsf) == classes.end())
|
||||||
|
{
|
||||||
|
// then add the source to this target and add it to the queue
|
||||||
|
classes.push_back(outsf);
|
||||||
|
std::string name = outsf->GetSourceName();
|
||||||
|
if (outsf->GetSourceExtension() != "rule")
|
||||||
|
{
|
||||||
|
name += ".";
|
||||||
|
name += outsf->GetSourceExtension();
|
||||||
|
}
|
||||||
|
srcFilesToProcess.push(name);
|
||||||
|
}
|
||||||
|
// add its dependencies to the list to check
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < outsf->GetCustomCommand()->GetDepends().size(); ++i)
|
||||||
|
{
|
||||||
|
std::string dep = cmSystemTools::GetFilenameName(
|
||||||
|
outsf->GetCustomCommand()->GetDepends()[i]);
|
||||||
|
if (cmSystemTools::GetFilenameLastExtension(dep) == ".exe")
|
||||||
|
{
|
||||||
|
dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
|
||||||
|
}
|
||||||
|
// watch for target dependencies,
|
||||||
|
std::string libPath = dep + "_CMAKE_PATH";
|
||||||
|
const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
|
||||||
|
if (cacheValue)
|
||||||
|
{
|
||||||
|
// add the depend as a utility on the target
|
||||||
|
target.AddUtility(dep.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcFilesToProcess.push(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// finished with this SF move to the next
|
||||||
|
srcFilesToProcess.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the classes from the source lists then add them to the groups
|
||||||
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
||||||
i != classes.end(); i++)
|
i != classes.end(); i++)
|
||||||
{
|
{
|
||||||
|
@ -656,23 +745,9 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
{
|
{
|
||||||
m_ModuleDefinitionFile = (*i)->GetFullPath();
|
m_ModuleDefinitionFile = (*i)->GetFullPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
|
|
||||||
sourceGroups);
|
|
||||||
sourceGroup.AddSource(source.c_str(), *i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add any custom rules to the source groups
|
|
||||||
for (std::vector<cmCustomCommand>::const_iterator cr =
|
|
||||||
target.GetCustomCommands().begin();
|
|
||||||
cr != target.GetCustomCommands().end(); ++cr)
|
|
||||||
{
|
|
||||||
cmSourceGroup& sourceGroup =
|
cmSourceGroup& sourceGroup =
|
||||||
m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
|
m_Makefile->FindSourceGroup(source.c_str(), sourceGroups);
|
||||||
sourceGroups);
|
sourceGroup.AddSource(source.c_str(), *i);
|
||||||
cmCustomCommand cc(*cr);
|
|
||||||
cc.ExpandVariables(*m_Makefile);
|
|
||||||
sourceGroup.AddCustomCommand(cc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the project
|
// open the project
|
||||||
|
@ -682,34 +757,18 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
|
|
||||||
fout << "\t<Files>\n";
|
fout << "\t<Files>\n";
|
||||||
|
|
||||||
// if we should add regen rule then...
|
|
||||||
const char *suppRegenRule =
|
|
||||||
m_Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
|
|
||||||
|
|
||||||
// Find the group in which the CMakeLists.txt source belongs, and add
|
|
||||||
// the rule to generate this VCProj file.
|
|
||||||
if (!cmSystemTools::IsOn(suppRegenRule))
|
|
||||||
{
|
|
||||||
for(std::vector<cmSourceGroup>::reverse_iterator sg =
|
|
||||||
sourceGroups.rbegin();
|
|
||||||
sg != sourceGroups.rend(); ++sg)
|
|
||||||
{
|
|
||||||
if(sg->Matches("CMakeLists.txt"))
|
|
||||||
{
|
|
||||||
this->AddVCProjBuildRule(*sg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through every source group.
|
// Loop through every source group.
|
||||||
for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
|
for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
|
||||||
sg != sourceGroups.end(); ++sg)
|
sg != sourceGroups.end(); ++sg)
|
||||||
{
|
{
|
||||||
const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
|
const std::vector<const cmSourceFile *> &sourceFiles =
|
||||||
|
sg->GetSourceFiles();
|
||||||
// If the group is empty, don't write it at all.
|
// If the group is empty, don't write it at all.
|
||||||
if(buildRules.empty())
|
if(sourceFiles.empty())
|
||||||
{ continue; }
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If the group has a name, write the header.
|
// If the group has a name, write the header.
|
||||||
std::string name = sg->GetName();
|
std::string name = sg->GetName();
|
||||||
|
@ -718,45 +777,41 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
|
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through each build rule in the source group.
|
// Loop through each source in the source group.
|
||||||
for(cmSourceGroup::BuildRules::const_iterator cc =
|
for(std::vector<const cmSourceFile *>::const_iterator sf =
|
||||||
buildRules.begin(); cc != buildRules.end(); ++ cc)
|
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
|
||||||
{
|
{
|
||||||
std::string source = cc->first;
|
std::string source = (*sf)->GetFullPath();
|
||||||
const cmSourceGroup::Commands& commands = cc->second.m_Commands;
|
const cmCustomCommand *command = (*sf)->GetCustomCommand();
|
||||||
std::string compileFlags;
|
std::string compileFlags;
|
||||||
std::string additionalDeps;
|
std::string additionalDeps;
|
||||||
if(cc->second.m_SourceFile)
|
|
||||||
|
// Check for extra compiler flags.
|
||||||
|
const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS");
|
||||||
|
if(cflags)
|
||||||
{
|
{
|
||||||
// Check for extra compiler flags.
|
compileFlags = cflags;
|
||||||
const char* cflags = cc->second.m_SourceFile->GetProperty("COMPILE_FLAGS");
|
}
|
||||||
if(cflags)
|
if(cmSystemTools::GetFileFormat((*sf)->GetSourceExtension().c_str())
|
||||||
|
== cmSystemTools::CXX_FILE_FORMAT)
|
||||||
|
{
|
||||||
|
// force a C++ file type
|
||||||
|
compileFlags += " /TP ";
|
||||||
|
}
|
||||||
|
// Check for extra object-file dependencies.
|
||||||
|
const char* deps = (*sf)->GetProperty("OBJECT_DEPENDS");
|
||||||
|
if(deps)
|
||||||
|
{
|
||||||
|
std::vector<std::string> depends;
|
||||||
|
cmSystemTools::ExpandListArgument(deps, depends);
|
||||||
|
if(!depends.empty())
|
||||||
{
|
{
|
||||||
compileFlags = cc->second.m_SourceFile->GetProperty("COMPILE_FLAGS");
|
std::vector<std::string>::iterator i = depends.begin();
|
||||||
}
|
additionalDeps = this->ConvertToXMLOutputPath(i->c_str());
|
||||||
if(cmSystemTools::GetFileFormat(
|
for(++i;i != depends.end(); ++i)
|
||||||
cc->second.m_SourceFile->GetSourceExtension().c_str())
|
|
||||||
== cmSystemTools::CXX_FILE_FORMAT)
|
|
||||||
{
|
|
||||||
// force a C++ file type
|
|
||||||
compileFlags += " /TP ";
|
|
||||||
}
|
|
||||||
// Check for extra object-file dependencies.
|
|
||||||
const char* deps =
|
|
||||||
cc->second.m_SourceFile->GetProperty("OBJECT_DEPENDS");
|
|
||||||
if(deps)
|
|
||||||
{
|
|
||||||
std::vector<std::string> depends;
|
|
||||||
cmSystemTools::ExpandListArgument(deps, depends);
|
|
||||||
if(!depends.empty())
|
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator i = depends.begin();
|
additionalDeps += ";";
|
||||||
additionalDeps = this->ConvertToXMLOutputPath(i->c_str());
|
additionalDeps += this->ConvertToXMLOutputPath(i->c_str());
|
||||||
for(++i;i != depends.end(); ++i)
|
|
||||||
{
|
|
||||||
additionalDeps += ";";
|
|
||||||
additionalDeps += this->ConvertToXMLOutputPath(i->c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -767,18 +822,20 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
// Tell MS-Dev what the source is. If the compiler knows how to
|
// Tell MS-Dev what the source is. If the compiler knows how to
|
||||||
// build it, then it will.
|
// build it, then it will.
|
||||||
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
|
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
|
||||||
if (!commands.empty())
|
if (command)
|
||||||
{
|
{
|
||||||
cmSourceGroup::CommandFiles totalCommand;
|
|
||||||
std::string totalCommandStr;
|
std::string totalCommandStr;
|
||||||
totalCommandStr = this->CombineCommands(commands, totalCommand,
|
totalCommandStr =
|
||||||
source.c_str());
|
cmSystemTools::ConvertToOutputPath(command->GetCommand().c_str());
|
||||||
const char* comment = totalCommand.m_Comment.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(), totalCommandStr.c_str(),
|
||||||
(*comment?comment:"Custom Rule"),
|
(*comment?comment:"Custom Rule"),
|
||||||
totalCommand.m_Depends,
|
command->GetDepends(),
|
||||||
totalCommand.m_Outputs, flags);
|
command->GetOutput().c_str(), flags);
|
||||||
}
|
}
|
||||||
else if(compileFlags.size() || additionalDeps.length())
|
else if(compileFlags.size() || additionalDeps.length())
|
||||||
{
|
{
|
||||||
|
@ -820,13 +877,14 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmLocalVisualStudio7Generator::WriteCustomRule(std::ostream& fout,
|
void cmLocalVisualStudio7Generator::
|
||||||
const char* source,
|
WriteCustomRule(std::ostream& fout,
|
||||||
const char* command,
|
const char* source,
|
||||||
const char* comment,
|
const char* command,
|
||||||
const std::set<std::string>& depends,
|
const char* comment,
|
||||||
const std::set<std::string>& outputs,
|
const std::vector<std::string>& depends,
|
||||||
const char* compileFlags)
|
const char *output,
|
||||||
|
const char* compileFlags)
|
||||||
{
|
{
|
||||||
std::string cmd = command;
|
std::string cmd = command;
|
||||||
cmSystemTools::ReplaceString(cmd, "\"", """);
|
cmSystemTools::ReplaceString(cmd, "\"", """);
|
||||||
|
@ -847,17 +905,13 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(std::ostream& fout,
|
||||||
fout << "\t\t\t\t\t<Tool\n"
|
fout << "\t\t\t\t\t<Tool\n"
|
||||||
<< "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"
|
<< "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"
|
||||||
<< "\t\t\t\t\tDescription=\"Building " << comment;
|
<< "\t\t\t\t\tDescription=\"Building " << comment;
|
||||||
std::set<std::string>::const_iterator it;
|
fout << " " << output;
|
||||||
for ( it = outputs.begin(); it != outputs.end(); it ++ )
|
|
||||||
{
|
|
||||||
fout << " " << *it;
|
|
||||||
}
|
|
||||||
fout << "\"\n"
|
fout << "\"\n"
|
||||||
<< "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n"
|
<< "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n"
|
||||||
<< "\t\t\t\t\tAdditionalDependencies=\"";
|
<< "\t\t\t\t\tAdditionalDependencies=\"";
|
||||||
// Write out the dependencies for the rule.
|
// Write out the dependencies for the rule.
|
||||||
std::string temp;
|
std::string temp;
|
||||||
for(std::set<std::string>::const_iterator d = depends.begin();
|
for(std::vector<std::string>::const_iterator d = depends.begin();
|
||||||
d != depends.end(); ++d)
|
d != depends.end(); ++d)
|
||||||
{
|
{
|
||||||
fout << this->ConvertToXMLOutputPath(d->c_str())
|
fout << this->ConvertToXMLOutputPath(d->c_str())
|
||||||
|
@ -865,26 +919,14 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(std::ostream& fout,
|
||||||
}
|
}
|
||||||
fout << "\"\n";
|
fout << "\"\n";
|
||||||
fout << "\t\t\t\t\tOutputs=\"";
|
fout << "\t\t\t\t\tOutputs=\"";
|
||||||
if(outputs.size() == 0)
|
if(output == 0)
|
||||||
{
|
{
|
||||||
fout << source << "_force";
|
fout << source << "_force";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
// Write a rule for every output generated by this command.
|
// Write a rule for the output generated by this command.
|
||||||
for(std::set<std::string>::const_iterator output = outputs.begin();
|
fout << this->ConvertToXMLOutputPathSingle(output);
|
||||||
output != outputs.end(); ++output)
|
|
||||||
{
|
|
||||||
if(!first)
|
|
||||||
{
|
|
||||||
fout << ";";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
fout << this->ConvertToXMLOutputPathSingle(output->c_str());
|
|
||||||
}
|
|
||||||
fout << "\"/>\n";
|
fout << "\"/>\n";
|
||||||
fout << "\t\t\t\t</FileConfiguration>\n";
|
fout << "\t\t\t\t</FileConfiguration>\n";
|
||||||
}
|
}
|
||||||
|
@ -907,85 +949,90 @@ void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string
|
|
||||||
cmLocalVisualStudio7Generator::CombineCommands(
|
|
||||||
const cmSourceGroup::Commands &commands,
|
|
||||||
cmSourceGroup::CommandFiles &totalCommand,
|
|
||||||
const char *source)
|
|
||||||
|
|
||||||
{
|
|
||||||
// Loop through every custom command generating code from the
|
|
||||||
// current source.
|
|
||||||
// build up the depends and outputs and commands
|
|
||||||
std::string totalCommandStr = "";
|
|
||||||
std::string temp;
|
|
||||||
for(cmSourceGroup::Commands::const_iterator c = commands.begin();
|
|
||||||
c != commands.end(); ++c)
|
|
||||||
{
|
|
||||||
temp=
|
|
||||||
cmSystemTools::ConvertToOutputPath(c->second.m_Command.c_str());
|
|
||||||
totalCommandStr += temp;
|
|
||||||
totalCommandStr += " ";
|
|
||||||
totalCommandStr += c->second.m_Arguments;
|
|
||||||
totalCommandStr += "\n";
|
|
||||||
totalCommand.Merge(c->second);
|
|
||||||
totalCommand.m_Comment = c->second.m_Comment.c_str();
|
|
||||||
}
|
|
||||||
// Create a dummy file with the name of the source if it does
|
|
||||||
// not exist
|
|
||||||
if(totalCommand.m_Outputs.empty())
|
|
||||||
{
|
|
||||||
std::string dummyFile = m_Makefile->GetStartOutputDirectory();
|
|
||||||
dummyFile += "/";
|
|
||||||
dummyFile += source;
|
|
||||||
if(!cmSystemTools::FileExists(dummyFile.c_str()))
|
|
||||||
{
|
|
||||||
std::ofstream fout(dummyFile.c_str());
|
|
||||||
fout << "Dummy file created by cmake as unused source for utility command.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalCommandStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// look for custom rules on a target and collect them together
|
// look for custom rules on a target and collect them together
|
||||||
|
|
||||||
void cmLocalVisualStudio7Generator::OutputTargetRules(std::ostream& fout,
|
void cmLocalVisualStudio7Generator::OutputTargetRules(std::ostream& fout,
|
||||||
const cmTarget &target,
|
const cmTarget &target,
|
||||||
const char *libName)
|
const char *libName)
|
||||||
{
|
{
|
||||||
if (target.GetType() >= cmTarget::UTILITY)
|
if (target.GetType() > cmTarget::UTILITY)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the group in which the lix exe custom rules belong
|
// add the pre build rules
|
||||||
|
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"";
|
||||||
bool init = false;
|
bool init = false;
|
||||||
for (std::vector<cmCustomCommand>::const_iterator cr =
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
target.GetCustomCommands().begin();
|
target.GetPreBuildCommands().begin();
|
||||||
cr != target.GetCustomCommands().end(); ++cr)
|
cr != target.GetPreBuildCommands().end(); ++cr)
|
||||||
{
|
{
|
||||||
cmCustomCommand cc(*cr);
|
cmCustomCommand cc(*cr);
|
||||||
cc.ExpandVariables(*m_Makefile);
|
cc.ExpandVariables(*m_Makefile);
|
||||||
if (cc.GetSourceName() == libName)
|
if(!init)
|
||||||
{
|
{
|
||||||
if(!init)
|
fout << "\nCommandLine=\"";
|
||||||
{
|
init = true;
|
||||||
fout << "\nCommandLine=\"";
|
|
||||||
init = true;
|
|
||||||
}
|
|
||||||
std::string args = cc.GetArguments();
|
|
||||||
cmSystemTools::ReplaceString(args, "\"", """);
|
|
||||||
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " << args << "\n";
|
|
||||||
}
|
}
|
||||||
|
std::string args = cc.GetArguments();
|
||||||
|
cmSystemTools::ReplaceString(args, "\"", """);
|
||||||
|
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " <<
|
||||||
|
args << "\n";
|
||||||
}
|
}
|
||||||
if (init)
|
if (init)
|
||||||
{
|
{
|
||||||
fout << "\"";
|
fout << "\"";
|
||||||
}
|
}
|
||||||
|
fout << "/>\n";
|
||||||
|
|
||||||
|
// add the pre Link rules
|
||||||
|
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"";
|
||||||
|
init = false;
|
||||||
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
|
target.GetPreLinkCommands().begin();
|
||||||
|
cr != target.GetPreLinkCommands().end(); ++cr)
|
||||||
|
{
|
||||||
|
cmCustomCommand cc(*cr);
|
||||||
|
cc.ExpandVariables(*m_Makefile);
|
||||||
|
if(!init)
|
||||||
|
{
|
||||||
|
fout << "\nCommandLine=\"";
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
std::string args = cc.GetArguments();
|
||||||
|
cmSystemTools::ReplaceString(args, "\"", """);
|
||||||
|
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " <<
|
||||||
|
args << "\n";
|
||||||
|
}
|
||||||
|
if (init)
|
||||||
|
{
|
||||||
|
fout << "\"";
|
||||||
|
}
|
||||||
|
fout << "/>\n";
|
||||||
|
|
||||||
|
// add the PostBuild rules
|
||||||
|
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"";
|
||||||
|
init = false;
|
||||||
|
for (std::vector<cmCustomCommand>::const_iterator cr =
|
||||||
|
target.GetPostBuildCommands().begin();
|
||||||
|
cr != target.GetPostBuildCommands().end(); ++cr)
|
||||||
|
{
|
||||||
|
cmCustomCommand cc(*cr);
|
||||||
|
cc.ExpandVariables(*m_Makefile);
|
||||||
|
if(!init)
|
||||||
|
{
|
||||||
|
fout << "\nCommandLine=\"";
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
std::string args = cc.GetArguments();
|
||||||
|
cmSystemTools::ReplaceString(args, "\"", """);
|
||||||
|
fout << this->ConvertToXMLOutputPath(cc.GetCommand().c_str()) << " " <<
|
||||||
|
args << "\n";
|
||||||
|
}
|
||||||
|
if (init)
|
||||||
|
{
|
||||||
|
fout << "\"";
|
||||||
|
}
|
||||||
|
fout << "/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -22,9 +22,8 @@
|
||||||
class cmMakeDepend;
|
class cmMakeDepend;
|
||||||
class cmTarget;
|
class cmTarget;
|
||||||
class cmSourceFile;
|
class cmSourceFile;
|
||||||
|
class cmCustomCommand;
|
||||||
// please remove me.... Yuck
|
class cmSourceGroup;
|
||||||
#include "cmSourceGroup.h"
|
|
||||||
|
|
||||||
/** \class cmLocalVisualStudio7Generator
|
/** \class cmLocalVisualStudio7Generator
|
||||||
* \brief Write a LocalUnix makefiles.
|
* \brief Write a LocalUnix makefiles.
|
||||||
|
@ -74,7 +73,7 @@ private:
|
||||||
void CreateSingleVCProj(const char *lname, cmTarget &tgt);
|
void CreateSingleVCProj(const char *lname, cmTarget &tgt);
|
||||||
void WriteVCProjFile(std::ostream& fout, const char *libName,
|
void WriteVCProjFile(std::ostream& fout, const char *libName,
|
||||||
cmTarget &tgt);
|
cmTarget &tgt);
|
||||||
void AddVCProjBuildRule(cmSourceGroup&);
|
void AddVCProjBuildRule();
|
||||||
void WriteConfigurations(std::ostream& fout,
|
void WriteConfigurations(std::ostream& fout,
|
||||||
const char *libName,
|
const char *libName,
|
||||||
const cmTarget &tgt);
|
const cmTarget &tgt);
|
||||||
|
@ -107,15 +106,12 @@ private:
|
||||||
const char* group,
|
const char* group,
|
||||||
const char* filter);
|
const char* filter);
|
||||||
void WriteVCProjEndGroup(std::ostream& fout);
|
void WriteVCProjEndGroup(std::ostream& fout);
|
||||||
std::string CombineCommands(const cmSourceGroup::Commands &commands,
|
|
||||||
cmSourceGroup::CommandFiles &totalCommand,
|
|
||||||
const char *source);
|
|
||||||
void WriteCustomRule(std::ostream& fout,
|
void WriteCustomRule(std::ostream& fout,
|
||||||
const char* source,
|
const char* source,
|
||||||
const char* command,
|
const char* command,
|
||||||
const char* comment,
|
const char* comment,
|
||||||
const std::set<std::string>& depends,
|
const std::vector<std::string>& depends,
|
||||||
const std::set<std::string>& outputs,
|
const char* output,
|
||||||
const char* extraFlags);
|
const char* extraFlags);
|
||||||
|
|
||||||
std::vector<std::string> m_CreatedProjectNames;
|
std::vector<std::string> m_CreatedProjectNames;
|
||||||
|
|
|
@ -65,6 +65,7 @@ cmMakefile::cmMakefile()
|
||||||
this->AddSourceGroup("Source Files",
|
this->AddSourceGroup("Source Files",
|
||||||
"\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
|
"\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
|
||||||
this->AddSourceGroup("Header Files", "\\.(h|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
|
this->AddSourceGroup("Header Files", "\\.(h|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
|
||||||
|
this->AddSourceGroup("CMake Rules", "\\.rule$");
|
||||||
this->AddDefaultDefinitions();
|
this->AddDefaultDefinitions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ void cmMakefile::Print() const
|
||||||
for( std::vector<cmSourceGroup>::const_iterator i = m_SourceGroups.begin();
|
for( std::vector<cmSourceGroup>::const_iterator i = m_SourceGroups.begin();
|
||||||
i != m_SourceGroups.end(); ++i)
|
i != m_SourceGroups.end(); ++i)
|
||||||
{
|
{
|
||||||
i->Print();
|
std::cout << "Source Group: " << i->GetName() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +442,7 @@ void cmMakefile::ConfigureFinalPass()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this is the old style signature, we convert to new style
|
||||||
void cmMakefile::AddCustomCommand(const char* source,
|
void cmMakefile::AddCustomCommand(const char* source,
|
||||||
const char* command,
|
const char* command,
|
||||||
const std::vector<std::string>& commandArgs,
|
const std::vector<std::string>& commandArgs,
|
||||||
|
@ -448,6 +450,130 @@ void cmMakefile::AddCustomCommand(const char* source,
|
||||||
const std::vector<std::string>& outputs,
|
const std::vector<std::string>& outputs,
|
||||||
const char *target,
|
const char *target,
|
||||||
const char *comment)
|
const char *comment)
|
||||||
|
{
|
||||||
|
if (strcmp(source,target))
|
||||||
|
{
|
||||||
|
// what a pain, for backwards compatibility we will try to
|
||||||
|
// convert this to an output based rule... so for each output..
|
||||||
|
for(std::vector<std::string>::const_iterator d = outputs.begin();
|
||||||
|
d != outputs.end(); ++d)
|
||||||
|
{
|
||||||
|
this->AddCustomCommandToOutput(d->c_str(), command, commandArgs,
|
||||||
|
source, depends, comment);
|
||||||
|
// add the output to the target?
|
||||||
|
std::string sname = *d;
|
||||||
|
sname += ".rule";
|
||||||
|
if (!this->GetSource(sname.c_str()))
|
||||||
|
{
|
||||||
|
m_Targets[target].GetSourceLists().push_back(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->AddCustomCommandToTarget(target, command, commandArgs,
|
||||||
|
cmTarget::POST_BUILD,
|
||||||
|
comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmMakefile::AddCustomCommand(const char* source,
|
||||||
|
const char* command,
|
||||||
|
const std::vector<std::string>& commandArgs,
|
||||||
|
const std::vector<std::string>& depends,
|
||||||
|
const char* output,
|
||||||
|
const char *target)
|
||||||
|
{
|
||||||
|
std::vector<std::string> outputs;
|
||||||
|
outputs.push_back(output);
|
||||||
|
this->AddCustomCommand(source, command, commandArgs, depends,
|
||||||
|
outputs, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmMakefile::
|
||||||
|
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,
|
||||||
|
bool replace)
|
||||||
|
{
|
||||||
|
cmSourceFile *file = 0;
|
||||||
|
std::string outName = output;
|
||||||
|
outName += ".rule";
|
||||||
|
|
||||||
|
// 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(main_dependency);
|
||||||
|
if (file && file->GetCustomCommand() && !replace)
|
||||||
|
{
|
||||||
|
// generate a source instead
|
||||||
|
file = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = this->GetOrCreateSource(main_dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
file = this->GetSource(outName.c_str());
|
||||||
|
if (file && file->GetCustomCommand() && !replace)
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("Attempt to add a custom rule to an output that already has a custom rule. For output: ", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// create a cmSourceFile for the output
|
||||||
|
file = this->GetOrCreateSource(outName.c_str(), true);
|
||||||
|
// always mark as generated
|
||||||
|
file->SetProperty("GENERATED","1");
|
||||||
|
}
|
||||||
|
|
||||||
|
// always create the output and mark it generated
|
||||||
|
cmSourceFile *out = this->GetOrCreateSource(output, true);
|
||||||
|
out->SetProperty("GENERATED","1");
|
||||||
|
|
||||||
|
// process the command
|
||||||
|
std::string expandC = command;
|
||||||
|
this->ExpandVariablesInString(expandC);
|
||||||
|
std::string c = cmSystemTools::EscapeSpaces(expandC.c_str());
|
||||||
|
|
||||||
|
std::string combinedArgs;
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < commandArgs.size(); ++i)
|
||||||
|
{
|
||||||
|
expandC = commandArgs[i].c_str();
|
||||||
|
this->ExpandVariablesInString(expandC);
|
||||||
|
combinedArgs += cmSystemTools::EscapeSpaces(expandC.c_str());
|
||||||
|
combinedArgs += " ";
|
||||||
|
}
|
||||||
|
std::vector<std::string> depends2(depends);
|
||||||
|
if (main_dependency && main_dependency[0] != '\0')
|
||||||
|
{
|
||||||
|
depends2.push_back(main_dependency);
|
||||||
|
}
|
||||||
|
cmCustomCommand *cc =
|
||||||
|
new cmCustomCommand(c.c_str(),combinedArgs.c_str(),depends2, output);
|
||||||
|
if ( comment && comment[0] )
|
||||||
|
{
|
||||||
|
cc->SetComment(comment);
|
||||||
|
}
|
||||||
|
if (file->GetCustomCommand())
|
||||||
|
{
|
||||||
|
delete file->GetCustomCommand();
|
||||||
|
}
|
||||||
|
file->SetCustomCommand(cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmMakefile::
|
||||||
|
AddCustomCommandToTarget(const char* target, const char* command,
|
||||||
|
const std::vector<std::string>& commandArgs,
|
||||||
|
cmTarget::CustomCommandType type,
|
||||||
|
const char *comment)
|
||||||
{
|
{
|
||||||
// find the target,
|
// find the target,
|
||||||
if (m_Targets.find(target) != m_Targets.end())
|
if (m_Targets.find(target) != m_Targets.end())
|
||||||
|
@ -467,12 +593,23 @@ void cmMakefile::AddCustomCommand(const char* source,
|
||||||
combinedArgs += " ";
|
combinedArgs += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
cmCustomCommand cc(source,c.c_str(),combinedArgs.c_str(),depends,outputs);
|
cmCustomCommand cc(c.c_str(),combinedArgs.c_str());
|
||||||
if ( comment && comment[0] )
|
if ( comment && comment[0] )
|
||||||
{
|
{
|
||||||
cc.SetComment(comment);
|
cc.SetComment(comment);
|
||||||
}
|
}
|
||||||
m_Targets[target].GetCustomCommands().push_back(cc);
|
switch (type)
|
||||||
|
{
|
||||||
|
case cmTarget::PRE_BUILD:
|
||||||
|
m_Targets[target].GetPreBuildCommands().push_back(cc);
|
||||||
|
break;
|
||||||
|
case cmTarget::PRE_LINK:
|
||||||
|
m_Targets[target].GetPreLinkCommands().push_back(cc);
|
||||||
|
break;
|
||||||
|
case cmTarget::POST_BUILD:
|
||||||
|
m_Targets[target].GetPostBuildCommands().push_back(cc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
std::string cacheCommand = command;
|
std::string cacheCommand = command;
|
||||||
this->ExpandVariablesInString(cacheCommand);
|
this->ExpandVariablesInString(cacheCommand);
|
||||||
if(this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
|
if(this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
|
||||||
|
@ -483,18 +620,6 @@ void cmMakefile::AddCustomCommand(const char* source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmMakefile::AddCustomCommand(const char* source,
|
|
||||||
const char* command,
|
|
||||||
const std::vector<std::string>& commandArgs,
|
|
||||||
const std::vector<std::string>& depends,
|
|
||||||
const char* output,
|
|
||||||
const char *target)
|
|
||||||
{
|
|
||||||
std::vector<std::string> outputs;
|
|
||||||
outputs.push_back(output);
|
|
||||||
this->AddCustomCommand(source, command, commandArgs, depends, outputs, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmMakefile::AddDefineFlag(const char* flag)
|
void cmMakefile::AddDefineFlag(const char* flag)
|
||||||
{
|
{
|
||||||
m_DefineFlags += " ";
|
m_DefineFlags += " ";
|
||||||
|
@ -799,11 +924,12 @@ void cmMakefile::AddExecutable(const char *exeName,
|
||||||
void cmMakefile::AddUtilityCommand(const char* utilityName,
|
void cmMakefile::AddUtilityCommand(const char* utilityName,
|
||||||
const char* command,
|
const char* command,
|
||||||
const char* arguments,
|
const char* arguments,
|
||||||
bool all)
|
bool all,
|
||||||
|
const std::vector<std::string> &depends)
|
||||||
{
|
{
|
||||||
std::vector<std::string> empty;
|
std::vector<std::string> empty;
|
||||||
this->AddUtilityCommand(utilityName,command,arguments,all,
|
this->AddUtilityCommand(utilityName,command,arguments,all,
|
||||||
empty,empty);
|
depends, empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmMakefile::AddUtilityCommand(const char* utilityName,
|
void cmMakefile::AddUtilityCommand(const char* utilityName,
|
||||||
|
@ -816,11 +942,54 @@ void cmMakefile::AddUtilityCommand(const char* utilityName,
|
||||||
cmTarget target;
|
cmTarget target;
|
||||||
target.SetType(cmTarget::UTILITY);
|
target.SetType(cmTarget::UTILITY);
|
||||||
target.SetInAll(all);
|
target.SetInAll(all);
|
||||||
cmCustomCommand cc(utilityName, command, arguments, dep, out);
|
if (out.size() > 1)
|
||||||
target.GetCustomCommands().push_back(cc);
|
{
|
||||||
|
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, NULL);
|
||||||
|
target.GetPostBuildCommands().push_back(cc);
|
||||||
|
}
|
||||||
m_Targets.insert(cmTargets::value_type(utilityName,target));
|
m_Targets.insert(cmTargets::value_type(utilityName,target));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
|
||||||
|
{
|
||||||
|
std::string name = cname;
|
||||||
|
|
||||||
|
// look through all the source files that have custom commands
|
||||||
|
// and see if the custom command has the passed source file as an output
|
||||||
|
// keep in mind the possible .rule extension that may be tacked on
|
||||||
|
for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin();
|
||||||
|
i != m_SourceFiles.end(); ++i)
|
||||||
|
{
|
||||||
|
// does this source file have a custom command?
|
||||||
|
if ((*i)->GetCustomCommand())
|
||||||
|
{
|
||||||
|
// is the output of the custom command match the source files name
|
||||||
|
std::string out = (*i)->GetCustomCommand()->GetOutput();
|
||||||
|
if (out.rfind(name) != out.npos &&
|
||||||
|
out.rfind(name) == out.size() - name.size())
|
||||||
|
{
|
||||||
|
return *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise return NULL
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cmSourceGroup* cmMakefile::GetSourceGroup(const char* name)
|
cmSourceGroup* cmMakefile::GetSourceGroup(const char* name)
|
||||||
{
|
{
|
||||||
// First see if the group exists. If so, replace its regular expression.
|
// First see if the group exists. If so, replace its regular expression.
|
||||||
|
@ -946,6 +1115,19 @@ void cmMakefile::ExpandVariables()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmMakefile::ExpandVariablesInCustomCommands()
|
||||||
|
{
|
||||||
|
for(std::vector<cmSourceFile*>::iterator i = m_SourceFiles.begin();
|
||||||
|
i != m_SourceFiles.end(); ++i)
|
||||||
|
{
|
||||||
|
cmCustomCommand *cc = (*i)->GetCustomCommand();
|
||||||
|
if (cc)
|
||||||
|
{
|
||||||
|
cc->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);
|
||||||
|
@ -1254,7 +1436,7 @@ cmMakefile::FindSourceGroup(const char* source,
|
||||||
std::string::size_type pos = file.rfind('/');
|
std::string::size_type pos = file.rfind('/');
|
||||||
if(pos != std::string::npos)
|
if(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
file = file.substr(pos, file.length()-pos);
|
file = file.substr(pos+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
|
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
|
||||||
|
@ -1402,11 +1584,11 @@ cmSourceFile* cmMakefile::GetSource(const char* sourceName) const
|
||||||
{
|
{
|
||||||
std::string s = cmSystemTools::GetFilenameName(sourceName);
|
std::string s = cmSystemTools::GetFilenameName(sourceName);
|
||||||
std::string ext;
|
std::string ext;
|
||||||
std::string::size_type pos = s.rfind('.');
|
ext = cmSystemTools::GetFilenameLastExtension(s);
|
||||||
if(pos != std::string::npos)
|
s = s.substr(0, s.length()-ext.length());
|
||||||
|
if ( ext.length() && ext[0] == '.' )
|
||||||
{
|
{
|
||||||
ext = s.substr(pos+1, s.size() - pos-1);
|
ext = ext.substr(1);
|
||||||
s = s.substr(0, pos);
|
|
||||||
}
|
}
|
||||||
for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin();
|
for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin();
|
||||||
i != m_SourceFiles.end(); ++i)
|
i != m_SourceFiles.end(); ++i)
|
||||||
|
@ -1422,6 +1604,69 @@ cmSourceFile* cmMakefile::GetSource(const char* sourceName) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
|
||||||
|
bool generated)
|
||||||
|
{
|
||||||
|
// check to see if it exists
|
||||||
|
cmSourceFile* ret = this->GetSource(sourceName);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we must create one
|
||||||
|
std::string newfile = sourceName;
|
||||||
|
cmSourceFile file;
|
||||||
|
std::string path = cmSystemTools::GetFilenamePath(newfile);
|
||||||
|
if(generated)
|
||||||
|
{
|
||||||
|
std::string ext = cmSystemTools::GetFilenameLastExtension(newfile);
|
||||||
|
std::string name_no_ext = cmSystemTools::GetFilenameName(newfile.c_str());
|
||||||
|
name_no_ext = name_no_ext.substr(0, name_no_ext.length()-ext.length());
|
||||||
|
if ( ext.length() && ext[0] == '.' )
|
||||||
|
{
|
||||||
|
ext = ext.substr(1);
|
||||||
|
}
|
||||||
|
if((path.size() && path[0] == '/') ||
|
||||||
|
(path.size() > 1 && path[1] == ':'))
|
||||||
|
{
|
||||||
|
file.SetName(name_no_ext.c_str(), path.c_str(), ext.c_str(), false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file.SetName(name_no_ext.c_str(), this->GetCurrentOutputDirectory(),
|
||||||
|
ext.c_str(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if this is a full path then
|
||||||
|
if((path.size() && path[0] == '/') ||
|
||||||
|
(path.size() > 1 && path[1] == ':'))
|
||||||
|
{
|
||||||
|
file.SetName(cmSystemTools::GetFilenameName(newfile.c_str()).c_str(),
|
||||||
|
path.c_str(),
|
||||||
|
this->GetSourceExtensions(),
|
||||||
|
this->GetHeaderExtensions());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file.SetName(newfile.c_str(), this->GetCurrentDirectory(),
|
||||||
|
this->GetSourceExtensions(),
|
||||||
|
this->GetHeaderExtensions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add the source file to the makefile
|
||||||
|
this->AddSource(file);
|
||||||
|
ret = this->GetSource(sourceName);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
cmSystemTools::Error(
|
||||||
|
"CMake failed to properly look up cmSourceFile: ", sourceName);
|
||||||
|
int i = *(int *)0x0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
|
cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
|
||||||
|
|
|
@ -118,6 +118,22 @@ public:
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a custom command to the build.
|
* Add a custom command to the build.
|
||||||
*/
|
*/
|
||||||
|
@ -156,7 +172,8 @@ public:
|
||||||
void AddUtilityCommand(const char* utilityName,
|
void AddUtilityCommand(const char* utilityName,
|
||||||
const char* command,
|
const char* command,
|
||||||
const char* arguments,
|
const char* arguments,
|
||||||
bool all);
|
bool all,
|
||||||
|
const std::vector<std::string> &depends);
|
||||||
void AddUtilityCommand(const char* utilityName,
|
void AddUtilityCommand(const char* utilityName,
|
||||||
const char* command,
|
const char* command,
|
||||||
const char* arguments,
|
const char* arguments,
|
||||||
|
@ -418,6 +435,14 @@ public:
|
||||||
///! Add a new cmSourceFile to the list of sources for this makefile.
|
///! Add a new cmSourceFile to the list of sources for this makefile.
|
||||||
cmSourceFile* AddSource(cmSourceFile const&);
|
cmSourceFile* AddSource(cmSourceFile const&);
|
||||||
|
|
||||||
|
/** Get a cmSourceFile pointer for a given source name, if the name is
|
||||||
|
* not found, then create the source file and return it. generated
|
||||||
|
* indicates if it is a generated file, this is used in determining
|
||||||
|
* how to create the source file instance e.g. name
|
||||||
|
*/
|
||||||
|
cmSourceFile* GetOrCreateSource(const char* sourceName,
|
||||||
|
bool generated = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a list of auxiliary source directories.
|
* Obtain a list of auxiliary source directories.
|
||||||
*/
|
*/
|
||||||
|
@ -508,6 +533,7 @@ 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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find what source group this source is in
|
* find what source group this source is in
|
||||||
|
@ -559,6 +585,19 @@ public:
|
||||||
*/
|
*/
|
||||||
cmake *GetCMakeInstance() const;
|
cmake *GetCMakeInstance() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the source files this makefile knows about
|
||||||
|
*/
|
||||||
|
const std::vector<cmSourceFile*> &GetSourceFiles() const
|
||||||
|
{return m_SourceFiles;}
|
||||||
|
std::vector<cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is there a source file that has the provided source file as an output?
|
||||||
|
* if so then return it
|
||||||
|
*/
|
||||||
|
cmSourceFile *GetSourceFileWithOutput(const char *outName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// add link libraries and directories to the target
|
// add link libraries and directories to the target
|
||||||
void AddGlobalLinkInformation(const char* name, cmTarget& target);
|
void AddGlobalLinkInformation(const char* name, cmTarget& target);
|
||||||
|
|
|
@ -29,6 +29,7 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
|
||||||
// first collect up the list of files
|
// first collect up the list of files
|
||||||
std::vector<std::string> propertyPairs;
|
std::vector<std::string> propertyPairs;
|
||||||
bool doingFiles = true;
|
bool doingFiles = true;
|
||||||
|
bool generated = false;
|
||||||
int numFiles = 0;
|
int numFiles = 0;
|
||||||
std::vector<std::string>::const_iterator j;
|
std::vector<std::string>::const_iterator j;
|
||||||
for(j= args.begin(); j != args.end();++j)
|
for(j= args.begin(); j != args.end();++j)
|
||||||
|
@ -49,6 +50,7 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
|
||||||
else if(*j == "GENERATED")
|
else if(*j == "GENERATED")
|
||||||
{
|
{
|
||||||
doingFiles = false;
|
doingFiles = false;
|
||||||
|
generated = true;
|
||||||
propertyPairs.push_back("GENERATED");
|
propertyPairs.push_back("GENERATED");
|
||||||
propertyPairs.push_back("1");
|
propertyPairs.push_back("1");
|
||||||
}
|
}
|
||||||
|
@ -84,7 +86,18 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
|
||||||
while (j != args.end())
|
while (j != args.end())
|
||||||
{
|
{
|
||||||
propertyPairs.push_back(*j);
|
propertyPairs.push_back(*j);
|
||||||
++j;
|
if(*j == "GENERATED")
|
||||||
|
{
|
||||||
|
++j;
|
||||||
|
if(j != args.end() && cmSystemTools::IsOn(j->c_str()))
|
||||||
|
{
|
||||||
|
generated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++j;
|
||||||
|
}
|
||||||
if(j == args.end())
|
if(j == args.end())
|
||||||
{
|
{
|
||||||
this->SetError("called with incorrect number of arguments.");
|
this->SetError("called with incorrect number of arguments.");
|
||||||
|
@ -112,67 +125,13 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
for(i = 0; i < numFiles; ++i)
|
for(i = 0; i < numFiles; ++i)
|
||||||
{
|
{
|
||||||
// if the file is already in the makefile just set properites on it
|
// get the source file
|
||||||
cmSourceFile* sf = m_Makefile->GetSource(args[i].c_str());
|
cmSourceFile* sf =
|
||||||
if(sf)
|
m_Makefile->GetOrCreateSource(args[i].c_str(), generated);
|
||||||
|
// now loop through all the props and set them
|
||||||
|
for (k = 0; k < propertyPairs.size(); k = k + 2)
|
||||||
{
|
{
|
||||||
// now loop through all the props and set them
|
sf->SetProperty(propertyPairs[k].c_str(),propertyPairs[k+1].c_str());
|
||||||
for (k = 0; k < propertyPairs.size(); k = k + 2)
|
|
||||||
{
|
|
||||||
sf->SetProperty(propertyPairs[k].c_str(),propertyPairs[k+1].c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if file is not already in the makefile, then add it
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string newfile = args[i];
|
|
||||||
cmSourceFile file;
|
|
||||||
std::string path = cmSystemTools::GetFilenamePath(newfile);
|
|
||||||
// now loop through all the props and set them
|
|
||||||
for (k = 0; k < propertyPairs.size(); k = k + 2)
|
|
||||||
{
|
|
||||||
file.SetProperty(propertyPairs[k].c_str(),propertyPairs[k+1].c_str());
|
|
||||||
}
|
|
||||||
if(file.GetPropertyAsBool("GENERATED"))
|
|
||||||
{
|
|
||||||
std::string ext = cmSystemTools::GetFilenameExtension(newfile);
|
|
||||||
std::string name_no_ext = cmSystemTools::GetFilenameName(newfile.c_str());
|
|
||||||
name_no_ext = name_no_ext.substr(0, name_no_ext.length()-ext.length());
|
|
||||||
if ( ext.length() && ext[0] == '.' )
|
|
||||||
{
|
|
||||||
ext = ext.substr(1);
|
|
||||||
}
|
|
||||||
if((path.size() && path[0] == '/') ||
|
|
||||||
(path.size() > 1 && path[1] == ':'))
|
|
||||||
{
|
|
||||||
file.SetName(name_no_ext.c_str(), path.c_str(), ext.c_str(), false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file.SetName(name_no_ext.c_str(), m_Makefile->GetCurrentOutputDirectory(),
|
|
||||||
ext.c_str(), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if this is a full path then
|
|
||||||
if((path.size() && path[0] == '/') ||
|
|
||||||
(path.size() > 1 && path[1] == ':'))
|
|
||||||
{
|
|
||||||
file.SetName(cmSystemTools::GetFilenameName(newfile.c_str()).c_str(),
|
|
||||||
path.c_str(),
|
|
||||||
m_Makefile->GetSourceExtensions(),
|
|
||||||
m_Makefile->GetHeaderExtensions());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file.SetName(newfile.c_str(), m_Makefile->GetCurrentDirectory(),
|
|
||||||
m_Makefile->GetSourceExtensions(),
|
|
||||||
m_Makefile->GetHeaderExtensions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add the source file to the makefile
|
|
||||||
m_Makefile->AddSource(file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define cmSourceFile_h
|
#define cmSourceFile_h
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
#include "cmStandardIncludes.h"
|
||||||
|
#include "cmCustomCommand.h"
|
||||||
|
|
||||||
/** \class cmSourceFile
|
/** \class cmSourceFile
|
||||||
* \brief Represent a class loaded from a makefile.
|
* \brief Represent a class loaded from a makefile.
|
||||||
|
@ -34,6 +35,11 @@ public:
|
||||||
*/
|
*/
|
||||||
cmSourceFile()
|
cmSourceFile()
|
||||||
{
|
{
|
||||||
|
m_CustomCommand = 0;
|
||||||
|
}
|
||||||
|
~cmSourceFile()
|
||||||
|
{
|
||||||
|
if (m_CustomCommand) { delete m_CustomCommand; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,6 +51,15 @@ public:
|
||||||
const std::vector<std::string>& sourceExts,
|
const std::vector<std::string>& sourceExts,
|
||||||
const std::vector<std::string>& headerExts);
|
const std::vector<std::string>& headerExts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of the custom commands for this source file
|
||||||
|
*/
|
||||||
|
const cmCustomCommand *GetCustomCommand() const
|
||||||
|
{return m_CustomCommand;}
|
||||||
|
cmCustomCommand *GetCustomCommand() {return m_CustomCommand;}
|
||||||
|
void SetCustomCommand(cmCustomCommand *cc)
|
||||||
|
{ m_CustomCommand = cc;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of the file, given the directory the file should be in. IN
|
* Set the name of the file, given the directory the file should be in. IN
|
||||||
* this version the extension is provided in the call. This is useful for
|
* this version the extension is provided in the call. This is useful for
|
||||||
|
@ -77,8 +92,7 @@ public:
|
||||||
void SetSourceName(const char *name) {m_SourceName = name;}
|
void SetSourceName(const char *name) {m_SourceName = name;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file name associated with stripped off directory and extension.
|
* The file extension associated with source file
|
||||||
* (In most cases this is the name of the class.)
|
|
||||||
*/
|
*/
|
||||||
const std::string &GetSourceExtension() const {return m_SourceExtension;}
|
const std::string &GetSourceExtension() const {return m_SourceExtension;}
|
||||||
void SetSourceExtension(const char *name) {m_SourceExtension = name;}
|
void SetSourceExtension(const char *name) {m_SourceExtension = name;}
|
||||||
|
@ -90,8 +104,8 @@ public:
|
||||||
std::vector<std::string> &GetDepends() {return m_Depends;}
|
std::vector<std::string> &GetDepends() {return m_Depends;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<cmStdString,cmStdString> m_Properties;
|
std::map<cmStdString,cmStdString> m_Properties;
|
||||||
|
cmCustomCommand *m_CustomCommand;
|
||||||
std::string m_FullPath;
|
std::string m_FullPath;
|
||||||
std::string m_SourceName;
|
std::string m_SourceName;
|
||||||
std::string m_SourceExtension;
|
std::string m_SourceExtension;
|
||||||
|
|
|
@ -33,7 +33,7 @@ cmSourceGroup::cmSourceGroup(const char* name, const char* regex):
|
||||||
cmSourceGroup::cmSourceGroup(const cmSourceGroup& r):
|
cmSourceGroup::cmSourceGroup(const cmSourceGroup& r):
|
||||||
m_Name(r.m_Name),
|
m_Name(r.m_Name),
|
||||||
m_GroupRegex(r.m_GroupRegex),
|
m_GroupRegex(r.m_GroupRegex),
|
||||||
m_BuildRules(r.m_BuildRules)
|
m_SourceFiles(r.m_SourceFiles)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,100 +52,6 @@ bool cmSourceGroup::Matches(const char* name)
|
||||||
*/
|
*/
|
||||||
void cmSourceGroup::AddSource(const char* name, const cmSourceFile* sf)
|
void cmSourceGroup::AddSource(const char* name, const cmSourceFile* sf)
|
||||||
{
|
{
|
||||||
BuildRules::iterator s = m_BuildRules.find(name);
|
m_SourceFiles.push_back(sf);
|
||||||
if(s == m_BuildRules.end())
|
|
||||||
{
|
|
||||||
SourceAndCommands sc;
|
|
||||||
sc.m_SourceFile = sf;
|
|
||||||
// The source was not found. Add it with no commands.
|
|
||||||
m_BuildRules[name] = sc;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a source and corresponding custom command to the group. If the
|
|
||||||
* source already exists, the command will be added to its set of commands.
|
|
||||||
* If the command also already exists, the given dependencies and outputs
|
|
||||||
* are added to it.
|
|
||||||
*/
|
|
||||||
void cmSourceGroup::AddCustomCommand(const cmCustomCommand &cmd)
|
|
||||||
{
|
|
||||||
std::string commandAndArgs = cmd.GetCommandAndArguments();
|
|
||||||
BuildRules::iterator s = m_BuildRules.find(cmd.GetSourceName());
|
|
||||||
if(s == m_BuildRules.end())
|
|
||||||
{
|
|
||||||
// The source was not found. Add it with this command.
|
|
||||||
CommandFiles& cmdFiles =
|
|
||||||
m_BuildRules[cmd.GetSourceName()].m_Commands[commandAndArgs];
|
|
||||||
cmdFiles.m_Command = cmd.GetCommand();
|
|
||||||
cmdFiles.m_Comment = cmd.GetComment();
|
|
||||||
cmdFiles.m_Arguments = cmd.GetArguments();
|
|
||||||
cmdFiles.m_Depends.insert(cmd.GetDepends().begin(),cmd.GetDepends().end());
|
|
||||||
cmdFiles.m_Outputs.insert(cmd.GetOutputs().begin(),cmd.GetOutputs().end());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The source already exists. See if the command exists.
|
|
||||||
Commands& commands = s->second.m_Commands;
|
|
||||||
Commands::iterator c = commands.find(commandAndArgs);
|
|
||||||
if(c == commands.end())
|
|
||||||
{
|
|
||||||
// The command did not exist. Add it.
|
|
||||||
commands[commandAndArgs].m_Command = cmd.GetCommand();
|
|
||||||
commands[commandAndArgs].m_Comment = cmd.GetComment();
|
|
||||||
commands[commandAndArgs].m_Arguments = cmd.GetArguments();
|
|
||||||
commands[commandAndArgs].m_Depends.insert(cmd.GetDepends().begin(),
|
|
||||||
cmd.GetDepends().end());
|
|
||||||
commands[commandAndArgs].m_Outputs.insert(cmd.GetOutputs().begin(),
|
|
||||||
cmd.GetOutputs().end());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The command already exists for this source. Merge the sets.
|
|
||||||
CommandFiles& commandFiles = c->second;
|
|
||||||
commandFiles.m_Depends.insert(cmd.GetDepends().begin(),
|
|
||||||
cmd.GetDepends().end());
|
|
||||||
commandFiles.m_Outputs.insert(cmd.GetOutputs().begin(),
|
|
||||||
cmd.GetOutputs().end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmSourceGroup::Print() const
|
|
||||||
{
|
|
||||||
std::cout << "cmSourceGroup: " << m_Name.c_str() << "\n";
|
|
||||||
for(BuildRules::const_iterator i = m_BuildRules.begin();
|
|
||||||
i != m_BuildRules.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << "BuildRule: " << i->first.c_str() << "\n";
|
|
||||||
for(Commands::const_iterator j = i->second.m_Commands.begin();
|
|
||||||
j != i->second.m_Commands.end(); ++j)
|
|
||||||
{
|
|
||||||
std::cout << "FullCommand: " << j->first.c_str() << "\n";
|
|
||||||
std::cout << "Command: " << j->second.m_Command.c_str() << "\n";
|
|
||||||
std::cout << "Arguments: " << j->second.m_Arguments.c_str() << "\n";
|
|
||||||
std::cout << "Command Outputs "
|
|
||||||
<< static_cast<int>(j->second.m_Outputs.size()) << "\n";
|
|
||||||
std::cout << "Command Depends "
|
|
||||||
<< static_cast<int>(j->second.m_Depends.size()) << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cmSourceGroup::CommandFiles::Merge(const CommandFiles &r)
|
|
||||||
{
|
|
||||||
std::set<std::string>::const_iterator dep = r.m_Depends.begin();
|
|
||||||
std::set<std::string>::const_iterator out = r.m_Outputs.begin();
|
|
||||||
for (;dep != r.m_Depends.end(); ++dep)
|
|
||||||
{
|
|
||||||
this->m_Depends.insert(*dep);
|
|
||||||
}
|
|
||||||
for (;out != r.m_Outputs.end(); ++out)
|
|
||||||
{
|
|
||||||
this->m_Outputs.insert(*out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
#include "cmStandardIncludes.h"
|
||||||
#include "cmRegularExpression.h"
|
#include "cmRegularExpression.h"
|
||||||
#include "cmCustomCommand.h"
|
|
||||||
class cmSourceFile;
|
class cmSourceFile;
|
||||||
|
|
||||||
/** \class cmSourceGroup
|
/** \class cmSourceGroup
|
||||||
|
@ -35,47 +34,20 @@ public:
|
||||||
cmSourceGroup(const cmSourceGroup&);
|
cmSourceGroup(const cmSourceGroup&);
|
||||||
~cmSourceGroup() {}
|
~cmSourceGroup() {}
|
||||||
|
|
||||||
struct CommandFiles
|
|
||||||
{
|
|
||||||
CommandFiles() {}
|
|
||||||
CommandFiles(const CommandFiles& r):
|
|
||||||
m_Comment(r.m_Comment), m_Outputs(r.m_Outputs), m_Depends(r.m_Depends) {}
|
|
||||||
|
|
||||||
void Merge(const CommandFiles &r);
|
|
||||||
|
|
||||||
std::string m_Command;
|
|
||||||
std::string m_Arguments;
|
|
||||||
std::string m_Comment;
|
|
||||||
std::set<std::string> m_Outputs;
|
|
||||||
std::set<std::string> m_Depends;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map from command to its output/depends sets.
|
|
||||||
*/
|
|
||||||
typedef std::map<cmStdString, CommandFiles> Commands;
|
|
||||||
|
|
||||||
struct SourceAndCommands
|
|
||||||
{
|
|
||||||
SourceAndCommands(): m_SourceFile(0) {}
|
|
||||||
const cmSourceFile* m_SourceFile;
|
|
||||||
Commands m_Commands;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Map from source to command map.
|
|
||||||
*/
|
|
||||||
typedef std::map<cmStdString, SourceAndCommands> BuildRules;
|
|
||||||
|
|
||||||
bool Matches(const char* name);
|
|
||||||
void SetGroupRegex(const char* regex)
|
void SetGroupRegex(const char* regex)
|
||||||
{ m_GroupRegex.compile(regex); }
|
{ m_GroupRegex.compile(regex); }
|
||||||
void AddSource(const char* name, const cmSourceFile*);
|
void AddSource(const char* name, const cmSourceFile*);
|
||||||
void AddCustomCommand(const cmCustomCommand &cmd);
|
|
||||||
const char* GetName() const
|
const char* GetName() const
|
||||||
{ return m_Name.c_str(); }
|
{ return m_Name.c_str(); }
|
||||||
const BuildRules& GetBuildRules() const
|
bool Matches(const char *);
|
||||||
{ return m_BuildRules; }
|
|
||||||
void Print() const;
|
/**
|
||||||
|
* Get the list of the source files used by this target
|
||||||
|
*/
|
||||||
|
const std::vector<const cmSourceFile*> &GetSourceFiles() const
|
||||||
|
{return m_SourceFiles;}
|
||||||
|
std::vector<const cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* The name of the source group.
|
* The name of the source group.
|
||||||
|
@ -88,11 +60,9 @@ private:
|
||||||
cmRegularExpression m_GroupRegex;
|
cmRegularExpression m_GroupRegex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from source name to the commands to build from the source.
|
* vector of all source files in this source group
|
||||||
* Some commands may build from files that the compiler also knows how to
|
|
||||||
* build.
|
|
||||||
*/
|
*/
|
||||||
BuildRules m_BuildRules;
|
std::vector<const cmSourceFile*> m_SourceFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1932,6 +1932,25 @@ std::string cmSystemTools::GetFilenameExtension(const std::string& filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return file extension of a full filename (dot included).
|
||||||
|
* Warning: this is the shortest extension (for example: .tar.gz)
|
||||||
|
*/
|
||||||
|
std::string
|
||||||
|
cmSystemTools::GetFilenameLastExtension(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::string name = cmSystemTools::GetFilenameName(filename);
|
||||||
|
std::string::size_type dot_pos = name.rfind(".");
|
||||||
|
if(dot_pos != std::string::npos)
|
||||||
|
{
|
||||||
|
return name.substr(dot_pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return file name without extension of a full filename (i.e. without path).
|
* Return file name without extension of a full filename (i.e. without path).
|
||||||
|
|
|
@ -284,6 +284,9 @@ public:
|
||||||
///! return file extension of a full filename (dot included).
|
///! return file extension of a full filename (dot included).
|
||||||
static std::string GetFilenameExtension(const std::string&);
|
static std::string GetFilenameExtension(const std::string&);
|
||||||
|
|
||||||
|
///! return file extension of a full filename (dot included).
|
||||||
|
static std::string GetFilenameLastExtension(const std::string&);
|
||||||
|
|
||||||
///! return file name without extension of a full filename.
|
///! return file name without extension of a full filename.
|
||||||
static std::string GetFilenameWithoutExtension(const std::string&);
|
static std::string GetFilenameWithoutExtension(const std::string&);
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ public:
|
||||||
SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, INSTALL_FILES,
|
SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, INSTALL_FILES,
|
||||||
INSTALL_PROGRAMS };
|
INSTALL_PROGRAMS };
|
||||||
|
|
||||||
|
enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the type of target.
|
* Return the type of target.
|
||||||
*/
|
*/
|
||||||
|
@ -57,8 +59,18 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get the list of the custom commands for this target
|
* Get the list of the custom commands for this target
|
||||||
*/
|
*/
|
||||||
const std::vector<cmCustomCommand> &GetCustomCommands() const {return m_CustomCommands;}
|
const std::vector<cmCustomCommand> &GetPreBuildCommands() const
|
||||||
std::vector<cmCustomCommand> &GetCustomCommands() {return m_CustomCommands;}
|
{return m_PreBuildCommands;}
|
||||||
|
std::vector<cmCustomCommand> &GetPreBuildCommands()
|
||||||
|
{return m_PreBuildCommands;}
|
||||||
|
const std::vector<cmCustomCommand> &GetPreLinkCommands() const
|
||||||
|
{return m_PreLinkCommands;}
|
||||||
|
std::vector<cmCustomCommand> &GetPreLinkCommands()
|
||||||
|
{return m_PreLinkCommands;}
|
||||||
|
const std::vector<cmCustomCommand> &GetPostBuildCommands() const
|
||||||
|
{return m_PostBuildCommands;}
|
||||||
|
std::vector<cmCustomCommand> &GetPostBuildCommands()
|
||||||
|
{return m_PostBuildCommands;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of the source lists used by this target
|
* Get the list of the source lists used by this target
|
||||||
|
@ -186,7 +198,9 @@ private:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<cmCustomCommand> m_CustomCommands;
|
std::vector<cmCustomCommand> m_PreBuildCommands;
|
||||||
|
std::vector<cmCustomCommand> m_PreLinkCommands;
|
||||||
|
std::vector<cmCustomCommand> m_PostBuildCommands;
|
||||||
std::vector<std::string> m_SourceLists;
|
std::vector<std::string> m_SourceLists;
|
||||||
TargetType m_TargetType;
|
TargetType m_TargetType;
|
||||||
std::vector<cmSourceFile*> m_SourceFiles;
|
std::vector<cmSourceFile*> m_SourceFiles;
|
||||||
|
|
Loading…
Reference in New Issue