cmGlobalUnixMakefileGenerator3.cxx 32 KB

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