cmTestGenerator.cxx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmTestGenerator.h"
  11. #include "cmGeneratorExpression.h"
  12. #include "cmLocalGenerator.h"
  13. #include "cmMakefile.h"
  14. #include "cmSystemTools.h"
  15. #include "cmTarget.h"
  16. #include "cmTest.h"
  17. //----------------------------------------------------------------------------
  18. cmTestGenerator
  19. ::cmTestGenerator(cmTest* test,
  20. std::vector<std::string> const& configurations):
  21. cmScriptGenerator("CTEST_CONFIGURATION_TYPE", configurations),
  22. Test(test)
  23. {
  24. this->ActionsPerConfig = !test->GetOldStyle();
  25. this->TestGenerated = false;
  26. }
  27. //----------------------------------------------------------------------------
  28. cmTestGenerator
  29. ::~cmTestGenerator()
  30. {
  31. }
  32. //----------------------------------------------------------------------------
  33. void cmTestGenerator::GenerateScriptConfigs(std::ostream& os,
  34. Indent const& indent)
  35. {
  36. // First create the tests.
  37. this->cmScriptGenerator::GenerateScriptConfigs(os, indent);
  38. // Now generate the test properties.
  39. if(this->TestGenerated)
  40. {
  41. cmTest* test = this->Test;
  42. cmMakefile* mf = test->GetMakefile();
  43. cmLocalGenerator* lg = mf->GetLocalGenerator();
  44. std::ostream& fout = os;
  45. cmPropertyMap::const_iterator pit;
  46. cmPropertyMap* mpit = &test->GetProperties();
  47. if ( mpit->size() )
  48. {
  49. fout << "SET_TESTS_PROPERTIES(" << test->GetName() << " PROPERTIES ";
  50. for ( pit = mpit->begin(); pit != mpit->end(); ++ pit )
  51. {
  52. fout << " " << pit->first
  53. << " " << lg->EscapeForCMake(pit->second.GetValue());
  54. }
  55. fout << ")" << std::endl;
  56. }
  57. }
  58. }
  59. //----------------------------------------------------------------------------
  60. void cmTestGenerator::GenerateScriptActions(std::ostream& os,
  61. Indent const& indent)
  62. {
  63. if(this->ActionsPerConfig)
  64. {
  65. // This is the per-config generation in a single-configuration
  66. // build generator case. The superclass will call our per-config
  67. // method.
  68. this->cmScriptGenerator::GenerateScriptActions(os, indent);
  69. }
  70. else
  71. {
  72. // This is an old-style test, so there is only one config.
  73. //assert(this->Test->GetOldStyle());
  74. this->GenerateOldStyle(os, indent);
  75. }
  76. }
  77. //----------------------------------------------------------------------------
  78. void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
  79. const char* config,
  80. Indent const& indent)
  81. {
  82. this->TestGenerated = true;
  83. // Set up generator expression evaluation context.
  84. cmGeneratorExpression ge(this->Test->GetBacktrace());
  85. // Start the test command.
  86. os << indent << "ADD_TEST(" << this->Test->GetName() << " ";
  87. // Get the test command line to be executed.
  88. std::vector<std::string> const& command = this->Test->GetCommand();
  89. // Check whether the command executable is a target whose name is to
  90. // be translated.
  91. std::string exe = command[0];
  92. cmMakefile* mf = this->Test->GetMakefile();
  93. cmTarget* target = mf->FindTargetToUse(exe.c_str());
  94. if(target && target->GetType() == cmTarget::EXECUTABLE)
  95. {
  96. // Use the target file on disk.
  97. exe = target->GetFullPath(config);
  98. }
  99. else
  100. {
  101. // Use the command name given.
  102. exe = ge.Parse(exe.c_str()).Evaluate(mf, config);
  103. cmSystemTools::ConvertToUnixSlashes(exe);
  104. }
  105. // Generate the command line with full escapes.
  106. cmLocalGenerator* lg = mf->GetLocalGenerator();
  107. os << lg->EscapeForCMake(exe.c_str());
  108. for(std::vector<std::string>::const_iterator ci = command.begin()+1;
  109. ci != command.end(); ++ci)
  110. {
  111. os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config));
  112. }
  113. // Finish the test command.
  114. os << ")\n";
  115. }
  116. //----------------------------------------------------------------------------
  117. void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os,
  118. Indent const& indent)
  119. {
  120. os << indent << "ADD_TEST(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
  121. }
  122. //----------------------------------------------------------------------------
  123. bool cmTestGenerator::NeedsScriptNoConfig() const
  124. {
  125. return (this->TestGenerated && // test generated for at least one config
  126. this->ActionsPerConfig && // test is config-aware
  127. this->Configurations.empty() && // test runs in all configs
  128. !this->ConfigurationTypes->empty()); // config-dependent command
  129. }
  130. //----------------------------------------------------------------------------
  131. void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
  132. Indent const& indent)
  133. {
  134. this->TestGenerated = true;
  135. // Get the test command line to be executed.
  136. std::vector<std::string> const& command = this->Test->GetCommand();
  137. std::string exe = command[0];
  138. cmSystemTools::ConvertToUnixSlashes(exe);
  139. fout << indent;
  140. fout << "ADD_TEST(";
  141. fout << this->Test->GetName() << " \"" << exe << "\"";
  142. for(std::vector<std::string>::const_iterator argit = command.begin()+1;
  143. argit != command.end(); ++argit)
  144. {
  145. // Just double-quote all arguments so they are re-parsed
  146. // correctly by the test system.
  147. fout << " \"";
  148. for(std::string::const_iterator c = argit->begin();
  149. c != argit->end(); ++c)
  150. {
  151. // Escape quotes within arguments. We should escape
  152. // backslashes too but we cannot because it makes the result
  153. // inconsistent with previous behavior of this command.
  154. if((*c == '"'))
  155. {
  156. fout << '\\';
  157. }
  158. fout << *c;
  159. }
  160. fout << "\"";
  161. }
  162. fout << ")" << std::endl;
  163. }