cmCreateTestSourceList.cxx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 "cmCreateTestSourceList.h"
  11. #include "cmSourceFile.h"
  12. // cmCreateTestSourceList
  13. bool cmCreateTestSourceList
  14. ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
  15. {
  16. if (args.size() < 3)
  17. {
  18. this->SetError("called with wrong number of arguments.");
  19. return false;
  20. }
  21. std::vector<std::string>::const_iterator i = args.begin();
  22. std::string extraInclude;
  23. std::string function;
  24. std::vector<std::string> tests;
  25. // extract extra include and function ot
  26. for(; i != args.end(); i++)
  27. {
  28. if(*i == "EXTRA_INCLUDE")
  29. {
  30. ++i;
  31. if(i == args.end())
  32. {
  33. this->SetError("incorrect arguments to EXTRA_INCLUDE");
  34. return false;
  35. }
  36. extraInclude = "#include \"";
  37. extraInclude += *i;
  38. extraInclude += "\"\n";
  39. }
  40. else if(*i == "FUNCTION")
  41. {
  42. ++i;
  43. if(i == args.end())
  44. {
  45. this->SetError("incorrect arguments to FUNCTION");
  46. return false;
  47. }
  48. function = *i;
  49. function += "(&ac, &av);\n";
  50. }
  51. else
  52. {
  53. tests.push_back(*i);
  54. }
  55. }
  56. i = tests.begin();
  57. // Name of the source list
  58. const char* sourceList = i->c_str();
  59. ++i;
  60. // Name of the test driver
  61. // make sure they specified an extension
  62. if (cmSystemTools::GetFilenameExtension(*i).size() < 2)
  63. {
  64. this->SetError(
  65. "You must specify a file extension for the test driver file.");
  66. return false;
  67. }
  68. std::string driver = this->Makefile->GetCurrentOutputDirectory();
  69. driver += "/";
  70. driver += *i;
  71. ++i;
  72. std::string configFile =
  73. this->Makefile->GetRequiredDefinition("CMAKE_ROOT");
  74. configFile += "/Templates/TestDriver.cxx.in";
  75. // Create the test driver file
  76. std::vector<std::string>::const_iterator testsBegin = i;
  77. std::vector<std::string> tests_func_name;
  78. // The rest of the arguments consist of a list of test source files.
  79. // Sadly, they can be in directories. Let's find a unique function
  80. // name for the corresponding test, and push it to the tests_func_name
  81. // list.
  82. // For the moment:
  83. // - replace spaces ' ', ':' and '/' with underscores '_'
  84. std::string forwardDeclareCode;
  85. for(i = testsBegin; i != tests.end(); ++i)
  86. {
  87. if(*i == "EXTRA_INCLUDE")
  88. {
  89. break;
  90. }
  91. std::string func_name;
  92. if (cmSystemTools::GetFilenamePath(*i).size() > 0)
  93. {
  94. func_name = cmSystemTools::GetFilenamePath(*i) + "/" +
  95. cmSystemTools::GetFilenameWithoutLastExtension(*i);
  96. }
  97. else
  98. {
  99. func_name = cmSystemTools::GetFilenameWithoutLastExtension(*i);
  100. }
  101. cmSystemTools::ConvertToUnixSlashes(func_name);
  102. cmSystemTools::ReplaceString(func_name, " ", "_");
  103. cmSystemTools::ReplaceString(func_name, "/", "_");
  104. cmSystemTools::ReplaceString(func_name, ":", "_");
  105. tests_func_name.push_back(func_name);
  106. forwardDeclareCode += "int ";
  107. forwardDeclareCode += func_name;
  108. forwardDeclareCode += "(int, char*[]);\n";
  109. }
  110. std::string functionMapCode;
  111. int numTests = 0;
  112. std::vector<std::string>::iterator j;
  113. for(i = testsBegin, j = tests_func_name.begin(); i != tests.end(); ++i, ++j)
  114. {
  115. std::string func_name;
  116. if (cmSystemTools::GetFilenamePath(*i).size() > 0)
  117. {
  118. func_name = cmSystemTools::GetFilenamePath(*i) + "/" +
  119. cmSystemTools::GetFilenameWithoutLastExtension(*i);
  120. }
  121. else
  122. {
  123. func_name = cmSystemTools::GetFilenameWithoutLastExtension(*i);
  124. }
  125. functionMapCode += " {\n"
  126. " \"";
  127. functionMapCode += func_name;
  128. functionMapCode += "\",\n"
  129. " ";
  130. functionMapCode += *j;
  131. functionMapCode += "\n"
  132. " },\n";
  133. numTests++;
  134. }
  135. if(extraInclude.size())
  136. {
  137. this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES",
  138. extraInclude.c_str());
  139. }
  140. if(function.size())
  141. {
  142. this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION",
  143. function.c_str());
  144. }
  145. this->Makefile->AddDefinition("CMAKE_FORWARD_DECLARE_TESTS",
  146. forwardDeclareCode.c_str());
  147. this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES",
  148. functionMapCode.c_str());
  149. bool res = true;
  150. if ( !this->Makefile->ConfigureFile(configFile.c_str(), driver.c_str(),
  151. false, true, false) )
  152. {
  153. res = false;
  154. }
  155. // Construct the source list.
  156. std::string sourceListValue;
  157. {
  158. cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver);
  159. sf->SetProperty("ABSTRACT","0");
  160. sourceListValue = args[1];
  161. }
  162. for(i = testsBegin; i != tests.end(); ++i)
  163. {
  164. cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
  165. sf->SetProperty("ABSTRACT","0");
  166. sourceListValue += ";";
  167. sourceListValue += *i;
  168. }
  169. this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
  170. return res;
  171. }