cmCreateTestSourceList.cxx 5.4 KB

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