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;
|
std::vector<std::string> depends, outputs, output;
|
||||||
bool verbatim = false;
|
bool verbatim = false;
|
||||||
bool append = false;
|
bool append = false;
|
||||||
|
std::string implicit_depends_lang;
|
||||||
|
cmCustomCommand::ImplicitDependsList implicit_depends;
|
||||||
|
|
||||||
// Accumulate one command line at a time.
|
// Accumulate one command line at a time.
|
||||||
cmCustomCommandLine currentLine;
|
cmCustomCommandLine currentLine;
|
||||||
|
@ -54,6 +56,8 @@ bool cmAddCustomCommandCommand::InitialPass(
|
||||||
doing_command,
|
doing_command,
|
||||||
doing_target,
|
doing_target,
|
||||||
doing_depends,
|
doing_depends,
|
||||||
|
doing_implicit_depends_lang,
|
||||||
|
doing_implicit_depends_file,
|
||||||
doing_main_dependency,
|
doing_main_dependency,
|
||||||
doing_output,
|
doing_output,
|
||||||
doing_outputs,
|
doing_outputs,
|
||||||
|
@ -131,6 +135,10 @@ bool cmAddCustomCommandCommand::InitialPass(
|
||||||
{
|
{
|
||||||
doing = doing_main_dependency;
|
doing = doing_main_dependency;
|
||||||
}
|
}
|
||||||
|
else if (copy == "IMPLICIT_DEPENDS")
|
||||||
|
{
|
||||||
|
doing = doing_implicit_depends_lang;
|
||||||
|
}
|
||||||
else if (copy == "COMMENT")
|
else if (copy == "COMMENT")
|
||||||
{
|
{
|
||||||
doing = doing_comment;
|
doing = doing_comment;
|
||||||
|
@ -173,6 +181,25 @@ bool cmAddCustomCommandCommand::InitialPass(
|
||||||
case doing_main_dependency:
|
case doing_main_dependency:
|
||||||
main_dependency = copy;
|
main_dependency = copy;
|
||||||
break;
|
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:
|
case doing_command:
|
||||||
currentLine.push_back(copy);
|
currentLine.push_back(copy);
|
||||||
break;
|
break;
|
||||||
|
@ -240,6 +267,7 @@ bool cmAddCustomCommandCommand::InitialPass(
|
||||||
{
|
{
|
||||||
cc->AppendCommands(commandLines);
|
cc->AppendCommands(commandLines);
|
||||||
cc->AppendDepends(depends);
|
cc->AppendDepends(depends);
|
||||||
|
cc->AppendImplicitDepends(implicit_depends);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,6 +299,29 @@ bool cmAddCustomCommandCommand::InitialPass(
|
||||||
commandLines, comment,
|
commandLines, comment,
|
||||||
working.c_str(), false,
|
working.c_str(), false,
|
||||||
escapeOldStyle);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -279,6 +330,7 @@ bool cmAddCustomCommandCommand::InitialPass(
|
||||||
source.c_str(), commandLines,
|
source.c_str(), commandLines,
|
||||||
comment);
|
comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
||||||
" [MAIN_DEPENDENCY depend]\n"
|
" [MAIN_DEPENDENCY depend]\n"
|
||||||
" [DEPENDS [depends...]]\n"
|
" [DEPENDS [depends...]]\n"
|
||||||
|
" [IMPLICIT_DEPENDS <lang1> depend1 ...]\n"
|
||||||
" [WORKING_DIRECTORY dir]\n"
|
" [WORKING_DIRECTORY dir]\n"
|
||||||
" [COMMENT comment] [VERBATIM] [APPEND])\n"
|
" [COMMENT comment] [VERBATIM] [APPEND])\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 "
|
||||||
|
@ -129,6 +130,15 @@ public:
|
||||||
"created as a file on disk it should be marked as SYMBOLIC with "
|
"created as a file on disk it should be marked as SYMBOLIC with "
|
||||||
"SET_SOURCE_FILES_PROPERTIES.\n"
|
"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 "
|
"If COMMAND specifies an executable target (created by "
|
||||||
"ADD_EXECUTABLE) it will automatically be replaced by the location "
|
"ADD_EXECUTABLE) it will automatically be replaced by the location "
|
||||||
"of the executable created at build time. Additionally a "
|
"of the executable created at build time. Additionally a "
|
||||||
|
|
|
@ -134,3 +134,23 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b)
|
||||||
{
|
{
|
||||||
this->EscapeAllowMakeVars = 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;
|
bool GetEscapeAllowMakeVars() const;
|
||||||
void SetEscapeAllowMakeVars(bool b);
|
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:
|
private:
|
||||||
std::vector<std::string> Outputs;
|
std::vector<std::string> Outputs;
|
||||||
std::vector<std::string> Depends;
|
std::vector<std::string> Depends;
|
||||||
|
@ -77,6 +83,7 @@ private:
|
||||||
std::string WorkingDirectory;
|
std::string WorkingDirectory;
|
||||||
bool EscapeAllowMakeVars;
|
bool EscapeAllowMakeVars;
|
||||||
bool EscapeOldStyle;
|
bool EscapeOldStyle;
|
||||||
|
ImplicitDependsList ImplicitDepends;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -939,6 +939,21 @@ void cmMakefileTargetGenerator
|
||||||
}
|
}
|
||||||
this->GenerateExtraOutput(o->c_str(), in, symbolic);
|
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