From bfb7288f8103298bf4cabb60a13208f95595a7db Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 6 Dec 2010 14:33:59 -0500 Subject: Record backtrace in cmCustomCommand This will be used to report custom command errors to the user with a backtrace pointing at the add_custom_command or add_custom_target call. --- Source/cmCustomCommand.cxx | 27 ++++++++++++++++++++++++--- Source/cmCustomCommand.h | 11 ++++++++++- Source/cmGlobalGenerator.cxx | 2 +- Source/cmLocalVisualStudio6Generator.cxx | 2 +- Source/cmLocalVisualStudioGenerator.cxx | 2 +- Source/cmMakefile.cxx | 5 +++-- 6 files changed, 40 insertions(+), 9 deletions(-) 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& outputs, +cmCustomCommand::cmCustomCommand(cmMakefile* mf, + const std::vector& outputs, const std::vector& depends, const cmCustomCommandLines& commandLines, const char* comment, @@ -45,10 +49,21 @@ cmCustomCommand::cmCustomCommand(const std::vector& 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& outputs, + cmCustomCommand(cmMakefile* mf, + const std::vector& outputs, const std::vector& depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDirectory); + ~cmCustomCommand(); + /** Get the output file produced by the command. */ const std::vector& 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 ImplicitDependsPair; class ImplicitDependsList: public std::vector {}; void SetImplicitDepends(ImplicitDependsList const&); @@ -78,6 +86,7 @@ private: std::string WorkingDirectory; bool EscapeAllowMakeVars; bool EscapeOldStyle; + cmListFileBacktrace* Backtrace; ImplicitDependsList ImplicitDepends; }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 15abd02..f558509 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1893,7 +1893,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( std::vector no_outputs; std::vector 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 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 6d43dc4..a044363 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -53,7 +53,7 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, std::vector 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 56e0ed9..3bce01c 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 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& outputs, if(file) { cmCustomCommand* cc = - new cmCustomCommand(outputs, depends2, commandLines, + new cmCustomCommand(this, outputs, depends2, commandLines, comment, workingDir); cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); -- cgit v0.12 From 4091bca4ecf4a7f9c2099a7d34e125494de60e1c Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 6 Dec 2010 17:11:36 -0500 Subject: Factor generator expression docs out of add_test This documentation may be reused wherever generator expressions are supported. --- Source/CMakeLists.txt | 1 + Source/cmAddTestCommand.h | 15 ++------------- Source/cmDocumentGeneratorExpressions.h | 30 ++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 Source/cmDocumentGeneratorExpressions.h 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/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 name\n" - " $ = main file (.exe, .so.1.2, .a)\n" - " $ = file used to link (.a, .lib, .so)\n" - " $ = 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" - " $/$\n" - " $/$\n" - " $/$\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS "Example usage:\n" " add_test(NAME mytest\n" " COMMAND testDriver --config $\n" 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 name\n" \ + " $ = main file (.exe, .so.1.2, .a)\n" \ + " $ = file used to link (.a, .lib, .so)\n" \ + " $ = 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" \ + " $/$\n" \ + " $/$\n" \ + " $/$\n" + +#endif -- cgit v0.12 From 45e1953c4037d4492668651ae3bbfd6a4a875bc1 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 17:36:24 -0500 Subject: Factor per-config sample targets out of 'Testing' test Put the source files, build rules, and test scripts for these targets under Tests/PerConfig and refer to it from Tests/Testing as a subdirectory. The targets and scripts will be useful in other tests. --- Tests/PerConfig/CMakeLists.txt | 33 +++++++++++++++++++++++++++++++++ Tests/PerConfig/pcShared.c | 5 +++++ Tests/PerConfig/pcShared.h | 16 ++++++++++++++++ Tests/PerConfig/pcStatic.c | 4 ++++ Tests/PerConfig/perconfig.c | 8 ++++++++ Tests/PerConfig/perconfig.cmake | 40 ++++++++++++++++++++++++++++++++++++++++ Tests/Testing/CMakeLists.txt | 34 +++------------------------------- Tests/Testing/driver.cmake | 40 ---------------------------------------- Tests/Testing/pcShared.c | 5 ----- Tests/Testing/pcShared.h | 16 ---------------- Tests/Testing/pcStatic.c | 4 ---- Tests/Testing/perconfig.c | 8 -------- 12 files changed, 109 insertions(+), 104 deletions(-) create mode 100644 Tests/PerConfig/CMakeLists.txt create mode 100644 Tests/PerConfig/pcShared.c create mode 100644 Tests/PerConfig/pcShared.h create mode 100644 Tests/PerConfig/pcStatic.c create mode 100644 Tests/PerConfig/perconfig.c create mode 100644 Tests/PerConfig/perconfig.cmake delete mode 100644 Tests/Testing/driver.cmake delete mode 100644 Tests/Testing/pcShared.c delete mode 100644 Tests/Testing/pcShared.h delete mode 100644 Tests/Testing/pcStatic.c delete mode 100644 Tests/Testing/perconfig.c diff --git a/Tests/PerConfig/CMakeLists.txt b/Tests/PerConfig/CMakeLists.txt new file mode 100644 index 0000000..a45abc8 --- /dev/null +++ b/Tests/PerConfig/CMakeLists.txt @@ -0,0 +1,33 @@ +project(PerConfig C) + +# Targets with per-configuration names. +ADD_LIBRARY(pcStatic STATIC pcStatic.c) +SET_PROPERTY(TARGET pcStatic PROPERTY RELEASE_POSTFIX -opt) +SET_PROPERTY(TARGET pcStatic PROPERTY DEBUG_POSTFIX -dbg) +ADD_LIBRARY(pcShared SHARED pcShared.c) +SET_PROPERTY(TARGET pcShared PROPERTY RELEASE_POSTFIX -opt) +SET_PROPERTY(TARGET pcShared PROPERTY DEBUG_POSTFIX -dbg) +SET_PROPERTY(TARGET pcShared PROPERTY VERSION 1.2) +SET_PROPERTY(TARGET pcShared PROPERTY SOVERSION 3) +IF(NOT WIN32) + SET(soname_file -DpcShared_soname_file=$) +ENDIF() +ADD_EXECUTABLE(perconfig perconfig.c) +TARGET_LINK_LIBRARIES(perconfig pcStatic pcShared) +SET_PROPERTY(TARGET perconfig PROPERTY RELEASE_POSTFIX -opt) +SET_PROPERTY(TARGET perconfig PROPERTY DEBUG_POSTFIX -dbg) + +SET(PerConfig_COMMAND + ${CMAKE_COMMAND} + -Dconfiguration=$ + -Dperconfig_file_dir=$ + -Dperconfig_file_name=$ + -Dperconfig_file=$ + -DpcStatic_file=$ + -DpcStatic_linker_file=$ + -DpcShared_file=$ + -DpcShared_linker_file=$ + ${soname_file} + -P ${PerConfig_SOURCE_DIR}/perconfig.cmake + ) +SET(PerConfig_COMMAND "${PerConfig_COMMAND}" PARENT_SCOPE) diff --git a/Tests/PerConfig/pcShared.c b/Tests/PerConfig/pcShared.c new file mode 100644 index 0000000..b08fadc --- /dev/null +++ b/Tests/PerConfig/pcShared.c @@ -0,0 +1,5 @@ +#include "pcShared.h" +const char* pcShared(void) +{ + return "INFO:symbol[pcShared]"; +} diff --git a/Tests/PerConfig/pcShared.h b/Tests/PerConfig/pcShared.h new file mode 100644 index 0000000..59a6ef4 --- /dev/null +++ b/Tests/PerConfig/pcShared.h @@ -0,0 +1,16 @@ +#ifndef pcShared_h +#define pcShared_h + +#ifdef _WIN32 +# ifdef pcShared_EXPORTS +# define PC_EXPORT __declspec(dllexport) +# else +# define PC_EXPORT __declspec(dllimport) +# endif +#else +# define PC_EXPORT +#endif + +PC_EXPORT const char* pcShared(void); + +#endif diff --git a/Tests/PerConfig/pcStatic.c b/Tests/PerConfig/pcStatic.c new file mode 100644 index 0000000..7e1bf51 --- /dev/null +++ b/Tests/PerConfig/pcStatic.c @@ -0,0 +1,4 @@ +const char* pcStatic(void) +{ + return "INFO:symbol[pcStatic]"; +} diff --git a/Tests/PerConfig/perconfig.c b/Tests/PerConfig/perconfig.c new file mode 100644 index 0000000..d942d45 --- /dev/null +++ b/Tests/PerConfig/perconfig.c @@ -0,0 +1,8 @@ +#include "pcShared.h" +extern const char* pcStatic(void); +int main() +{ + pcStatic(); + pcShared(); + return 0; +} diff --git a/Tests/PerConfig/perconfig.cmake b/Tests/PerConfig/perconfig.cmake new file mode 100644 index 0000000..4a93acc --- /dev/null +++ b/Tests/PerConfig/perconfig.cmake @@ -0,0 +1,40 @@ +# Print values for human reference. +foreach(v + configuration + perconfig_file_dir + perconfig_file_name + perconfig_file + pcStatic_file + pcStatic_linker_file + pcShared_file + pcShared_linker_file + pcShared_soname_file + ) + message("${v}=${${v}}") +endforeach() + +# Verify that file names match as expected. +set(pc_file_components ${perconfig_file_dir}/${perconfig_file_name}) +if(NOT "${pc_file_components}" STREQUAL "${perconfig_file}") + message(SEND_ERROR + "File components ${pc_file_components} do not match ${perconfig_file}") +endif() +if(NOT "${pcStatic_file}" STREQUAL "${pcStatic_linker_file}") + message(SEND_ERROR + "pcStatic_file does not match pcStatic_linker_file:\n" + " ${pcStatic_file}\n" + " ${pcStatic_linker_file}\n" + ) +endif() + +# Verify that the implementation files are named correctly. +foreach(lib pcStatic pcShared) + file(STRINGS "${${lib}_file}" info LIMIT_COUNT 1 REGEX "INFO:[^[]*\\[") + if(NOT "${info}" MATCHES ".*INFO:symbol\\[${lib}\\].*") + message(SEND_ERROR "No INFO:symbol[${lib}] found in:\n ${${lib}_file}") + endif() +endforeach() +execute_process(COMMAND ${perconfig_file} RESULT_VARIABLE result) +if(result) + message(SEND_ERROR "Error running:\n ${perconfig_file}\n(${result})") +endif() diff --git a/Tests/Testing/CMakeLists.txt b/Tests/Testing/CMakeLists.txt index f857407..815b52b 100644 --- a/Tests/Testing/CMakeLists.txt +++ b/Tests/Testing/CMakeLists.txt @@ -53,35 +53,7 @@ ADD_TEST(testing.1 ${Testing_BINARY_DIR}/bin/testing) # ADD_SUBDIRECTORY(Sub/Sub2) -# Per-config target name test. -ADD_LIBRARY(pcStatic STATIC pcStatic.c) -SET_PROPERTY(TARGET pcStatic PROPERTY RELEASE_POSTFIX -opt) -SET_PROPERTY(TARGET pcStatic PROPERTY DEBUG_POSTFIX -dbg) -ADD_LIBRARY(pcShared SHARED pcShared.c) -SET_PROPERTY(TARGET pcShared PROPERTY RELEASE_POSTFIX -opt) -SET_PROPERTY(TARGET pcShared PROPERTY DEBUG_POSTFIX -dbg) -SET_PROPERTY(TARGET pcShared PROPERTY VERSION 1.2) -SET_PROPERTY(TARGET pcShared PROPERTY SOVERSION 3) -IF(NOT WIN32) - SET(soname_file -DpcShared_soname_file=$) -ENDIF() -ADD_EXECUTABLE(perconfig perconfig.c) -TARGET_LINK_LIBRARIES(perconfig pcStatic pcShared) -SET_PROPERTY(TARGET perconfig PROPERTY RELEASE_POSTFIX -opt) -SET_PROPERTY(TARGET perconfig PROPERTY DEBUG_POSTFIX -dbg) +# Per-config target name and generator expressions. +ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig) ADD_TEST(NAME testing.perconfig COMMAND perconfig) - -# Test using a driver script with generator expressions. -ADD_TEST(NAME testing.driver - COMMAND ${CMAKE_COMMAND} - -Dconfiguration=$ - -Dperconfig_file_dir=$ - -Dperconfig_file_name=$ - -Dperconfig_file=$ - -DpcStatic_file=$ - -DpcStatic_linker_file=$ - -DpcShared_file=$ - -DpcShared_linker_file=$ - ${soname_file} - -P ${Testing_SOURCE_DIR}/driver.cmake - ) +ADD_TEST(NAME testing.driver COMMAND ${PerConfig_COMMAND}) diff --git a/Tests/Testing/driver.cmake b/Tests/Testing/driver.cmake deleted file mode 100644 index 4a93acc..0000000 --- a/Tests/Testing/driver.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# Print values for human reference. -foreach(v - configuration - perconfig_file_dir - perconfig_file_name - perconfig_file - pcStatic_file - pcStatic_linker_file - pcShared_file - pcShared_linker_file - pcShared_soname_file - ) - message("${v}=${${v}}") -endforeach() - -# Verify that file names match as expected. -set(pc_file_components ${perconfig_file_dir}/${perconfig_file_name}) -if(NOT "${pc_file_components}" STREQUAL "${perconfig_file}") - message(SEND_ERROR - "File components ${pc_file_components} do not match ${perconfig_file}") -endif() -if(NOT "${pcStatic_file}" STREQUAL "${pcStatic_linker_file}") - message(SEND_ERROR - "pcStatic_file does not match pcStatic_linker_file:\n" - " ${pcStatic_file}\n" - " ${pcStatic_linker_file}\n" - ) -endif() - -# Verify that the implementation files are named correctly. -foreach(lib pcStatic pcShared) - file(STRINGS "${${lib}_file}" info LIMIT_COUNT 1 REGEX "INFO:[^[]*\\[") - if(NOT "${info}" MATCHES ".*INFO:symbol\\[${lib}\\].*") - message(SEND_ERROR "No INFO:symbol[${lib}] found in:\n ${${lib}_file}") - endif() -endforeach() -execute_process(COMMAND ${perconfig_file} RESULT_VARIABLE result) -if(result) - message(SEND_ERROR "Error running:\n ${perconfig_file}\n(${result})") -endif() diff --git a/Tests/Testing/pcShared.c b/Tests/Testing/pcShared.c deleted file mode 100644 index b08fadc..0000000 --- a/Tests/Testing/pcShared.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "pcShared.h" -const char* pcShared(void) -{ - return "INFO:symbol[pcShared]"; -} diff --git a/Tests/Testing/pcShared.h b/Tests/Testing/pcShared.h deleted file mode 100644 index 59a6ef4..0000000 --- a/Tests/Testing/pcShared.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef pcShared_h -#define pcShared_h - -#ifdef _WIN32 -# ifdef pcShared_EXPORTS -# define PC_EXPORT __declspec(dllexport) -# else -# define PC_EXPORT __declspec(dllimport) -# endif -#else -# define PC_EXPORT -#endif - -PC_EXPORT const char* pcShared(void); - -#endif diff --git a/Tests/Testing/pcStatic.c b/Tests/Testing/pcStatic.c deleted file mode 100644 index 7e1bf51..0000000 --- a/Tests/Testing/pcStatic.c +++ /dev/null @@ -1,4 +0,0 @@ -const char* pcStatic(void) -{ - return "INFO:symbol[pcStatic]"; -} diff --git a/Tests/Testing/perconfig.c b/Tests/Testing/perconfig.c deleted file mode 100644 index d942d45..0000000 --- a/Tests/Testing/perconfig.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "pcShared.h" -extern const char* pcStatic(void); -int main() -{ - pcStatic(); - pcShared(); - return 0; -} -- cgit v0.12 From ef9e9de0b80a08bb9290fce3816ff621d2ff3419 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 13:32:09 -0500 Subject: Optionally suppress errors in cmGeneratorExpression --- Source/cmGeneratorExpression.cxx | 7 ++++--- Source/cmGeneratorExpression.h | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index a61880f..971cad2 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("^\\$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; } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index aa36055..9bed780 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -32,7 +32,8 @@ 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); @@ -41,6 +42,7 @@ private: cmMakefile* Makefile; const char* Config; cmListFileBacktrace const& Backtrace; + bool Quiet; std::vector Data; std::stack Barriers; cmsys::RegularExpression TargetInfo; -- cgit v0.12 From 4749e4cb76cc1e23cb23f37ceec2e856a18218ce Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 13:34:05 -0500 Subject: Record set of targets used in cmGeneratorExpression --- Source/cmGeneratorExpression.cxx | 1 + Source/cmGeneratorExpression.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 971cad2..8710dfc 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -141,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 9bed780..1a9d4c6 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -15,6 +15,7 @@ #include +class cmTarget; class cmMakefile; class cmListFileBacktrace; @@ -38,6 +39,10 @@ public: /** 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 const& GetTargets() const + { return this->Targets; } private: cmMakefile* Makefile; const char* Config; @@ -46,6 +51,7 @@ private: std::vector Data; std::stack Barriers; cmsys::RegularExpression TargetInfo; + std::set Targets; bool Evaluate(); bool Evaluate(const char* expr, std::string& result); bool EvaluateTargetInfo(std::string& result); -- cgit v0.12 From f0cdb6001b3e915fc0d9c1120165d49725440bbd Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 16:13:07 -0500 Subject: Introduce "generator expression" syntax to custom commands (#11209) Evaluate in the COMMAND arguments of custom commands the generator expression syntax introduced in commit d2e1f2b4 (Introduce "generator expressions" to add_test, 2009-08-11). These expressions have a syntax like $ and are evaluated during build system generation. This syntax allows per-configuration target output files to be referenced in custom command lines. --- Source/cmAddCustomCommandCommand.h | 12 ++++++++++-- Source/cmCustomCommandGenerator.cxx | 14 +++++++++++--- Source/cmCustomCommandGenerator.h | 3 +++ Source/cmTarget.cxx | 17 +++++++++++++++++ Tests/CustomCommand/CMakeLists.txt | 12 ++++++++++++ Tests/PerConfig/CMakeLists.txt | 1 + Tests/PerConfig/perconfig.cmake | 2 +- 7 files changed, 55 insertions(+), 6 deletions(-) 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/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(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/cmTarget.cxx b/Source/cmTarget.cxx index c82c11e..40f68e4 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 #include #include @@ -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 targets = ge.GetTargets(); + for(std::set::iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + this->Target->AddUtility((*ti)->GetName()); } // Queue the custom command dependencies. diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 746c9a7..450323e 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -423,3 +423,15 @@ ADD_CUSTOM_TARGET(DifferentName ALL ) # # + +# Per-config target name and generator expressions. +ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig) +ADD_CUSTOM_COMMAND( + OUTPUT perconfig.out + COMMAND ${PerConfig_COMMAND} + DEPENDS ${PerConfig_DEPENDS} + VERBATIM + ) +ADD_CUSTOM_TARGET(perconfig_target ALL + COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$" "config=$" + DEPENDS perconfig.out) diff --git a/Tests/PerConfig/CMakeLists.txt b/Tests/PerConfig/CMakeLists.txt index a45abc8..7b7bf2e 100644 --- a/Tests/PerConfig/CMakeLists.txt +++ b/Tests/PerConfig/CMakeLists.txt @@ -31,3 +31,4 @@ SET(PerConfig_COMMAND -P ${PerConfig_SOURCE_DIR}/perconfig.cmake ) SET(PerConfig_COMMAND "${PerConfig_COMMAND}" PARENT_SCOPE) +SET(PerConfig_DEPENDS ${PerConfig_SOURCE_DIR}/perconfig.cmake perconfig pcStatic pcShared) diff --git a/Tests/PerConfig/perconfig.cmake b/Tests/PerConfig/perconfig.cmake index 4a93acc..6a710ca 100644 --- a/Tests/PerConfig/perconfig.cmake +++ b/Tests/PerConfig/perconfig.cmake @@ -10,7 +10,7 @@ foreach(v pcShared_linker_file pcShared_soname_file ) - message("${v}=${${v}}") + message(STATUS "${v}=${${v}}") endforeach() # Verify that file names match as expected. -- cgit v0.12 From 4499d50ad2df7c1db4335d40f9fa20c642f59a5d Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 20 Dec 2010 12:09:23 -0500 Subject: Mark CustomCommand test perconfig.out as SYMBOLIC The custom command with this output does not actually create the file, so mark it as SYMBOLIC. --- Tests/CustomCommand/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 450323e..6a86a34 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -432,6 +432,7 @@ ADD_CUSTOM_COMMAND( DEPENDS ${PerConfig_DEPENDS} VERBATIM ) +SET_PROPERTY(SOURCE perconfig.out PROPERTY SYMBOLIC 1) ADD_CUSTOM_TARGET(perconfig_target ALL COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$" "config=$" DEPENDS perconfig.out) -- cgit v0.12