diff options
author | Brad King <brad.king@kitware.com> | 2010-12-21 19:03:24 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2010-12-21 19:03:24 (GMT) |
commit | 31b0657e7d4bab3e6c5a00c1318d1c231d8ab44b (patch) | |
tree | 5f16dfb9e9d73794a6c791147a6614b8e5492e2a /Source | |
parent | 533f5a20372829aa41a71ed4698cac2a50820a7e (diff) | |
parent | 4499d50ad2df7c1db4335d40f9fa20c642f59a5d (diff) | |
download | CMake-31b0657e7d4bab3e6c5a00c1318d1c231d8ab44b.zip CMake-31b0657e7d4bab3e6c5a00c1318d1c231d8ab44b.tar.gz CMake-31b0657e7d4bab3e6c5a00c1318d1c231d8ab44b.tar.bz2 |
Merge topic 'custom-command-generator-expressions'
4499d50 Mark CustomCommand test perconfig.out as SYMBOLIC
f0cdb60 Introduce "generator expression" syntax to custom commands (#11209)
4749e4c Record set of targets used in cmGeneratorExpression
ef9e9de Optionally suppress errors in cmGeneratorExpression
45e1953 Factor per-config sample targets out of 'Testing' test
4091bca Factor generator expression docs out of add_test
bfb7288 Record backtrace in cmCustomCommand
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/cmAddCustomCommandCommand.h | 12 | ||||
-rw-r--r-- | Source/cmAddTestCommand.h | 15 | ||||
-rw-r--r-- | Source/cmCustomCommand.cxx | 27 | ||||
-rw-r--r-- | Source/cmCustomCommand.h | 11 | ||||
-rw-r--r-- | Source/cmCustomCommandGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmCustomCommandGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmDocumentGeneratorExpressions.h | 30 | ||||
-rw-r--r-- | Source/cmGeneratorExpression.cxx | 8 | ||||
-rw-r--r-- | Source/cmGeneratorExpression.h | 10 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio6Generator.cxx | 2 | ||||
-rw-r--r-- | Source/cmLocalVisualStudioGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 5 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 17 |
15 files changed, 128 insertions, 31 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 49412d8..f183eb4 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -158,6 +158,7 @@ SET(SRCS cmDocumentationFormatterText.cxx cmDocumentationFormatterUsage.cxx cmDocumentationSection.cxx + cmDocumentGeneratorExpressions.h cmDocumentVariables.cxx cmDynamicLoader.cxx cmDynamicLoader.h diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index 6c5e1af..490e043 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -13,6 +13,7 @@ #define cmAddCustomCommandCommand_h #include "cmCommand.h" +#include "cmDocumentGeneratorExpressions.h" /** \class cmAddCustomCommandCommand * \brief @@ -146,8 +147,15 @@ public: "target-level dependency will be added so that the executable target " "will be built before any target using this custom command. However " "this does NOT add a file-level dependency that would cause the " - "custom command to re-run whenever the executable is recompiled.\n" - + "custom command to re-run whenever the executable is recompiled." + "\n" + "Arguments to COMMAND may use \"generator expressions\" with the " + "syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + "References to target names in generator expressions imply " + "target-level dependencies, but NOT file-level dependencies. " + "List target names with the DEPENDS option to add file dependencies." + "\n" "The DEPENDS option specifies files on which the command depends. " "If any dependency is an OUTPUT of another custom command in the " "same directory (CMakeLists.txt file) CMake automatically brings the " diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index 79fb481..1cc86c4 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -13,6 +13,7 @@ #define cmAddTestCommand_h #include "cmCommand.h" +#include "cmDocumentGeneratorExpressions.h" /** \class cmAddTestCommand * \brief Add a test to the lists of tests to run. @@ -77,19 +78,7 @@ public: "\n" "Arguments after COMMAND may use \"generator expressions\" with the " "syntax \"$<...>\". " - "These expressions are evaluted during build system generation and " - "produce information specific to each generated build configuration. " - "Valid expressions are:\n" - " $<CONFIGURATION> = configuration name\n" - " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" - " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" - " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" - "where \"tgt\" is the name of a target. " - "Target file expressions produce a full path, but _DIR and _NAME " - "versions can produce the directory and file name components:\n" - " $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" - " $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" - " $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS "Example usage:\n" " add_test(NAME mytest\n" " COMMAND testDriver --config $<CONFIGURATION>\n" diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 5db88fa..bd860ee 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmCustomCommand.h" +#include "cmMakefile.h" + //---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand() { @@ -28,12 +30,14 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): Comment(r.Comment), WorkingDirectory(r.WorkingDirectory), EscapeAllowMakeVars(r.EscapeAllowMakeVars), - EscapeOldStyle(r.EscapeOldStyle) + EscapeOldStyle(r.EscapeOldStyle), + Backtrace(new cmListFileBacktrace(*r.Backtrace)) { } //---------------------------------------------------------------------------- -cmCustomCommand::cmCustomCommand(const std::vector<std::string>& outputs, +cmCustomCommand::cmCustomCommand(cmMakefile* mf, + const std::vector<std::string>& outputs, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, const char* comment, @@ -45,10 +49,21 @@ cmCustomCommand::cmCustomCommand(const std::vector<std::string>& outputs, Comment(comment?comment:""), WorkingDirectory(workingDirectory?workingDirectory:""), EscapeAllowMakeVars(false), - EscapeOldStyle(true) + EscapeOldStyle(true), + Backtrace(new cmListFileBacktrace) { this->EscapeOldStyle = true; this->EscapeAllowMakeVars = false; + if(mf) + { + mf->GetBacktrace(*this->Backtrace); + } +} + +//---------------------------------------------------------------------------- +cmCustomCommand::~cmCustomCommand() +{ + delete this->Backtrace; } //---------------------------------------------------------------------------- @@ -131,6 +146,12 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b) } //---------------------------------------------------------------------------- +cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const +{ + return *this->Backtrace; +} + +//---------------------------------------------------------------------------- cmCustomCommand::ImplicitDependsList const& cmCustomCommand::GetImplicitDepends() const { diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index c9adddf..dd92e34 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -13,6 +13,8 @@ #define cmCustomCommand_h #include "cmStandardIncludes.h" +class cmMakefile; +class cmListFileBacktrace; /** \class cmCustomCommand * \brief A class to encapsulate a custom command @@ -27,12 +29,15 @@ public: cmCustomCommand(const cmCustomCommand& r); /** Main constructor specifies all information for the command. */ - cmCustomCommand(const std::vector<std::string>& outputs, + cmCustomCommand(cmMakefile* mf, + const std::vector<std::string>& outputs, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDirectory); + ~cmCustomCommand(); + /** Get the output file produced by the command. */ const std::vector<std::string>& GetOutputs() const; @@ -63,6 +68,9 @@ public: bool GetEscapeAllowMakeVars() const; void SetEscapeAllowMakeVars(bool b); + /** Backtrace of the command that created this custom command. */ + cmListFileBacktrace const& GetBacktrace() const; + typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair; class ImplicitDependsList: public std::vector<ImplicitDependsPair> {}; void SetImplicitDepends(ImplicitDependsList const&); @@ -78,6 +86,7 @@ private: std::string WorkingDirectory; bool EscapeAllowMakeVars; bool EscapeOldStyle; + cmListFileBacktrace* Backtrace; ImplicitDependsList ImplicitDepends; }; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 2a3b553..a650129 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -14,16 +14,24 @@ #include "cmMakefile.h" #include "cmCustomCommand.h" #include "cmLocalGenerator.h" +#include "cmGeneratorExpression.h" //---------------------------------------------------------------------------- cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, const char* config, cmMakefile* mf): CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), - OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()) + OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()), + GE(new cmGeneratorExpression(mf, config, cc.GetBacktrace())) { } //---------------------------------------------------------------------------- +cmCustomCommandGenerator::~cmCustomCommandGenerator() +{ + delete this->GE; +} + +//---------------------------------------------------------------------------- unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const { return static_cast<unsigned int>(this->CC.GetCommandLines().size()); @@ -39,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const { return target->GetLocation(this->Config); } - return argv0; + return this->GE->Process(argv0); } //---------------------------------------------------------------------------- @@ -50,7 +58,7 @@ cmCustomCommandGenerator cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; for(unsigned int j=1;j < commandLine.size(); ++j) { - std::string const& arg = commandLine[j]; + std::string arg = this->GE->Process(commandLine[j]); cmd += " "; if(this->OldStyle) { diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index 5417ec5..4e89f27 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -17,6 +17,7 @@ class cmCustomCommand; class cmMakefile; class cmLocalGenerator; +class cmGeneratorExpression; class cmCustomCommandGenerator { @@ -26,9 +27,11 @@ class cmCustomCommandGenerator cmLocalGenerator* LG; bool OldStyle; bool MakeVars; + cmGeneratorExpression* GE; public: cmCustomCommandGenerator(cmCustomCommand const& cc, const char* config, cmMakefile* mf); + ~cmCustomCommandGenerator(); unsigned int GetNumberOfCommands() const; std::string GetCommand(unsigned int c) const; void AppendArguments(unsigned int c, std::string& cmd) const; diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h new file mode 100644 index 0000000..5359013 --- /dev/null +++ b/Source/cmDocumentGeneratorExpressions.h @@ -0,0 +1,30 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2010 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmDocumentGeneratorExpressions_h +#define cmDocumentGeneratorExpressions_h + +#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \ + "Generator expressions are evaluted during build system generation " \ + "to produce information specific to each build configuration. " \ + "Valid expressions are:\n" \ + " $<CONFIGURATION> = configuration name\n" \ + " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \ + " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \ + " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \ + "where \"tgt\" is the name of a target. " \ + "Target file expressions produce a full path, but _DIR and _NAME " \ + "versions can produce the directory and file name components:\n" \ + " $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" \ + " $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \ + " $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" + +#endif diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index a61880f..8710dfc 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -17,8 +17,8 @@ //---------------------------------------------------------------------------- cmGeneratorExpression::cmGeneratorExpression( cmMakefile* mf, const char* config, - cmListFileBacktrace const& backtrace): - Makefile(mf), Config(config), Backtrace(backtrace) + cmListFileBacktrace const& backtrace, bool quiet): + Makefile(mf), Config(config), Backtrace(backtrace), Quiet(quiet) { this->TargetInfo.compile("^\\$<TARGET" "(|_SONAME|_LINKER)" // File with what purpose? @@ -87,7 +87,7 @@ bool cmGeneratorExpression::Evaluate() this->Data.insert(this->Data.end(), result.begin(), result.end()); return true; } - else + else if(!this->Quiet) { // Failure. Report the error message. cmOStringStream e; @@ -99,6 +99,7 @@ bool cmGeneratorExpression::Evaluate() this->Backtrace); return false; } + return true; } //---------------------------------------------------------------------------- @@ -140,6 +141,7 @@ bool cmGeneratorExpression::EvaluateTargetInfo(std::string& result) result = "Target \"" + name + "\" is not an executable or library."; return false; } + this->Targets.insert(target); // Lookup the target file with the given purpose. std::string purpose = this->TargetInfo.match(1); diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index aa36055..1a9d4c6 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -15,6 +15,7 @@ #include <cmsys/RegularExpression.hxx> +class cmTarget; class cmMakefile; class cmListFileBacktrace; @@ -32,18 +33,25 @@ class cmGeneratorExpression public: /** Construct with an evaluation context and configuration. */ cmGeneratorExpression(cmMakefile* mf, const char* config, - cmListFileBacktrace const& backtrace); + cmListFileBacktrace const& backtrace, + bool quiet = false); /** Evaluate generator expressions in a string. */ const char* Process(std::string const& input); const char* Process(const char* input); + + /** Get set of targets found during evaluations. */ + std::set<cmTarget*> const& GetTargets() const + { return this->Targets; } private: cmMakefile* Makefile; const char* Config; cmListFileBacktrace const& Backtrace; + bool Quiet; std::vector<char> Data; std::stack<size_t> Barriers; cmsys::RegularExpression TargetInfo; + std::set<cmTarget*> Targets; bool Evaluate(); bool Evaluate(const char* expr, std::string& result); bool EvaluateTargetInfo(std::string& result); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ea091f9..123ab5e 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1879,7 +1879,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( std::vector<std::string> no_outputs; std::vector<std::string> no_depends; // Store the custom command in the target. - cmCustomCommand cc(no_outputs, no_depends, *commandLines, 0, + cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0, workingDirectory); target.GetPostBuildCommands().push_back(cc); target.SetProperty("EchoString", message); diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 851c526..7aabf4d 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -838,7 +838,7 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target, std::vector<std::string> no_depends; cmCustomCommandLines commands; commands.push_back(command); - pcc.reset(new cmCustomCommand(no_output, no_depends, commands, 0, 0)); + pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 9a8cbc7..9164beb 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -53,7 +53,7 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, std::vector<std::string> no_depends; cmCustomCommandLines commands; commands.push_back(command); - pcc.reset(new cmCustomCommand(no_output, no_depends, commands, 0, 0)); + pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 1463680..cf03b80 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -827,7 +827,8 @@ cmMakefile::AddCustomCommandToTarget(const char* target, { // Add the command to the appropriate build step for the target. std::vector<std::string> no_output; - cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir); + cmCustomCommand cc(this, no_output, depends, + commandLines, comment, workingDir); cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeAllowMakeVars(true); switch(type) @@ -947,7 +948,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, if(file) { cmCustomCommand* cc = - new cmCustomCommand(outputs, depends2, commandLines, + new cmCustomCommand(this, outputs, depends2, commandLines, comment, workingDir); cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ef274b4..9a698c0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -17,6 +17,7 @@ #include "cmGlobalGenerator.h" #include "cmComputeLinkInformation.h" #include "cmListFileCache.h" +#include "cmGeneratorExpression.h" #include <cmsys/RegularExpression.hxx> #include <map> #include <set> @@ -1402,6 +1403,7 @@ cmTargetTraceDependencies { // Transform command names that reference targets built in this // project to corresponding target-level dependencies. + cmGeneratorExpression ge(this->Makefile, 0, cc.GetBacktrace(), true); for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin(); cit != cc.GetCommandLines().end(); ++cit) { @@ -1418,6 +1420,21 @@ cmTargetTraceDependencies this->Target->AddUtility(command.c_str()); } } + + // Check for target references in generator expressions. + for(cmCustomCommandLine::const_iterator cli = cit->begin(); + cli != cit->end(); ++cli) + { + ge.Process(*cli); + } + } + + // Add target-level dependencies referenced by generator expressions. + std::set<cmTarget*> targets = ge.GetTargets(); + for(std::set<cmTarget*>::iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + this->Target->AddUtility((*ti)->GetName()); } // Queue the custom command dependencies. |