ENH: Added IMPLICIT_DEPENDS option to ADD_CUSTOM_COMMAND. It currently works only for Makefile generators. It allows a custom command to have implicit dependencies in the form of C or CXX sources.
This commit is contained in:
parent
267fd538d8
commit
d7a5d4c191
|
@ -40,6 +40,8 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
std::vector<std::string> depends, outputs, output;
|
||||
bool verbatim = false;
|
||||
bool append = false;
|
||||
std::string implicit_depends_lang;
|
||||
cmCustomCommand::ImplicitDependsList implicit_depends;
|
||||
|
||||
// Accumulate one command line at a time.
|
||||
cmCustomCommandLine currentLine;
|
||||
|
@ -54,6 +56,8 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
doing_command,
|
||||
doing_target,
|
||||
doing_depends,
|
||||
doing_implicit_depends_lang,
|
||||
doing_implicit_depends_file,
|
||||
doing_main_dependency,
|
||||
doing_output,
|
||||
doing_outputs,
|
||||
|
@ -131,6 +135,10 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
{
|
||||
doing = doing_main_dependency;
|
||||
}
|
||||
else if (copy == "IMPLICIT_DEPENDS")
|
||||
{
|
||||
doing = doing_implicit_depends_lang;
|
||||
}
|
||||
else if (copy == "COMMENT")
|
||||
{
|
||||
doing = doing_comment;
|
||||
|
@ -173,6 +181,25 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
case doing_main_dependency:
|
||||
main_dependency = copy;
|
||||
break;
|
||||
case doing_implicit_depends_lang:
|
||||
implicit_depends_lang = copy;
|
||||
doing = doing_implicit_depends_file;
|
||||
break;
|
||||
case doing_implicit_depends_file:
|
||||
{
|
||||
// An implicit dependency starting point is also an
|
||||
// explicit dependency.
|
||||
depends.push_back(copy);
|
||||
|
||||
// Add the implicit dependency language and file.
|
||||
cmCustomCommand::ImplicitDependsPair
|
||||
entry(implicit_depends_lang, copy);
|
||||
implicit_depends.push_back(entry);
|
||||
|
||||
// Switch back to looking for a language.
|
||||
doing = doing_implicit_depends_lang;
|
||||
}
|
||||
break;
|
||||
case doing_command:
|
||||
currentLine.push_back(copy);
|
||||
break;
|
||||
|
@ -240,6 +267,7 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
{
|
||||
cc->AppendCommands(commandLines);
|
||||
cc->AppendDepends(depends);
|
||||
cc->AppendImplicitDepends(implicit_depends);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +299,29 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
commandLines, comment,
|
||||
working.c_str(), false,
|
||||
escapeOldStyle);
|
||||
|
||||
// Add implicit dependency scanning requests if any were given.
|
||||
if(!implicit_depends.empty())
|
||||
{
|
||||
bool okay = false;
|
||||
if(cmSourceFile* sf =
|
||||
this->Makefile->GetSourceFileWithOutput(output[0].c_str()))
|
||||
{
|
||||
if(cmCustomCommand* cc = sf->GetCustomCommand())
|
||||
{
|
||||
okay = true;
|
||||
cc->SetImplicitDepends(implicit_depends);
|
||||
}
|
||||
}
|
||||
if(!okay)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "could not locate source file with a custom command producing \""
|
||||
<< output[0] << "\" even though this command tried to create it!";
|
||||
this->SetError(e.str().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -279,6 +330,7 @@ bool cmAddCustomCommandCommand::InitialPass(
|
|||
source.c_str(), commandLines,
|
||||
comment);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
||||
" [MAIN_DEPENDENCY depend]\n"
|
||||
" [DEPENDS [depends...]]\n"
|
||||
" [IMPLICIT_DEPENDS <lang1> depend1 ...]\n"
|
||||
" [WORKING_DIRECTORY dir]\n"
|
||||
" [COMMENT comment] [VERBATIM] [APPEND])\n"
|
||||
"This defines a new command that can be executed during the build "
|
||||
|
@ -129,6 +130,15 @@ public:
|
|||
"created as a file on disk it should be marked as SYMBOLIC with "
|
||||
"SET_SOURCE_FILES_PROPERTIES.\n"
|
||||
|
||||
"The IMPLICIT_DEPENDS option requests scanning of implicit "
|
||||
"dependencies of an input file. The language given specifies the "
|
||||
"programming language whose corresponding dependency scanner should "
|
||||
"be used. Currently only C and CXX language scanners are supported. "
|
||||
"Dependencies discovered from the scanning are added to those of "
|
||||
"the custom command at build time. Note that the IMPLICIT_DEPENDS "
|
||||
"option is currently supported only for Makefile generators and "
|
||||
"will be ignored by other generators."
|
||||
"\n"
|
||||
"If COMMAND specifies an executable target (created by "
|
||||
"ADD_EXECUTABLE) it will automatically be replaced by the location "
|
||||
"of the executable created at build time. Additionally a "
|
||||
|
|
|
@ -134,3 +134,23 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b)
|
|||
{
|
||||
this->EscapeAllowMakeVars = b;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmCustomCommand::ImplicitDependsList const&
|
||||
cmCustomCommand::GetImplicitDepends() const
|
||||
{
|
||||
return this->ImplicitDepends;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmCustomCommand::SetImplicitDepends(ImplicitDependsList const& l)
|
||||
{
|
||||
this->ImplicitDepends = l;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
|
||||
{
|
||||
this->ImplicitDepends.insert(this->ImplicitDepends.end(),
|
||||
l.begin(), l.end());
|
||||
}
|
||||
|
|
|
@ -68,6 +68,12 @@ public:
|
|||
bool GetEscapeAllowMakeVars() const;
|
||||
void SetEscapeAllowMakeVars(bool b);
|
||||
|
||||
typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair;
|
||||
class ImplicitDependsList: public std::vector<ImplicitDependsPair> {};
|
||||
void SetImplicitDepends(ImplicitDependsList const&);
|
||||
void AppendImplicitDepends(ImplicitDependsList const&);
|
||||
ImplicitDependsList const& GetImplicitDepends() const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> Outputs;
|
||||
std::vector<std::string> Depends;
|
||||
|
@ -77,6 +83,7 @@ private:
|
|||
std::string WorkingDirectory;
|
||||
bool EscapeAllowMakeVars;
|
||||
bool EscapeOldStyle;
|
||||
ImplicitDependsList ImplicitDepends;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -939,6 +939,21 @@ void cmMakefileTargetGenerator
|
|||
}
|
||||
this->GenerateExtraOutput(o->c_str(), in, symbolic);
|
||||
}
|
||||
|
||||
// Setup implicit dependency scanning.
|
||||
for(cmCustomCommand::ImplicitDependsList::const_iterator
|
||||
idi = cc.GetImplicitDepends().begin();
|
||||
idi != cc.GetImplicitDepends().end(); ++idi)
|
||||
{
|
||||
std::string objFullPath =
|
||||
this->Convert(outputs[0].c_str(), cmLocalGenerator::FULL);
|
||||
std::string srcFullPath =
|
||||
this->Convert(idi->second.c_str(), cmLocalGenerator::FULL);
|
||||
this->LocalGenerator->
|
||||
AddImplicitDepends(*this->Target, idi->first.c_str(),
|
||||
objFullPath.c_str(),
|
||||
srcFullPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue