cmGlobalGenerator.cxx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 "cmGlobalGenerator.h"
  14. #include "cmLocalGenerator.h"
  15. #include "cmake.h"
  16. #include "cmMakefile.h"
  17. cmGlobalGenerator::cmGlobalGenerator()
  18. {
  19. }
  20. cmGlobalGenerator::~cmGlobalGenerator()
  21. {
  22. // Delete any existing cmLocalGenerators
  23. unsigned int i;
  24. for (i = 0; i < m_LocalGenerators.size(); ++i)
  25. {
  26. delete m_LocalGenerators[i];
  27. }
  28. m_LocalGenerators.clear();
  29. }
  30. void cmGlobalGenerator::SetLanguageEnabled(const char* l)
  31. {
  32. m_LanguageEnabled[l] = true;
  33. }
  34. bool cmGlobalGenerator::GetLanguageEnabled(const char* l)
  35. {
  36. return (m_LanguageEnabled.count(l) > 0);
  37. }
  38. void cmGlobalGenerator::ClearEnabledLanguages()
  39. {
  40. m_LanguageEnabled.clear();
  41. }
  42. void cmGlobalGenerator::Configure()
  43. {
  44. // Delete any existing cmLocalGenerators
  45. unsigned int i;
  46. for (i = 0; i < m_LocalGenerators.size(); ++i)
  47. {
  48. delete m_LocalGenerators[i];
  49. }
  50. m_LocalGenerators.clear();
  51. // start with this directory
  52. cmLocalGenerator *lg = this->CreateLocalGenerator();
  53. m_LocalGenerators.push_back(lg);
  54. // set the Start directories
  55. lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetStartDirectory());
  56. lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetStartOutputDirectory());
  57. lg->GetMakefile()->MakeStartDirectoriesCurrent();
  58. // now do it
  59. this->RecursiveConfigure(lg,0.0f,0.9f);
  60. // after it is all done do a ConfigureFinalPass
  61. for (i = 0; i < m_LocalGenerators.size(); ++i)
  62. {
  63. m_LocalGenerators[i]->ConfigureFinalPass();
  64. m_CMakeInstance->UpdateProgress("Configuring",
  65. 0.9f+0.1f*(i+1.0f)/m_LocalGenerators.size());
  66. }
  67. m_CMakeInstance->UpdateProgress("Configuring done", -1);
  68. }
  69. // loop through the directories creating cmLocalGenerators and Configure()
  70. void cmGlobalGenerator::RecursiveConfigure(cmLocalGenerator *lg,
  71. float startProgress,
  72. float endProgress)
  73. {
  74. // configure the current directory
  75. lg->Configure();
  76. // get all the subdirectories
  77. std::vector<std::string> subdirs = lg->GetMakefile()->GetSubDirectories();
  78. float progressPiece = (endProgress - startProgress)/(1.0f+subdirs.size());
  79. m_CMakeInstance->UpdateProgress("Configuring",
  80. startProgress + progressPiece);
  81. // for each subdir recurse
  82. unsigned int i;
  83. for (i = 0; i < subdirs.size(); ++i)
  84. {
  85. cmLocalGenerator *lg2 = this->CreateLocalGenerator();
  86. m_LocalGenerators.push_back(lg2);
  87. // add the subdir to the start output directory
  88. std::string outdir = lg->GetMakefile()->GetStartOutputDirectory();
  89. outdir += "/";
  90. outdir += subdirs[i];
  91. lg2->GetMakefile()->SetStartOutputDirectory(outdir.c_str());
  92. // add the subdir to the start source directory
  93. std::string currentDir = lg->GetMakefile()->GetStartDirectory();
  94. currentDir += "/";
  95. currentDir += subdirs[i];
  96. lg2->GetMakefile()->SetStartDirectory(currentDir.c_str());
  97. lg2->GetMakefile()->MakeStartDirectoriesCurrent();
  98. this->RecursiveConfigure(lg2,
  99. startProgress + (i+1.0f)*progressPiece,
  100. startProgress + (i+2.0f)*progressPiece);
  101. }
  102. }
  103. void cmGlobalGenerator::Generate()
  104. {
  105. // For each existing cmLocalGenerator
  106. unsigned int i;
  107. for (i = 0; i < m_LocalGenerators.size(); ++i)
  108. {
  109. m_LocalGenerators[i]->Generate(true);
  110. m_CMakeInstance->UpdateProgress("Generating",
  111. (i+1.0f)/m_LocalGenerators.size());
  112. }
  113. m_CMakeInstance->UpdateProgress("Generating done", -1);
  114. }
  115. void cmGlobalGenerator::LocalGenerate()
  116. {
  117. // for this case we create one LocalGenerator
  118. // configure it, and then Generate it
  119. // start with this directory
  120. cmLocalGenerator *lg = this->CreateLocalGenerator();
  121. // set the Start directories
  122. lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetStartDirectory());
  123. lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetStartOutputDirectory());
  124. lg->GetMakefile()->MakeStartDirectoriesCurrent();
  125. // now do trhe configure
  126. lg->Configure();
  127. lg->ConfigureFinalPass();
  128. lg->Generate(false);
  129. delete lg;
  130. }
  131. int cmGlobalGenerator::TryCompile(const char *, const char *bindir,
  132. const char *, const char *target,
  133. std::string *output)
  134. {
  135. // now build the test
  136. std::string makeCommand =
  137. m_CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_MAKE_PROGRAM");
  138. if(makeCommand.size() == 0)
  139. {
  140. cmSystemTools::Error(
  141. "Generator cannot find the appropriate make command.");
  142. return 1;
  143. }
  144. makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str());
  145. /**
  146. * Run an executable command and put the stdout in output.
  147. */
  148. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  149. cmSystemTools::ChangeDirectory(bindir);
  150. // Since we have full control over the invocation of nmake, let us
  151. // make it quiet.
  152. if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
  153. {
  154. makeCommand += " /NOLOGO ";
  155. }
  156. // now build
  157. if (target)
  158. {
  159. makeCommand += " ";
  160. makeCommand += target;
  161. #if defined(_WIN32) || defined(__CYGWIN__)
  162. makeCommand += ".exe";
  163. #endif // WIN32
  164. }
  165. else
  166. {
  167. makeCommand += " all";
  168. }
  169. int retVal;
  170. if (!cmSystemTools::RunCommand(makeCommand.c_str(), *output, retVal, 0, false))
  171. {
  172. cmSystemTools::Error("Generator: execution of make failed.");
  173. // return to the original directory
  174. cmSystemTools::ChangeDirectory(cwd.c_str());
  175. return 1;
  176. }
  177. cmSystemTools::ChangeDirectory(cwd.c_str());
  178. return retVal;
  179. }
  180. cmLocalGenerator *cmGlobalGenerator::CreateLocalGenerator()
  181. {
  182. cmLocalGenerator *lg = new cmLocalGenerator;
  183. lg->SetGlobalGenerator(this);
  184. return lg;
  185. }
  186. void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
  187. cmMakefile *)
  188. {
  189. // create a temp generator
  190. cmLocalGenerator *lg = this->CreateLocalGenerator();
  191. lg->GetMakefile()->SetStartDirectory(m_CMakeInstance->GetStartDirectory());
  192. lg->GetMakefile()->SetStartOutputDirectory(m_CMakeInstance->GetStartOutputDirectory());
  193. lg->GetMakefile()->MakeStartDirectoriesCurrent();
  194. // for each existing language call enable Language
  195. std::map<cmStdString, bool>::const_iterator i =
  196. gen->m_LanguageEnabled.begin();
  197. for (;i != gen->m_LanguageEnabled.end(); ++i)
  198. {
  199. this->EnableLanguage(i->first.c_str(),lg->GetMakefile());
  200. }
  201. delete lg;
  202. }