From bbffccca42d4f209220e833e1a86e735a5c83339 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 7 Mar 2014 17:20:10 +0100 Subject: [PATCH] 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. --- Help/command/add_custom_command.rst | 4 ++ .../dev/add_custom_command-DEPENDS-genex.rst | 5 +++ Source/cmCustomCommandGenerator.cxx | 18 ++++++++- Source/cmCustomCommandGenerator.h | 2 + Source/cmGeneratorTarget.cxx | 39 ++++++++++++++++--- Tests/CustomCommand/CMakeLists.txt | 7 +++- 6 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 Help/release/dev/add_custom_command-DEPENDS-genex.rst diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index b0c54460c..028ca5ae5 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -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 dependency is created to cause the custom command to re-run whenever 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. diff --git a/Help/release/dev/add_custom_command-DEPENDS-genex.rst b/Help/release/dev/add_custom_command-DEPENDS-genex.rst new file mode 100644 index 000000000..1e528e680 --- /dev/null +++ b/Help/release/dev/add_custom_command-DEPENDS-genex.rst @@ -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``. diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index a091cff46..cebd9f5d3 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -21,7 +21,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, const std::string& config, cmMakefile* mf): CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()), - GE(new cmGeneratorExpression(cc.GetBacktrace())) + GE(new cmGeneratorExpression(cc.GetBacktrace())), DependsDone(false) { } @@ -93,5 +93,19 @@ std::vector const& cmCustomCommandGenerator::GetOutputs() const //---------------------------------------------------------------------------- std::vector const& cmCustomCommandGenerator::GetDepends() const { - return this->CC.GetDepends(); + if (!this->DependsDone) + { + this->DependsDone = true; + std::vector depends = this->CC.GetDepends(); + for(std::vector::const_iterator + i = depends.begin(); + i != depends.end(); ++i) + { + cmsys::auto_ptr cge + = this->GE->Parse(*i); + cmSystemTools::ExpandListArgument( + cge->Evaluate(this->Makefile, this->Config), this->Depends); + } + } + return this->Depends; } diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index cbcdb413f..0d8a0a4ed 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -28,6 +28,8 @@ class cmCustomCommandGenerator bool OldStyle; bool MakeVars; cmGeneratorExpression* GE; + mutable bool DependsDone; + mutable std::vector Depends; public: cmCustomCommandGenerator(cmCustomCommand const& cc, const std::string& config, diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 2a144c6b2..b35e859e6 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -19,6 +19,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionDAGChecker.h" #include "cmComputeLinkInformation.h" +#include "cmCustomCommandGenerator.h" #include @@ -610,6 +611,9 @@ private: bool IsUtility(std::string const& dep); void CheckCustomCommand(cmCustomCommand const& cc); void CheckCustomCommands(const std::vector& commands); + void FollowCommandDepends(cmCustomCommand const& cc, + const std::string& config, + std::set& emitted); }; //---------------------------------------------------------------------------- @@ -826,16 +830,41 @@ cmTargetTraceDependencies } // Queue the custom command dependencies. - std::vector const& depends = cc.GetDepends(); + std::vector configs; + std::set emitted; + this->Makefile->GetConfigurations(configs); + if (configs.empty()) + { + configs.push_back(""); + } + for(std::vector::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& emitted) +{ + cmCustomCommandGenerator ccg(cc, config, this->Makefile); + + const std::vector& depends = ccg.GetDepends(); + for(std::vector::const_iterator di = depends.begin(); di != depends.end(); ++di) { std::string const& dep = *di; - if(!this->IsUtility(dep)) + if(emitted.insert(dep).second) { - // The dependency does not name a target and may be a file we - // know how to generate. Queue it. - this->FollowName(dep); + if(!this->IsUtility(dep)) + { + // The dependency does not name a target and may be a file we + // know how to generate. Queue it. + this->FollowName(dep); + } } } } diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index bbae38719..a194a5f5d 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -185,7 +185,7 @@ add_executable(CustomCommand # here to test adding the generation rule after referencing the # generated source in a target. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c - DEPENDS generator + DEPENDS $<1:generator> $<0:does_not_exist> COMMAND generator ARGS ${PROJECT_BINARY_DIR}/generated.c ) @@ -221,8 +221,11 @@ add_subdirectory(GeneratorInExtraDir) 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 - DEPENDS tcat gen_redirect_in.c + DEPENDS $ COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c VERBATIM