From 77ddb6a0cd35996f1329d727a25de3460f6aa899 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 10 Jun 2011 08:48:20 -0400 Subject: [PATCH 1/2] Use cascading-if for per-config test and install code When generating per-config blocks in test and install scripts replace the form IF() # config == A ENDIF() IF() # config == B ENDIF() with IF() # config == A ELSEIF() # config == B ELSE() # no config matches ENDIF() for clarity and to support the else() case cleanly. --- Source/cmScriptGenerator.cxx | 14 ++++++++++++-- Source/cmScriptGenerator.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx index 86ecebe64..cabe98a51 100644 --- a/Source/cmScriptGenerator.cxx +++ b/Source/cmScriptGenerator.cxx @@ -209,6 +209,7 @@ void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os, // In a multi-configuration generator we produce a separate rule // in a block for each configuration that is built. We restrict // the list of configurations to those to which this rule applies. + bool first = true; for(std::vector::const_iterator i = this->ConfigurationTypes->begin(); i != this->ConfigurationTypes->end(); ++i) @@ -218,10 +219,19 @@ void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os, { // Generate a per-configuration block. std::string config_test = this->CreateConfigTest(config); - os << indent << "IF(" << config_test << ")\n"; + os << indent << (first? "IF(" : "ELSEIF(") << config_test << ")\n"; this->GenerateScriptForConfig(os, config, indent.Next()); - os << indent << "ENDIF(" << config_test << ")\n"; + first = false; } } + if(!first) + { + if(this->NeedsScriptNoConfig()) + { + os << indent << "ELSE()\n"; + this->GenerateScriptNoConfig(os, indent.Next()); + } + os << indent << "ENDIF()\n"; + } } } diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h index e2a0da56d..8b2ca335f 100644 --- a/Source/cmScriptGenerator.h +++ b/Source/cmScriptGenerator.h @@ -65,6 +65,8 @@ protected: virtual void GenerateScriptForConfig(std::ostream& os, const char* config, Indent const& indent); + virtual void GenerateScriptNoConfig(std::ostream&, Indent const&) {} + virtual bool NeedsScriptNoConfig() const { return false; } // Test if this generator does something for a given configuration. bool GeneratesForConfig(const char*); From a4ec24269b32a28104e1d5681e718024b28bb4e7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 10 Jun 2011 09:29:30 -0400 Subject: [PATCH 2/2] CTest: Report tests not run due to unknown configuration When add_test(NAME) is called without the CONFIGURATIONS argument then the test is intended to run in any configuration. In multi-config generators like the VS IDE and Xcode tests created by add_test(NAME) can only be run when testing a known configuration (otherwise there is no way to generate the test command line). If no test command line is known for a particular configuration, or if no configuration is given to ctest, report the test as not run instead of silently skipping it. Also fix CMake's own TestsWorkingDirectory test invocation to correct a previously silent failure exposed by this change. --- Source/CTest/cmCTestRunTest.cxx | 24 ++++++++++++++++++++++++ Source/CTest/cmCTestTestHandler.cxx | 4 ++++ Source/cmTestGenerator.cxx | 16 ++++++++++++++++ Source/cmTestGenerator.h | 2 ++ Tests/CMakeLists.txt | 2 +- 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index b5b46f60b..60695daa1 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -412,6 +412,30 @@ bool cmCTestRunTest::StartTest(size_t total) this->TestResult.TestCount = this->TestProperties->Index; this->TestResult.Name = this->TestProperties->Name; this->TestResult.Path = this->TestProperties->Directory.c_str(); + + if(args.size() >= 2 && args[1] == "NOT_AVAILABLE") + { + this->TestProcess = new cmProcess; + std::string msg; + if(this->CTest->GetConfigType().empty()) + { + msg = "Test not available without configuration."; + msg += " (Missing \"-C \"?)"; + } + else + { + msg = "Test not available in configuration \""; + msg += this->CTest->GetConfigType(); + msg += "\"."; + } + *this->TestHandler->LogFile << msg << std::endl; + cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl); + this->TestResult.Output = msg; + this->TestResult.FullCommandLine = ""; + this->TestResult.CompletionStatus = "Not Run"; + this->TestResult.Status = cmCTestTestHandler::NOT_RUN; + return false; + } // Check if all required files exist for(std::vector::iterator i = diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 56f663009..e3b81df88 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1320,6 +1320,10 @@ std::string cmCTestTestHandler::FindTheExecutable(const char *exe) std::string resConfig; std::vector extraPaths; std::vector failedPaths; + if(strcmp(exe, "NOT_AVAILABLE") == 0) + { + return exe; + } return cmCTestTestHandler::FindExecutable(this->CTest, exe, resConfig, extraPaths, diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 39f86388b..e0892b282 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -129,6 +129,22 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, os << ")\n"; } +//---------------------------------------------------------------------------- +void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, + Indent const& indent) +{ + os << indent << "ADD_TEST(" << this->Test->GetName() << " NOT_AVAILABLE)\n"; +} + +//---------------------------------------------------------------------------- +bool cmTestGenerator::NeedsScriptNoConfig() const +{ + return (this->TestGenerated && // test generated for at least one config + this->ActionsPerConfig && // test is config-aware + this->Configurations.empty() && // test runs in all configs + !this->ConfigurationTypes->empty()); // config-dependent command +} + //---------------------------------------------------------------------------- void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent const& indent) diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h index 85d9091d6..2c69fc3c5 100644 --- a/Source/cmTestGenerator.h +++ b/Source/cmTestGenerator.h @@ -34,6 +34,8 @@ protected: virtual void GenerateScriptForConfig(std::ostream& os, const char* config, Indent const& indent); + virtual void GenerateScriptNoConfig(std::ostream& os, Indent const& indent); + virtual bool NeedsScriptNoConfig() const; void GenerateOldStyle(std::ostream& os, Indent const& indent); cmTest* Test; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 1be2a245e..2ad9a7759 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1310,7 +1310,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory" --force-new-ctest-process - --test-command ${CMAKE_CTEST_COMMAND} -V + --test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE} ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory")