cmGlobalUnixMakefileGenerator3.cxx 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator3
  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 "cmGlobalUnixMakefileGenerator3.h"
  14. #include "cmLocalUnixMakefileGenerator3.h"
  15. #include "cmMakefile.h"
  16. #include "cmake.h"
  17. #include "cmGeneratedFileStream.h"
  18. cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
  19. {
  20. // This type of makefile always requires unix style paths
  21. m_ForceUnixPaths = true;
  22. m_FindMakeProgramFile = "CMakeUnixFindMake.cmake";
  23. }
  24. void cmGlobalUnixMakefileGenerator3
  25. ::EnableLanguage(std::vector<std::string>const& languages, cmMakefile *mf)
  26. {
  27. mf->AddDefinition("CMAKE_CFG_INTDIR",".");
  28. this->cmGlobalGenerator::EnableLanguage(languages, mf);
  29. std::string path;
  30. for(std::vector<std::string>::const_iterator l = languages.begin();
  31. l != languages.end(); ++l)
  32. {
  33. const char* lang = l->c_str();
  34. std::string langComp = "CMAKE_";
  35. langComp += lang;
  36. langComp += "_COMPILER";
  37. if(!mf->GetDefinition(langComp.c_str()))
  38. {
  39. cmSystemTools::Error(langComp.c_str(), " not set, after EnableLanguage");
  40. continue;
  41. }
  42. const char* cc = mf->GetRequiredDefinition(langComp.c_str());
  43. path = cmSystemTools::FindProgram(cc);
  44. if(path.size() == 0)
  45. {
  46. std::string message = "your ";
  47. message += lang;
  48. message += " compiler: ";
  49. if(cc)
  50. {
  51. message += cc;
  52. }
  53. else
  54. {
  55. message += "(NULL)";
  56. }
  57. message += " was not found in your path. "
  58. "For CMake to correctly use try compile commands, the compiler must "
  59. "be in your path. Please add the compiler to your PATH environment,"
  60. " and re-run CMake.";
  61. cmSystemTools::Error(message.c_str());
  62. }
  63. }
  64. }
  65. ///! Create a local generator appropriate to this Global Generator
  66. cmLocalGenerator *cmGlobalUnixMakefileGenerator3::CreateLocalGenerator()
  67. {
  68. cmLocalGenerator* lg = new cmLocalUnixMakefileGenerator3;
  69. lg->SetGlobalGenerator(this);
  70. return lg;
  71. }
  72. //----------------------------------------------------------------------------
  73. void cmGlobalUnixMakefileGenerator3::GetDocumentation(cmDocumentationEntry& entry) const
  74. {
  75. entry.name = this->GetName();
  76. entry.brief = "Generates standard UNIX makefiles.";
  77. entry.full =
  78. "A hierarchy of UNIX makefiles is generated into the build tree. Any "
  79. "standard UNIX-style make program can build the project through the "
  80. "default make target. A \"make install\" target is also provided.";
  81. }
  82. //----------------------------------------------------------------------------
  83. void cmGlobalUnixMakefileGenerator3::Generate()
  84. {
  85. // first do superclass method
  86. this->cmGlobalGenerator::Generate();
  87. // write the main makefile
  88. this->WriteMainMakefile();
  89. this->WriteMainMakefile2();
  90. this->WriteMainCMakefile();
  91. }
  92. void cmGlobalUnixMakefileGenerator3::WriteMainMakefile()
  93. {
  94. // Open the output file. This should not be copy-if-different
  95. // because the check-build-system step compares the makefile time to
  96. // see if the build system must be regenerated.
  97. std::string makefileName =
  98. this->GetCMakeInstance()->GetHomeOutputDirectory();
  99. makefileName += "/Makefile";
  100. cmGeneratedFileStream makefileStream(makefileName.c_str());
  101. if(!makefileStream)
  102. {
  103. return;
  104. }
  105. // get a local generator for some useful methods
  106. cmLocalUnixMakefileGenerator3 *lg =
  107. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  108. // Write the do not edit header.
  109. lg->WriteDisclaimer(makefileStream);
  110. // Write the main entry point target. This must be the VERY first
  111. // target so that make with no arguments will run it.
  112. // Just depend on the all target to drive the build.
  113. std::vector<std::string> depends;
  114. std::vector<std::string> no_commands;
  115. depends.push_back("all");
  116. // Write the rule.
  117. lg->WriteMakeRule(makefileStream,
  118. "Default target executed when no arguments are "
  119. "given to make.",
  120. "default_target",
  121. depends,
  122. no_commands);
  123. lg->WriteMakeVariables(makefileStream, cmLocalGenerator::HOME_OUTPUT);
  124. lg->WriteSpecialTargetsTop(makefileStream);
  125. this->WriteAllRules(lg,makefileStream);
  126. // Keep track of targets already listed.
  127. std::set<cmStdString> emittedTargets;
  128. // write the target convenience rules
  129. unsigned int i;
  130. for (i = 0; i < m_LocalGenerators.size(); ++i)
  131. {
  132. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  133. this->WriteConvenienceRules(makefileStream,lg,emittedTargets);
  134. }
  135. // add a help target as long as there isn;t a real target named help
  136. if(emittedTargets.insert("help").second)
  137. {
  138. this->WriteHelpRule(makefileStream);
  139. }
  140. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  141. lg->WriteSpecialTargetsBottom(makefileStream);
  142. }
  143. void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
  144. {
  145. // Open the output file. This should not be copy-if-different
  146. // because the check-build-system step compares the makefile time to
  147. // see if the build system must be regenerated.
  148. std::string makefileName =
  149. this->GetCMakeInstance()->GetHomeOutputDirectory();
  150. makefileName += "/CMakeFiles/Makefile2";
  151. cmGeneratedFileStream makefileStream(makefileName.c_str());
  152. if(!makefileStream)
  153. {
  154. return;
  155. }
  156. // get a local generator for some useful methods
  157. cmLocalUnixMakefileGenerator3 *lg =
  158. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  159. // Write the do not edit header.
  160. lg->WriteDisclaimer(makefileStream);
  161. // Write the main entry point target. This must be the VERY first
  162. // target so that make with no arguments will run it.
  163. // Just depend on the all target to drive the build.
  164. std::vector<std::string> depends;
  165. std::vector<std::string> no_commands;
  166. depends.push_back("all");
  167. // Write the rule.
  168. lg->WriteMakeRule(makefileStream,
  169. "Default target executed when no arguments are "
  170. "given to make.",
  171. "default_target",
  172. depends,
  173. no_commands);
  174. // Write and empty all:
  175. lg->WriteMakeRule(makefileStream,
  176. "The main recursive all target", "all",
  177. no_commands, no_commands);
  178. lg->WriteMakeVariables(makefileStream,cmLocalGenerator::HOME_OUTPUT);
  179. // write the target convenience rules
  180. unsigned int i;
  181. for (i = 0; i < m_LocalGenerators.size(); ++i)
  182. {
  183. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  184. // are any parents excluded
  185. bool exclude = false;
  186. cmLocalGenerator *lg3 = lg;
  187. while (lg3)
  188. {
  189. if (lg3->GetExcludeAll())
  190. {
  191. exclude = true;
  192. break;
  193. }
  194. lg3 = lg3->GetParent();
  195. }
  196. this->WriteConvenienceRules2(makefileStream,lg,exclude);
  197. }
  198. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  199. lg->WriteSpecialTargetsBottom(makefileStream);
  200. }
  201. //----------------------------------------------------------------------------
  202. void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
  203. {
  204. // Open the output file. This should not be copy-if-different
  205. // because the check-build-system step compares the makefile time to
  206. // see if the build system must be regenerated.
  207. std::string cmakefileName =
  208. this->GetCMakeInstance()->GetHomeOutputDirectory();
  209. cmakefileName += "/CMakeFiles/Makefile.cmake";
  210. cmGeneratedFileStream cmakefileStream(cmakefileName.c_str());
  211. if(!cmakefileStream)
  212. {
  213. return;
  214. }
  215. std::string makefileName =
  216. this->GetCMakeInstance()->GetHomeOutputDirectory();
  217. makefileName += "/Makefile";
  218. // get a local generator for some useful methods
  219. cmLocalUnixMakefileGenerator3 *lg =
  220. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  221. // Write the do not edit header.
  222. lg->WriteDisclaimer(cmakefileStream);
  223. // Save the generator name
  224. cmakefileStream
  225. << "# The generator used is:\n"
  226. << "SET(CMAKE_DEPENDS_GENERATOR \"" << this->GetName() << "\")\n\n";
  227. // for each cmMakefile get its list of dependencies
  228. std::vector<std::string> lfiles;
  229. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  230. {
  231. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  232. // Get the list of files contributing to this generation step.
  233. lfiles.insert(lfiles.end(),lg->GetMakefile()->GetListFiles().begin(),
  234. lg->GetMakefile()->GetListFiles().end());
  235. }
  236. // Sort the list and remove duplicates.
  237. std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
  238. std::vector<std::string>::iterator new_end =
  239. std::unique(lfiles.begin(),lfiles.end());
  240. lfiles.erase(new_end, lfiles.end());
  241. // reset lg to the first makefile
  242. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  243. // Build the path to the cache file.
  244. std::string cache = this->GetCMakeInstance()->GetHomeOutputDirectory();
  245. cache += "/CMakeCache.txt";
  246. // Save the list to the cmake file.
  247. cmakefileStream
  248. << "# The top level Makefile was generated from the following files:\n"
  249. << "SET(CMAKE_MAKEFILE_DEPENDS\n"
  250. << " \"" << lg->Convert(cache.c_str(),
  251. cmLocalGenerator::START_OUTPUT).c_str() << "\"\n";
  252. for(std::vector<std::string>::const_iterator i = lfiles.begin();
  253. i != lfiles.end(); ++i)
  254. {
  255. cmakefileStream
  256. << " \"" << lg->Convert(i->c_str(),
  257. cmLocalGenerator::START_OUTPUT).c_str()
  258. << "\"\n";
  259. }
  260. cmakefileStream
  261. << " )\n\n";
  262. // Build the path to the cache check file.
  263. std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory();
  264. check += "/CMakeFiles/cmake.check_cache";
  265. // Set the corresponding makefile in the cmake file.
  266. cmakefileStream
  267. << "# The corresponding makefile is:\n"
  268. << "SET(CMAKE_MAKEFILE_OUTPUTS\n"
  269. << " \"" << lg->Convert(makefileName.c_str(),
  270. cmLocalGenerator::START_OUTPUT).c_str() << "\"\n"
  271. << " \"" << lg->Convert(check.c_str(),
  272. cmLocalGenerator::START_OUTPUT).c_str() << "\"\n";
  273. // add in all the directory information files
  274. std::string tmpStr;
  275. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  276. {
  277. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  278. tmpStr = lg->GetMakefile()->GetStartOutputDirectory();
  279. tmpStr += "/CMakeFiles/CMakeDirectoryInformation.cmake";
  280. cmakefileStream << " \"" <<
  281. lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() << "\"\n";
  282. }
  283. cmakefileStream << " )\n\n";
  284. this->WriteMainCMakefileLanguageRules(cmakefileStream, m_LocalGenerators);
  285. }
  286. void cmGlobalUnixMakefileGenerator3
  287. ::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
  288. std::vector<cmLocalGenerator *> &lGenerators)
  289. {
  290. cmLocalUnixMakefileGenerator3 *lg;
  291. // now list all the target info files
  292. cmakefileStream
  293. << "# The set of files whose dependency integrity should be checked:\n";
  294. cmakefileStream
  295. << "SET(CMAKE_DEPEND_INFO_FILES\n";
  296. for (unsigned int i = 0; i < lGenerators.size(); ++i)
  297. {
  298. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(lGenerators[i]);
  299. // for all of out targets
  300. for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
  301. l != lg->GetMakefile()->GetTargets().end(); l++)
  302. {
  303. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  304. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  305. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  306. (l->second.GetType() == cmTarget::MODULE_LIBRARY) )
  307. {
  308. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  309. tname += "/DependInfo.cmake";
  310. cmSystemTools::ConvertToUnixSlashes(tname);
  311. cmakefileStream << " \"" << tname.c_str() << "\"\n";
  312. }
  313. }
  314. }
  315. cmakefileStream << " )\n";
  316. }
  317. //----------------------------------------------------------------------------
  318. void cmGlobalUnixMakefileGenerator3
  319. ::WriteAllRules(cmLocalUnixMakefileGenerator3 *lg,
  320. std::ostream& makefileStream)
  321. {
  322. // Write section header.
  323. lg->WriteDivider(makefileStream);
  324. makefileStream
  325. << "# Rules to build dependencies and targets.\n"
  326. << "\n";
  327. std::vector<std::string> depends;
  328. std::vector<std::string> commands;
  329. // Check the build system in this directory.
  330. depends.push_back("cmake_check_build_system");
  331. commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2","all"));
  332. // Write the rule.
  333. lg->WriteMakeRule(makefileStream, "The main all target", "all", depends, commands);
  334. // write the clean
  335. depends.clear();
  336. commands.clear();
  337. commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2","clean"));
  338. lg->WriteMakeRule(makefileStream, "The main clean target", "clean",
  339. depends, commands);
  340. // write the depend rule, really a recompute depends rule
  341. depends.clear();
  342. commands.clear();
  343. std::string cmakefileName = "CMakeFiles/Makefile.cmake";
  344. std::string runRule =
  345. "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
  346. runRule += " --check-build-system ";
  347. runRule += lg->Convert(cmakefileName.c_str(),cmLocalGenerator::NONE,
  348. cmLocalGenerator::SHELL);
  349. runRule += " 1";
  350. commands.push_back(runRule);
  351. lg->WriteMakeRule(makefileStream, "clear depends",
  352. "depend",
  353. depends, commands);
  354. }
  355. //----------------------------------------------------------------------------
  356. void
  357. cmGlobalUnixMakefileGenerator3
  358. ::WriteDirectoryRules(std::ostream& ruleFileStream,
  359. cmLocalUnixMakefileGenerator3 *lg)
  360. {
  361. std::vector<std::string> depends;
  362. std::vector<std::string> commands;
  363. std::string localName;
  364. std::string makeTargetName;
  365. depends.push_back("cmake_check_build_system");
  366. if (lg->GetParent())
  367. {
  368. std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
  369. dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
  370. lg->WriteDivider(ruleFileStream);
  371. ruleFileStream
  372. << "# Directory level rules for directory "
  373. << dir << "\n\n";
  374. localName = dir;
  375. localName += "/directorystart";
  376. makeTargetName = dir;
  377. makeTargetName += "/directory";
  378. std::vector<std::string> all_tgts;
  379. // for all of out targets
  380. for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
  381. l != lg->GetMakefile()->GetTargets().end(); l++)
  382. {
  383. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  384. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  385. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  386. (l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  387. (l->second.GetType() == cmTarget::UTILITY))
  388. {
  389. // Add this to the list of depends rules in this directory.
  390. if(l->second.IsInAll())
  391. {
  392. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  393. tname += "/all";
  394. all_tgts.push_back(tname);
  395. }
  396. }
  397. }
  398. // write the directory rule add in the subdirs
  399. std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
  400. // for each subdir add the directory depend
  401. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  402. for (; sdi != subdirs.end(); ++sdi)
  403. {
  404. cmLocalUnixMakefileGenerator3 * lg2 =
  405. static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
  406. dir = lg2->GetMakefile()->GetStartOutputDirectory();
  407. dir += "/directory";
  408. dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
  409. cmLocalGenerator::MAKEFILE);
  410. all_tgts.push_back(dir);
  411. }
  412. // write the directory rule
  413. commands.clear();
  414. commands.push_back
  415. (lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
  416. makeTargetName.c_str()));
  417. // Write the rule.
  418. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
  419. localName.c_str(), depends, commands);
  420. // Write the rule.
  421. commands.clear();
  422. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
  423. makeTargetName.c_str(), all_tgts, commands);
  424. }
  425. // now do the clean targets
  426. if (lg->GetParent())
  427. {
  428. std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
  429. dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
  430. makeTargetName = dir;
  431. makeTargetName += "/clean";
  432. std::vector<std::string> all_tgts;
  433. // for all of out targets
  434. for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
  435. l != lg->GetMakefile()->GetTargets().end(); l++)
  436. {
  437. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  438. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  439. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  440. (l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  441. (l->second.GetType() == cmTarget::UTILITY))
  442. {
  443. // Add this to the list of depends rules in this directory.
  444. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  445. tname += "/clean";
  446. all_tgts.push_back(tname);
  447. }
  448. }
  449. // write the directory rule add in the subdirs
  450. std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
  451. // for each subdir add the directory depend
  452. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  453. for (; sdi != subdirs.end(); ++sdi)
  454. {
  455. cmLocalUnixMakefileGenerator3 * lg2 =
  456. static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
  457. dir = lg2->GetMakefile()->GetStartOutputDirectory();
  458. dir += "/clean";
  459. dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
  460. cmLocalGenerator::MAKEFILE);
  461. all_tgts.push_back(dir);
  462. }
  463. // write the directory clean rule
  464. commands.clear();
  465. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory clean.",
  466. makeTargetName.c_str(), all_tgts, commands);
  467. }
  468. }
  469. //----------------------------------------------------------------------------
  470. void
  471. cmGlobalUnixMakefileGenerator3
  472. ::WriteDirectoryRules2(std::ostream& ruleFileStream,
  473. cmLocalUnixMakefileGenerator3 *lg)
  474. {
  475. std::vector<std::string> depends;
  476. std::vector<std::string> commands;
  477. std::string localName;
  478. std::string makeTargetName;
  479. depends.push_back("cmake_check_build_system");
  480. if (lg->GetParent())
  481. {
  482. std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
  483. dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
  484. lg->WriteDivider(ruleFileStream);
  485. ruleFileStream
  486. << "# Directory level rules for directory "
  487. << dir << "\n\n";
  488. localName = dir;
  489. localName += "/directorystart";
  490. makeTargetName = dir;
  491. makeTargetName += "/directory";
  492. std::vector<std::string> all_tgts;
  493. // for all of out targets
  494. for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
  495. l != lg->GetMakefile()->GetTargets().end(); l++)
  496. {
  497. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  498. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  499. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  500. (l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  501. (l->second.GetType() == cmTarget::UTILITY))
  502. {
  503. // Add this to the list of depends rules in this directory.
  504. if(l->second.IsInAll())
  505. {
  506. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  507. tname += "/all";
  508. all_tgts.push_back(tname);
  509. }
  510. }
  511. }
  512. // write the directory rule add in the subdirs
  513. std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
  514. // for each subdir add the directory depend
  515. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  516. for (; sdi != subdirs.end(); ++sdi)
  517. {
  518. cmLocalUnixMakefileGenerator3 * lg2 =
  519. static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
  520. dir = lg2->GetMakefile()->GetStartOutputDirectory();
  521. dir += "/directory";
  522. dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
  523. cmLocalGenerator::MAKEFILE);
  524. all_tgts.push_back(dir);
  525. }
  526. // write the directory rule
  527. commands.clear();
  528. commands.push_back
  529. (lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
  530. makeTargetName.c_str()));
  531. // Write the rule.
  532. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
  533. localName.c_str(), depends, commands);
  534. // Write the rule.
  535. commands.clear();
  536. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
  537. makeTargetName.c_str(), all_tgts, commands);
  538. }
  539. // now do the clean targets
  540. if (lg->GetParent())
  541. {
  542. std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
  543. dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
  544. makeTargetName = dir;
  545. makeTargetName += "/clean";
  546. std::vector<std::string> all_tgts;
  547. // for all of out targets
  548. for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
  549. l != lg->GetMakefile()->GetTargets().end(); l++)
  550. {
  551. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  552. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  553. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  554. (l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  555. (l->second.GetType() == cmTarget::UTILITY))
  556. {
  557. // Add this to the list of depends rules in this directory.
  558. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  559. tname += "/clean";
  560. all_tgts.push_back(tname);
  561. }
  562. }
  563. // write the directory rule add in the subdirs
  564. std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
  565. // for each subdir add the directory depend
  566. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  567. for (; sdi != subdirs.end(); ++sdi)
  568. {
  569. cmLocalUnixMakefileGenerator3 * lg2 =
  570. static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
  571. dir = lg2->GetMakefile()->GetStartOutputDirectory();
  572. dir += "/clean";
  573. dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
  574. cmLocalGenerator::MAKEFILE);
  575. all_tgts.push_back(dir);
  576. }
  577. // write the directory clean rule
  578. commands.clear();
  579. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory clean.",
  580. makeTargetName.c_str(), all_tgts, commands);
  581. }
  582. }
  583. //----------------------------------------------------------------------------
  584. void
  585. cmGlobalUnixMakefileGenerator3
  586. ::WriteConvenienceRules(std::ostream& ruleFileStream,
  587. cmLocalUnixMakefileGenerator3 *lg,
  588. std::set<cmStdString> &emitted)
  589. {
  590. std::vector<std::string> depends;
  591. std::vector<std::string> commands;
  592. // write the directory level rules for this local gen
  593. //this->WriteDirectoryRules(ruleFileStream,lg);
  594. depends.push_back("cmake_check_build_system");
  595. // for each target Generate the rule files for each target.
  596. cmTargets& targets = lg->GetMakefile()->GetTargets();
  597. for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
  598. {
  599. if((t->second.GetType() == cmTarget::EXECUTABLE) ||
  600. (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  601. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  602. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  603. (t->second.GetType() == cmTarget::UTILITY))
  604. {
  605. // Don't emit the same rule twice (e.g. two targets with the same
  606. // simple name)
  607. if(t->second.GetName() &&
  608. strlen(t->second.GetName()) &&
  609. emitted.insert(t->second.GetName()).second)
  610. {
  611. // Add a rule to build the target by name.
  612. lg->WriteDivider(ruleFileStream);
  613. ruleFileStream
  614. << "# Target rules for targets named "
  615. << t->second.GetName() << "\n\n";
  616. // Write the rule.
  617. commands.clear();
  618. commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
  619. t->second.GetName()));
  620. depends.clear();
  621. depends.push_back("cmake_check_build_system");
  622. lg->WriteMakeRule(ruleFileStream,
  623. "Build rule for target.",
  624. t->second.GetName(), depends, commands);
  625. }
  626. }
  627. }
  628. }
  629. //----------------------------------------------------------------------------
  630. void
  631. cmGlobalUnixMakefileGenerator3
  632. ::WriteConvenienceRules2(std::ostream& ruleFileStream,
  633. cmLocalUnixMakefileGenerator3 *lg,
  634. bool exclude)
  635. {
  636. std::vector<std::string> depends;
  637. std::vector<std::string> commands;
  638. std::string localName;
  639. std::string makeTargetName;
  640. // write the directory level rules for this local gen
  641. this->WriteDirectoryRules2(ruleFileStream,lg);
  642. depends.push_back("cmake_check_build_system");
  643. // for each target Generate the rule files for each target.
  644. cmTargets& targets = lg->GetMakefile()->GetTargets();
  645. for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
  646. {
  647. if (((t->second.GetType() == cmTarget::EXECUTABLE) ||
  648. (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  649. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  650. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  651. (t->second.GetType() == cmTarget::UTILITY)) &&
  652. t->second.GetName() &&
  653. strlen(t->second.GetName()))
  654. {
  655. bool needRequiresStep =
  656. this->NeedRequiresStep(lg,t->second.GetName());
  657. // Add a rule to build the target by name.
  658. localName = lg->GetRelativeTargetDirectory(t->second);
  659. std::string makefileName = localName;
  660. makefileName += "/build.make";
  661. lg->WriteDivider(ruleFileStream);
  662. ruleFileStream
  663. << "# Target rules for target "
  664. << localName << "\n\n";
  665. commands.clear();
  666. if (t->second.GetType() != cmTarget::UTILITY)
  667. {
  668. makeTargetName = localName;
  669. makeTargetName += "/depend";
  670. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  671. makeTargetName.c_str()));
  672. // add requires if we need it for this generator
  673. if (needRequiresStep)
  674. {
  675. makeTargetName = localName;
  676. makeTargetName += "/requires";
  677. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  678. makeTargetName.c_str()));
  679. }
  680. }
  681. makeTargetName = localName;
  682. makeTargetName += "/build";
  683. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  684. makeTargetName.c_str()));
  685. // Write the rule.
  686. localName += "/all";
  687. depends.clear();
  688. this->AppendGlobalTargetDepends(depends,t->second);
  689. lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
  690. localName.c_str(), depends, commands);
  691. // add the all/all dependency
  692. if (!exclude && t->second.IsInAll())
  693. {
  694. depends.clear();
  695. depends.push_back(localName);
  696. commands.clear();
  697. lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
  698. "all", depends, commands);
  699. }
  700. // Write the rule.
  701. commands.clear();
  702. commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
  703. localName.c_str()));
  704. depends.clear();
  705. depends.push_back("cmake_check_build_system");
  706. localName = lg->GetRelativeTargetDirectory(t->second);
  707. localName += "/rule";
  708. lg->WriteMakeRule(ruleFileStream,
  709. "Build rule for subdir invocation for target.",
  710. localName.c_str(), depends, commands);
  711. // Add a target with the canonical name (no prefix, suffix or path).
  712. commands.clear();
  713. depends.clear();
  714. depends.push_back(localName);
  715. lg->WriteMakeRule(ruleFileStream, "Convenience name for target.",
  716. t->second.GetName(), depends, commands);
  717. // add the clean rule
  718. localName = lg->GetRelativeTargetDirectory(t->second);
  719. makeTargetName = localName;
  720. makeTargetName += "/clean";
  721. depends.clear();
  722. commands.clear();
  723. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  724. makeTargetName.c_str()));
  725. lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
  726. makeTargetName.c_str(), depends, commands);
  727. commands.clear();
  728. depends.push_back(makeTargetName);
  729. lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
  730. "clean", depends, commands);
  731. }
  732. }
  733. }
  734. //----------------------------------------------------------------------------
  735. void
  736. cmGlobalUnixMakefileGenerator3
  737. ::AppendGlobalTargetDepends(std::vector<std::string>& depends,
  738. cmTarget& target)
  739. {
  740. // Keep track of dependencies already listed.
  741. std::set<cmStdString> emitted;
  742. // A target should not depend on itself.
  743. emitted.insert(target.GetName());
  744. // Loop over all library dependencies but not for static libs
  745. if (target.GetType() != cmTarget::STATIC_LIBRARY)
  746. {
  747. const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries();
  748. for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
  749. lib != tlibs.end(); ++lib)
  750. {
  751. // Don't emit the same library twice for this target.
  752. if(emitted.insert(lib->first).second)
  753. {
  754. // Add this dependency.
  755. this->AppendAnyGlobalDepend(depends, lib->first.c_str(), emitted);
  756. }
  757. }
  758. }
  759. // Loop over all utility dependencies.
  760. const std::set<cmStdString>& tutils = target.GetUtilities();
  761. for(std::set<cmStdString>::const_iterator util = tutils.begin();
  762. util != tutils.end(); ++util)
  763. {
  764. // Don't emit the same utility twice for this target.
  765. if(emitted.insert(*util).second)
  766. {
  767. // Add this dependency.
  768. this->AppendAnyGlobalDepend(depends, util->c_str(), emitted);
  769. }
  770. }
  771. }
  772. //----------------------------------------------------------------------------
  773. void
  774. cmGlobalUnixMakefileGenerator3
  775. ::AppendAnyGlobalDepend(std::vector<std::string>& depends, const char* name,
  776. std::set<cmStdString>& emitted)
  777. {
  778. cmTarget *result;
  779. // search each local generator until a match is found
  780. unsigned int i;
  781. for (i = 0; i < m_LocalGenerators.size(); ++i)
  782. {
  783. // search all targets
  784. result = m_LocalGenerators[i]->GetMakefile()->FindTarget(name);
  785. // if a match was found then ...
  786. if (result)
  787. {
  788. cmLocalUnixMakefileGenerator3 *lg3 =
  789. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  790. std::string tgtName = lg3->GetRelativeTargetDirectory(*result);
  791. tgtName += "/all";
  792. depends.push_back(tgtName);
  793. if(result->GetType() == cmTarget::STATIC_LIBRARY)
  794. {
  795. const cmTarget::LinkLibraries& tlibs = result->GetLinkLibraries();
  796. for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
  797. lib != tlibs.end(); ++lib)
  798. {
  799. // Don't emit the same library twice for this target.
  800. if(emitted.insert(lib->first).second)
  801. {
  802. // Add this dependency.
  803. this->AppendAnyGlobalDepend(depends, lib->first.c_str(),
  804. emitted);
  805. }
  806. }
  807. }
  808. return;
  809. }
  810. }
  811. }
  812. //----------------------------------------------------------------------------
  813. void
  814. cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
  815. {
  816. cmLocalUnixMakefileGenerator3 *lg =
  817. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  818. // add the help target
  819. std::string path;
  820. std::vector<std::string> no_depends;
  821. std::vector<std::string> commands;
  822. lg->AppendEcho(commands,
  823. "The following are some of the valid targets for this Makefile:");
  824. lg->AppendEcho(commands,"... all (the default if no target is provided)");
  825. lg->AppendEcho(commands,"... clean");
  826. lg->AppendEcho(commands,"... depend");
  827. lg->AppendEcho(commands,"... install");
  828. lg->AppendEcho(commands,"... rebuild_cache");
  829. // Keep track of targets already listed.
  830. std::set<cmStdString> emittedTargets;
  831. // for each local generator
  832. unsigned int i;
  833. for (i = 0; i < m_LocalGenerators.size(); ++i)
  834. {
  835. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  836. // for each target Generate the rule files for each target.
  837. cmTargets& targets = lg->GetMakefile()->GetTargets();
  838. for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
  839. {
  840. if((t->second.GetType() == cmTarget::EXECUTABLE) ||
  841. (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  842. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  843. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  844. (t->second.GetType() == cmTarget::UTILITY))
  845. {
  846. if(emittedTargets.insert(t->second.GetName()).second)
  847. {
  848. path = "... ";
  849. path += t->second.GetName();
  850. lg->AppendEcho(commands,path.c_str());
  851. }
  852. }
  853. }
  854. }
  855. lg->WriteMakeRule(ruleFileStream, "Help Target",
  856. "help:",
  857. no_depends, commands);
  858. ruleFileStream << "\n\n";
  859. }
  860. bool cmGlobalUnixMakefileGenerator3
  861. ::NeedRequiresStep(cmLocalUnixMakefileGenerator3 *lg,const char *name)
  862. {
  863. std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>&
  864. checkSet = lg->GetIntegrityCheckSet()[name];
  865. for(std::map<cmStdString,
  866. cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
  867. l = checkSet.begin(); l != checkSet.end(); ++l)
  868. {
  869. std::string name2 = "CMAKE_NEEDS_REQUIRES_STEP_";
  870. name2 += l->first;
  871. name2 += "_FLAG";
  872. if(lg->GetMakefile()->GetDefinition(name2.c_str()))
  873. {
  874. return true;
  875. }
  876. }
  877. return false;
  878. }