add_custom_command: Evaluate generator expressions in DEPENDS
Rely on evaluation in cmCustomCommandGenerator for the generators. When tracing target dependencies, depend on the union of dependencies for all configurations.
This commit is contained in:
parent
fb4aff058d
commit
bbffccca42
|
@ -156,3 +156,7 @@ target is built before any target using this custom command.
|
||||||
Additionally, if the target is an executable or library a file-level
|
Additionally, if the target is an executable or library a file-level
|
||||||
dependency is created to cause the custom command to re-run whenever
|
dependency is created to cause the custom command to re-run whenever
|
||||||
the target is recompiled.
|
the target is recompiled.
|
||||||
|
|
||||||
|
Arguments to ``DEPENDS`` may use "generator expressions" with the syntax
|
||||||
|
``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for
|
||||||
|
available expressions.
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
add_custom_command-DEPENDS-genex
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
* The :command:`add_custom_command` command learned to interpret
|
||||||
|
:manual:`cmake-generator-expressions(7)` in arguments to ``DEPENDS``.
|
|
@ -21,7 +21,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
|
||||||
cmCustomCommand const& cc, const std::string& config, cmMakefile* mf):
|
cmCustomCommand const& cc, const std::string& config, cmMakefile* mf):
|
||||||
CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
|
CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
|
||||||
OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
|
OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
|
||||||
GE(new cmGeneratorExpression(cc.GetBacktrace()))
|
GE(new cmGeneratorExpression(cc.GetBacktrace())), DependsDone(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,5 +93,19 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
|
std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
|
||||||
{
|
{
|
||||||
return this->CC.GetDepends();
|
if (!this->DependsDone)
|
||||||
|
{
|
||||||
|
this->DependsDone = true;
|
||||||
|
std::vector<std::string> depends = this->CC.GetDepends();
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
i = depends.begin();
|
||||||
|
i != depends.end(); ++i)
|
||||||
|
{
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
|
||||||
|
= this->GE->Parse(*i);
|
||||||
|
cmSystemTools::ExpandListArgument(
|
||||||
|
cge->Evaluate(this->Makefile, this->Config), this->Depends);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this->Depends;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ class cmCustomCommandGenerator
|
||||||
bool OldStyle;
|
bool OldStyle;
|
||||||
bool MakeVars;
|
bool MakeVars;
|
||||||
cmGeneratorExpression* GE;
|
cmGeneratorExpression* GE;
|
||||||
|
mutable bool DependsDone;
|
||||||
|
mutable std::vector<std::string> Depends;
|
||||||
public:
|
public:
|
||||||
cmCustomCommandGenerator(cmCustomCommand const& cc,
|
cmCustomCommandGenerator(cmCustomCommand const& cc,
|
||||||
const std::string& config,
|
const std::string& config,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
#include "cmGeneratorExpressionDAGChecker.h"
|
#include "cmGeneratorExpressionDAGChecker.h"
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
|
#include "cmCustomCommandGenerator.h"
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
@ -610,6 +611,9 @@ private:
|
||||||
bool IsUtility(std::string const& dep);
|
bool IsUtility(std::string const& dep);
|
||||||
void CheckCustomCommand(cmCustomCommand const& cc);
|
void CheckCustomCommand(cmCustomCommand const& cc);
|
||||||
void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
|
void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
|
||||||
|
void FollowCommandDepends(cmCustomCommand const& cc,
|
||||||
|
const std::string& config,
|
||||||
|
std::set<std::string>& emitted);
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -826,11 +830,35 @@ cmTargetTraceDependencies
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue the custom command dependencies.
|
// Queue the custom command dependencies.
|
||||||
std::vector<std::string> const& depends = cc.GetDepends();
|
std::vector<std::string> configs;
|
||||||
|
std::set<std::string> emitted;
|
||||||
|
this->Makefile->GetConfigurations(configs);
|
||||||
|
if (configs.empty())
|
||||||
|
{
|
||||||
|
configs.push_back("");
|
||||||
|
}
|
||||||
|
for(std::vector<std::string>::const_iterator ci = configs.begin();
|
||||||
|
ci != configs.end(); ++ci)
|
||||||
|
{
|
||||||
|
this->FollowCommandDepends(cc, *ci, emitted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTargetTraceDependencies::FollowCommandDepends(cmCustomCommand const& cc,
|
||||||
|
const std::string& config,
|
||||||
|
std::set<std::string>& emitted)
|
||||||
|
{
|
||||||
|
cmCustomCommandGenerator ccg(cc, config, this->Makefile);
|
||||||
|
|
||||||
|
const std::vector<std::string>& depends = ccg.GetDepends();
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator di = depends.begin();
|
for(std::vector<std::string>::const_iterator di = depends.begin();
|
||||||
di != depends.end(); ++di)
|
di != depends.end(); ++di)
|
||||||
{
|
{
|
||||||
std::string const& dep = *di;
|
std::string const& dep = *di;
|
||||||
|
if(emitted.insert(dep).second)
|
||||||
|
{
|
||||||
if(!this->IsUtility(dep))
|
if(!this->IsUtility(dep))
|
||||||
{
|
{
|
||||||
// The dependency does not name a target and may be a file we
|
// The dependency does not name a target and may be a file we
|
||||||
|
@ -838,6 +866,7 @@ cmTargetTraceDependencies
|
||||||
this->FollowName(dep);
|
this->FollowName(dep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -185,7 +185,7 @@ add_executable(CustomCommand
|
||||||
# here to test adding the generation rule after referencing the
|
# here to test adding the generation rule after referencing the
|
||||||
# generated source in a target.
|
# generated source in a target.
|
||||||
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
|
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
|
||||||
DEPENDS generator
|
DEPENDS $<1:generator> $<0:does_not_exist>
|
||||||
COMMAND generator
|
COMMAND generator
|
||||||
ARGS ${PROJECT_BINARY_DIR}/generated.c
|
ARGS ${PROJECT_BINARY_DIR}/generated.c
|
||||||
)
|
)
|
||||||
|
@ -221,8 +221,11 @@ add_subdirectory(GeneratorInExtraDir)
|
||||||
|
|
||||||
add_executable(tcat tcat.cxx)
|
add_executable(tcat tcat.cxx)
|
||||||
|
|
||||||
|
# Test that list expansion from a generator expression works.
|
||||||
|
set_property(TARGET tcat PROPERTY DEPSLIST tcat gen_redirect_in.c)
|
||||||
|
|
||||||
add_custom_command(OUTPUT gen_redirect.c
|
add_custom_command(OUTPUT gen_redirect.c
|
||||||
DEPENDS tcat gen_redirect_in.c
|
DEPENDS $<TARGET_PROPERTY:tcat,DEPSLIST>
|
||||||
COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
|
COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
|
COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
|
||||||
VERBATIM
|
VERBATIM
|
||||||
|
|
Loading…
Reference in New Issue