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:
Brad King 2007-09-17 10:50:46 -04:00
parent 267fd538d8
commit d7a5d4c191
5 changed files with 104 additions and 0 deletions

View File

@ -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;
} }

View File

@ -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 "

View File

@ -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());
}

View File

@ -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

View File

@ -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());
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------