ENH: Add SKIP_RULE_DEPENDS option for add_custom_command()
- Allows make rules to be created with no dependencies. - Such rules will not re-run even if the commands themselves change. - Useful to create rules that run only if the output is missing.
This commit is contained in:
parent
3fb5602e54
commit
600e5e274e
|
@ -40,6 +40,7 @@ bool cmAddCustomCommandCommand
|
||||||
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;
|
||||||
|
bool skip_rule_depends = false;
|
||||||
std::string implicit_depends_lang;
|
std::string implicit_depends_lang;
|
||||||
cmCustomCommand::ImplicitDependsList implicit_depends;
|
cmCustomCommand::ImplicitDependsList implicit_depends;
|
||||||
|
|
||||||
|
@ -103,6 +104,11 @@ bool cmAddCustomCommandCommand
|
||||||
{
|
{
|
||||||
verbatim = true;
|
verbatim = true;
|
||||||
}
|
}
|
||||||
|
else if(copy == "SKIP_RULE_DEPENDS")
|
||||||
|
{
|
||||||
|
doing = doing_nothing;
|
||||||
|
skip_rule_depends = true;
|
||||||
|
}
|
||||||
else if(copy == "APPEND")
|
else if(copy == "APPEND")
|
||||||
{
|
{
|
||||||
append = true;
|
append = true;
|
||||||
|
@ -310,8 +316,8 @@ bool cmAddCustomCommandCommand
|
||||||
working.c_str(), false,
|
working.c_str(), false,
|
||||||
escapeOldStyle);
|
escapeOldStyle);
|
||||||
|
|
||||||
// Add implicit dependency scanning requests if any were given.
|
// Get the rule object to add some extra information.
|
||||||
if(!implicit_depends.empty())
|
if(!implicit_depends.empty() || skip_rule_depends)
|
||||||
{
|
{
|
||||||
bool okay = false;
|
bool okay = false;
|
||||||
if(cmSourceFile* sf =
|
if(cmSourceFile* sf =
|
||||||
|
@ -320,7 +326,16 @@ bool cmAddCustomCommandCommand
|
||||||
if(cmCustomCommand* cc = sf->GetCustomCommand())
|
if(cmCustomCommand* cc = sf->GetCustomCommand())
|
||||||
{
|
{
|
||||||
okay = true;
|
okay = true;
|
||||||
cc->SetImplicitDepends(implicit_depends);
|
|
||||||
|
// Add implicit dependency scanning requests if any were
|
||||||
|
// given.
|
||||||
|
if(!implicit_depends.empty())
|
||||||
|
{
|
||||||
|
cc->SetImplicitDepends(implicit_depends);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the rule dependency state.
|
||||||
|
cc->SetSkipRuleDepends(skip_rule_depends);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!okay)
|
if(!okay)
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
" COMMAND command1 [ARGS] [args1...]\n"
|
" COMMAND command1 [ARGS] [args1...]\n"
|
||||||
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
||||||
" [MAIN_DEPENDENCY depend]\n"
|
" [MAIN_DEPENDENCY depend]\n"
|
||||||
" [DEPENDS [depends...]]\n"
|
" [DEPENDS [depends...]] [SKIP_RULE_DEPENDS]\n"
|
||||||
" [IMPLICIT_DEPENDS <lang1> depend1 ...]\n"
|
" [IMPLICIT_DEPENDS <lang1> depend1 ...]\n"
|
||||||
" [WORKING_DIRECTORY dir]\n"
|
" [WORKING_DIRECTORY dir]\n"
|
||||||
" [COMMENT comment] [VERBATIM] [APPEND])\n"
|
" [COMMENT comment] [VERBATIM] [APPEND])\n"
|
||||||
|
@ -134,6 +134,12 @@ 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 SKIP_RULE_DEPENDS option prevents the custom build rule from "
|
||||||
|
"having a dependency on itself. This prevents the rule from running "
|
||||||
|
"again just because the command changed but is useful to create "
|
||||||
|
"rules that have absolutely no dependencies. Such rules run only "
|
||||||
|
"when the output file is missing.\n"
|
||||||
|
|
||||||
"The IMPLICIT_DEPENDS option requests scanning of implicit "
|
"The IMPLICIT_DEPENDS option requests scanning of implicit "
|
||||||
"dependencies of an input file. The language given specifies the "
|
"dependencies of an input file. The language given specifies the "
|
||||||
"programming language whose corresponding dependency scanner should "
|
"programming language whose corresponding dependency scanner should "
|
||||||
|
|
|
@ -22,6 +22,7 @@ cmCustomCommand::cmCustomCommand()
|
||||||
this->HaveComment = false;
|
this->HaveComment = false;
|
||||||
this->EscapeOldStyle = true;
|
this->EscapeOldStyle = true;
|
||||||
this->EscapeAllowMakeVars = false;
|
this->EscapeAllowMakeVars = false;
|
||||||
|
this->SkipRuleDepends = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -50,10 +51,9 @@ cmCustomCommand::cmCustomCommand(const std::vector<std::string>& outputs,
|
||||||
Comment(comment?comment:""),
|
Comment(comment?comment:""),
|
||||||
WorkingDirectory(workingDirectory?workingDirectory:""),
|
WorkingDirectory(workingDirectory?workingDirectory:""),
|
||||||
EscapeAllowMakeVars(false),
|
EscapeAllowMakeVars(false),
|
||||||
EscapeOldStyle(true)
|
EscapeOldStyle(true),
|
||||||
|
SkipRuleDepends(false)
|
||||||
{
|
{
|
||||||
this->EscapeOldStyle = true;
|
|
||||||
this->EscapeAllowMakeVars = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -135,6 +135,18 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b)
|
||||||
this->EscapeAllowMakeVars = b;
|
this->EscapeAllowMakeVars = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmCustomCommand::GetSkipRuleDepends() const
|
||||||
|
{
|
||||||
|
return this->SkipRuleDepends;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmCustomCommand::SetSkipRuleDepends(bool b)
|
||||||
|
{
|
||||||
|
this->SkipRuleDepends = b;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmCustomCommand::ImplicitDependsList const&
|
cmCustomCommand::ImplicitDependsList const&
|
||||||
cmCustomCommand::GetImplicitDepends() const
|
cmCustomCommand::GetImplicitDepends() const
|
||||||
|
|
|
@ -68,6 +68,10 @@ public:
|
||||||
bool GetEscapeAllowMakeVars() const;
|
bool GetEscapeAllowMakeVars() const;
|
||||||
void SetEscapeAllowMakeVars(bool b);
|
void SetEscapeAllowMakeVars(bool b);
|
||||||
|
|
||||||
|
/** Set/Get whether to skip the dependency on the rule itself. */
|
||||||
|
bool GetSkipRuleDepends() const;
|
||||||
|
void SetSkipRuleDepends(bool b);
|
||||||
|
|
||||||
typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair;
|
typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair;
|
||||||
class ImplicitDependsList: public std::vector<ImplicitDependsPair> {};
|
class ImplicitDependsList: public std::vector<ImplicitDependsPair> {};
|
||||||
void SetImplicitDepends(ImplicitDependsList const&);
|
void SetImplicitDepends(ImplicitDependsList const&);
|
||||||
|
@ -83,6 +87,7 @@ private:
|
||||||
std::string WorkingDirectory;
|
std::string WorkingDirectory;
|
||||||
bool EscapeAllowMakeVars;
|
bool EscapeAllowMakeVars;
|
||||||
bool EscapeOldStyle;
|
bool EscapeOldStyle;
|
||||||
|
bool SkipRuleDepends;
|
||||||
ImplicitDependsList ImplicitDepends;
|
ImplicitDependsList ImplicitDepends;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1122,8 +1122,11 @@ void cmMakefileTargetGenerator
|
||||||
this->LocalGenerator->AppendCustomDepend(depends, cc);
|
this->LocalGenerator->AppendCustomDepend(depends, cc);
|
||||||
|
|
||||||
// Add a dependency on the rule file itself.
|
// Add a dependency on the rule file itself.
|
||||||
this->LocalGenerator->AppendRuleDepend(depends,
|
if(!cc.GetSkipRuleDepends())
|
||||||
this->BuildFileNameFull.c_str());
|
{
|
||||||
|
this->LocalGenerator->AppendRuleDepend(depends,
|
||||||
|
this->BuildFileNameFull.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether we need to bother checking for a symbolic output.
|
// Check whether we need to bother checking for a symbolic output.
|
||||||
bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
|
bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
|
||||||
|
|
|
@ -151,6 +151,14 @@ ADD_EXECUTABLE(CustomCommand
|
||||||
${PROJECT_BINARY_DIR}/generated.c
|
${PROJECT_BINARY_DIR}/generated.c
|
||||||
${PROJECT_BINARY_DIR}/not_included.h
|
${PROJECT_BINARY_DIR}/not_included.h
|
||||||
gen_redirect.c # default location for custom commands is in build tree
|
gen_redirect.c # default location for custom commands is in build tree
|
||||||
|
gen_once.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add a rule with no dependencies.
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
OUTPUT gen_once.c
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/gen_once.c.in ${PROJECT_BINARY_DIR}/gen_once.c
|
||||||
|
SKIP_RULE_DEPENDS
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add the rule to create generated.c at build time. This is placed
|
# Add the rule to create generated.c at build time. This is placed
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
|
|
||||||
int generated();
|
int generated();
|
||||||
int wrapped();
|
int wrapped();
|
||||||
|
int gen_once(void);
|
||||||
|
|
||||||
int main ()
|
int main ()
|
||||||
{
|
{
|
||||||
if (generated()*wrapped()*doc() == 3*5*7)
|
if (generated()*wrapped()*doc()*gen_once() == 3*5*7*11)
|
||||||
{
|
{
|
||||||
FILE* fin = fopen(PROJECT_BINARY_DIR "/not_included.h", "r");
|
FILE* fin = fopen(PROJECT_BINARY_DIR "/not_included.h", "r");
|
||||||
if(fin)
|
if(fin)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
int gen_once(void) { return 11; }
|
Loading…
Reference in New Issue