cmGlobalUnixMakefileGenerator3.cxx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  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->WriteMainCMakefile();
  90. }
  91. void cmGlobalUnixMakefileGenerator3::WriteMainMakefile()
  92. {
  93. // Open the output file. This should not be copy-if-different
  94. // because the check-build-system step compares the makefile time to
  95. // see if the build system must be regenerated.
  96. std::string makefileName =
  97. this->GetCMakeInstance()->GetHomeOutputDirectory();
  98. makefileName += "/Makefile";
  99. cmGeneratedFileStream makefileStream(makefileName.c_str());
  100. if(!makefileStream)
  101. {
  102. return;
  103. }
  104. // get a local generator for some useful methods
  105. cmLocalUnixMakefileGenerator3 *lg =
  106. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  107. // Write the do not edit header.
  108. lg->WriteDisclaimer(makefileStream);
  109. // Write the main entry point target. This must be the VERY first
  110. // target so that make with no arguments will run it.
  111. // Just depend on the all target to drive the build.
  112. std::vector<std::string> depends;
  113. std::vector<std::string> no_commands;
  114. depends.push_back("all");
  115. // Write the rule.
  116. lg->WriteMakeRule(makefileStream,
  117. "Default target executed when no arguments are "
  118. "given to make.",
  119. "default_target",
  120. depends,
  121. no_commands);
  122. lg->WriteMakeVariables(makefileStream);
  123. lg->WriteSpecialTargetsTop(makefileStream);
  124. this->WriteAllRules(lg,makefileStream);
  125. // write the target convenience rules
  126. unsigned int i;
  127. for (i = 0; i < m_LocalGenerators.size(); ++i)
  128. {
  129. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  130. // are any parents excluded
  131. bool exclude = false;
  132. cmLocalGenerator *lg3 = lg;
  133. while (lg3)
  134. {
  135. if (lg3->GetExcludeAll())
  136. {
  137. exclude = true;
  138. break;
  139. }
  140. lg3 = lg3->GetParent();
  141. }
  142. this->WriteConvenienceRules(makefileStream,lg,exclude);
  143. }
  144. this->WriteHelpRule(makefileStream);
  145. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  146. lg->WriteSpecialTargetsBottom(makefileStream);
  147. }
  148. //----------------------------------------------------------------------------
  149. void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
  150. {
  151. // Open the output file. This should not be copy-if-different
  152. // because the check-build-system step compares the makefile time to
  153. // see if the build system must be regenerated.
  154. std::string cmakefileName =
  155. this->GetCMakeInstance()->GetHomeOutputDirectory();
  156. cmakefileName += "/Makefile.cmake";
  157. cmGeneratedFileStream cmakefileStream(cmakefileName.c_str());
  158. if(!cmakefileStream)
  159. {
  160. return;
  161. }
  162. std::string makefileName =
  163. this->GetCMakeInstance()->GetHomeOutputDirectory();
  164. makefileName += "/Makefile";
  165. // get a local generator for some useful methods
  166. cmLocalUnixMakefileGenerator3 *lg =
  167. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  168. // Write the do not edit header.
  169. lg->WriteDisclaimer(cmakefileStream);
  170. // Save the generator name
  171. cmakefileStream
  172. << "# The generator used is:\n"
  173. << "SET(CMAKE_DEPENDS_GENERATOR \"" << this->GetName() << "\")\n\n";
  174. // for each cmMakefile get its list of dependencies
  175. std::vector<std::string> lfiles;
  176. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  177. {
  178. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  179. // Get the list of files contributing to this generation step.
  180. lfiles.insert(lfiles.end(),lg->GetMakefile()->GetListFiles().begin(),
  181. lg->GetMakefile()->GetListFiles().end());
  182. }
  183. // Sort the list and remove duplicates.
  184. std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
  185. std::vector<std::string>::iterator new_end =
  186. std::unique(lfiles.begin(),lfiles.end());
  187. lfiles.erase(new_end, lfiles.end());
  188. // reset lg to the first makefile
  189. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  190. // Build the path to the cache file.
  191. std::string cache = this->GetCMakeInstance()->GetHomeOutputDirectory();
  192. cache += "/CMakeCache.txt";
  193. // Save the list to the cmake file.
  194. cmakefileStream
  195. << "# The top level Makefile was generated from the following files:\n"
  196. << "SET(CMAKE_MAKEFILE_DEPENDS\n"
  197. << " \"" << lg->ConvertToRelativePath(cache.c_str()).c_str() << "\"\n";
  198. for(std::vector<std::string>::const_iterator i = lfiles.begin();
  199. i != lfiles.end(); ++i)
  200. {
  201. cmakefileStream
  202. << " \"" << lg->ConvertToRelativePath(i->c_str()).c_str()
  203. << "\"\n";
  204. }
  205. cmakefileStream
  206. << " )\n\n";
  207. // Build the path to the cache check file.
  208. std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory();
  209. check += "/cmake.check_cache";
  210. // Set the corresponding makefile in the cmake file.
  211. cmakefileStream
  212. << "# The corresponding makefile is:\n"
  213. << "SET(CMAKE_MAKEFILE_OUTPUTS\n"
  214. << " \"" << lg->ConvertToRelativePath(makefileName.c_str()).c_str() << "\"\n"
  215. << " \"" << lg->ConvertToRelativePath(check.c_str()).c_str() << "\"\n";
  216. // add in all the directory information files
  217. std::string tmpStr;
  218. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  219. {
  220. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  221. tmpStr = lg->GetMakefile()->GetStartOutputDirectory();
  222. tmpStr += "/CMakeDirectoryInformation.cmake";
  223. cmakefileStream << " \"" <<
  224. lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() << "\"\n";
  225. }
  226. cmakefileStream << " )\n\n";
  227. this->WriteMainCMakefileLanguageRules(cmakefileStream);
  228. }
  229. void cmGlobalUnixMakefileGenerator3
  230. ::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream)
  231. {
  232. cmLocalUnixMakefileGenerator3 *lg;
  233. // now write all the language stuff
  234. // Set the set of files to check for dependency integrity.
  235. // loop over all of the local generators to collect this
  236. std::set<cmStdString> checkSetLangs;
  237. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  238. {
  239. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  240. std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& checkSet =
  241. lg->GetIntegrityCheckSet();
  242. for(std::map<cmStdString,
  243. cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
  244. l = checkSet.begin(); l != checkSet.end(); ++l)
  245. {
  246. checkSetLangs.insert(l->first);
  247. }
  248. }
  249. // list the languages
  250. cmakefileStream
  251. << "# The set of files whose dependency integrity should be checked:\n";
  252. cmakefileStream
  253. << "SET(CMAKE_DEPENDS_LANGUAGES\n";
  254. for(std::set<cmStdString>::iterator
  255. l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
  256. {
  257. cmakefileStream << " \"" << l->c_str() << "\"\n";
  258. }
  259. cmakefileStream << " )\n";
  260. // now list the files for each language
  261. for(std::set<cmStdString>::iterator
  262. l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
  263. {
  264. cmakefileStream
  265. << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n";
  266. // now for each local gen get the checkset
  267. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  268. {
  269. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  270. // get the check set for this local gen and language
  271. cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet =
  272. lg->GetIntegrityCheckSet()[*l];
  273. // for each file
  274. for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator csIter =
  275. iCheckSet.begin();
  276. csIter != iCheckSet.end(); ++csIter)
  277. {
  278. cmakefileStream << " \"" <<
  279. lg->Convert(csIter->c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() << "\"\n";
  280. }
  281. }
  282. cmakefileStream << " )\n";
  283. }
  284. }
  285. //----------------------------------------------------------------------------
  286. void cmGlobalUnixMakefileGenerator3
  287. ::WriteAllRules(cmLocalUnixMakefileGenerator3 *lg,
  288. std::ostream& makefileStream)
  289. {
  290. // Write section header.
  291. lg->WriteDivider(makefileStream);
  292. makefileStream
  293. << "# Rules to build dependencies and targets.\n"
  294. << "\n";
  295. std::vector<std::string> depends;
  296. std::vector<std::string> commands;
  297. // Check the build system in this directory.
  298. depends.push_back("cmake_check_build_system");
  299. commands.push_back(lg->GetRecursiveMakeCall("Makefile","all/all"));
  300. // Write the rule.
  301. lg->WriteMakeRule(makefileStream, "The main all target", "all", depends, commands);
  302. // Write and empty all/all:
  303. commands.clear();
  304. lg->WriteMakeRule(makefileStream, "The main recursive all target", "all/all",
  305. commands, commands);
  306. // write the clean
  307. lg->WriteMakeRule(makefileStream, "The main clean target", "clean",
  308. commands, commands);
  309. }
  310. //----------------------------------------------------------------------------
  311. void
  312. cmGlobalUnixMakefileGenerator3
  313. ::WriteDirectoryRules(std::ostream& ruleFileStream,
  314. cmLocalUnixMakefileGenerator3 *lg)
  315. {
  316. std::vector<std::string> depends;
  317. std::vector<std::string> commands;
  318. std::string localName;
  319. std::string makeTargetName;
  320. depends.push_back("cmake_check_build_system");
  321. if (lg->GetParent())
  322. {
  323. std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
  324. dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
  325. lg->WriteDivider(ruleFileStream);
  326. ruleFileStream
  327. << "# Directory level rules for directory "
  328. << dir << "\n\n";
  329. localName = dir;
  330. localName += "/directorystart";
  331. makeTargetName = dir;
  332. makeTargetName += "/directory";
  333. std::vector<std::string> all_tgts;
  334. // for all of out targets
  335. for (cmTargets::const_iterator l = lg->GetMakefile()->GetTargets().begin();
  336. l != lg->GetMakefile()->GetTargets().end(); l++)
  337. {
  338. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  339. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  340. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  341. (l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  342. (l->second.GetType() == cmTarget::UTILITY))
  343. {
  344. // Add this to the list of depends rules in this directory.
  345. if(l->second.IsInAll())
  346. {
  347. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  348. tname += "/all";
  349. all_tgts.push_back(tname);
  350. }
  351. }
  352. }
  353. // write the directory rule add in the subdirs
  354. std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
  355. // for each subdir add the directory depend
  356. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  357. for (; sdi != subdirs.end(); ++sdi)
  358. {
  359. cmLocalUnixMakefileGenerator3 * lg2 =
  360. static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
  361. dir = lg2->GetMakefile()->GetStartOutputDirectory();
  362. dir += "/directory";
  363. dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
  364. cmLocalGenerator::MAKEFILE);
  365. all_tgts.push_back(dir);
  366. }
  367. // write the directory rule
  368. commands.clear();
  369. commands.push_back
  370. (lg->GetRecursiveMakeCall("Makefile",makeTargetName.c_str()));
  371. // Write the rule.
  372. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
  373. localName.c_str(), depends, commands);
  374. // Write the rule.
  375. commands.clear();
  376. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
  377. makeTargetName.c_str(), all_tgts, commands);
  378. }
  379. // now do the clean targets
  380. if (lg->GetParent())
  381. {
  382. std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
  383. dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
  384. makeTargetName = dir;
  385. makeTargetName += "/clean";
  386. std::vector<std::string> all_tgts;
  387. // for all of out targets
  388. for (cmTargets::const_iterator l = lg->GetMakefile()->GetTargets().begin();
  389. l != lg->GetMakefile()->GetTargets().end(); l++)
  390. {
  391. if((l->second.GetType() == cmTarget::EXECUTABLE) ||
  392. (l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  393. (l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  394. (l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  395. (l->second.GetType() == cmTarget::UTILITY))
  396. {
  397. // Add this to the list of depends rules in this directory.
  398. std::string tname = lg->GetRelativeTargetDirectory(l->second);
  399. tname += "/clean";
  400. all_tgts.push_back(tname);
  401. }
  402. }
  403. // write the directory rule add in the subdirs
  404. std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
  405. // for each subdir add the directory depend
  406. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  407. for (; sdi != subdirs.end(); ++sdi)
  408. {
  409. cmLocalUnixMakefileGenerator3 * lg2 =
  410. static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
  411. dir = lg2->GetMakefile()->GetStartOutputDirectory();
  412. dir += "/clean";
  413. dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
  414. cmLocalGenerator::MAKEFILE);
  415. all_tgts.push_back(dir);
  416. }
  417. // write the directory clean rule
  418. commands.clear();
  419. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory clean.",
  420. makeTargetName.c_str(), all_tgts, commands);
  421. }
  422. }
  423. //----------------------------------------------------------------------------
  424. void
  425. cmGlobalUnixMakefileGenerator3
  426. ::WriteConvenienceRules(std::ostream& ruleFileStream,
  427. cmLocalUnixMakefileGenerator3 *lg,
  428. bool exclude)
  429. {
  430. std::vector<std::string> depends;
  431. std::vector<std::string> commands;
  432. std::string localName;
  433. std::string makeTargetName;
  434. // write the directory level rules for this local gen
  435. this->WriteDirectoryRules(ruleFileStream,lg);
  436. depends.push_back("cmake_check_build_system");
  437. // for each target Generate the rule files for each target.
  438. const cmTargets& targets = lg->GetMakefile()->GetTargets();
  439. bool needRequiresStep = this->NeedRequiresStep(lg);
  440. for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
  441. {
  442. if((t->second.GetType() == cmTarget::EXECUTABLE) ||
  443. (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  444. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  445. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  446. (t->second.GetType() == cmTarget::UTILITY))
  447. {
  448. // Add a rule to build the target by name.
  449. localName = lg->GetRelativeTargetDirectory(t->second);
  450. std::string makefileName = localName;
  451. makefileName += "/build.make";
  452. lg->WriteDivider(ruleFileStream);
  453. ruleFileStream
  454. << "# Target rules for target "
  455. << localName << "\n\n";
  456. commands.clear();
  457. if (t->second.GetType() != cmTarget::UTILITY)
  458. {
  459. makeTargetName = localName;
  460. makeTargetName += "/depend";
  461. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  462. makeTargetName.c_str()));
  463. // add requires if we need it for this generator
  464. if (needRequiresStep)
  465. {
  466. makeTargetName = localName;
  467. makeTargetName += "/requires";
  468. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  469. makeTargetName.c_str()));
  470. }
  471. }
  472. makeTargetName = localName;
  473. makeTargetName += "/build";
  474. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  475. makeTargetName.c_str()));
  476. // Write the rule.
  477. localName += "/all";
  478. depends.clear();
  479. this->AppendGlobalTargetDepends(depends,t->second);
  480. lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
  481. localName.c_str(), depends, commands);
  482. // add the all/all dependency
  483. if (!exclude && t->second.IsInAll())
  484. {
  485. depends.clear();
  486. depends.push_back(localName);
  487. commands.clear();
  488. lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
  489. "all/all", depends, commands);
  490. }
  491. // Write the rule.
  492. commands.clear();
  493. commands.push_back(lg->GetRecursiveMakeCall("Makefile",localName.c_str()));
  494. depends.clear();
  495. depends.push_back("cmake_check_build_system");
  496. localName = lg->GetRelativeTargetDirectory(t->second);
  497. lg->WriteMakeRule(ruleFileStream, "Build rule for subir invocation for target.",
  498. localName.c_str(), depends, commands);
  499. // Add a target with the canonical name (no prefix, suffix or path).
  500. commands.clear();
  501. depends.clear();
  502. depends.push_back(localName);
  503. lg->WriteMakeRule(ruleFileStream, "Convenience name for target.",
  504. t->second.GetName(), depends, commands);
  505. // add the clean rule
  506. makeTargetName = localName;
  507. makeTargetName += "/clean";
  508. depends.clear();
  509. commands.clear();
  510. commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(),
  511. makeTargetName.c_str()));
  512. lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
  513. makeTargetName.c_str(), depends, commands);
  514. commands.clear();
  515. depends.push_back(makeTargetName);
  516. lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
  517. "clean", depends, commands);
  518. }
  519. }
  520. }
  521. //----------------------------------------------------------------------------
  522. void
  523. cmGlobalUnixMakefileGenerator3
  524. ::AppendGlobalTargetDepends(std::vector<std::string>& depends,
  525. const cmTarget& target)
  526. {
  527. // Keep track of dependencies already listed.
  528. std::set<cmStdString> emitted;
  529. // A target should not depend on itself.
  530. emitted.insert(target.GetName());
  531. // Loop over all library dependencies but not for static libs
  532. if (target.GetType() != cmTarget::STATIC_LIBRARY)
  533. {
  534. const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries();
  535. for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
  536. lib != tlibs.end(); ++lib)
  537. {
  538. // Don't emit the same library twice for this target.
  539. if(emitted.insert(lib->first).second)
  540. {
  541. // Add this dependency.
  542. this->AppendAnyGlobalDepend(depends, lib->first.c_str());
  543. }
  544. }
  545. }
  546. // Loop over all utility dependencies.
  547. const std::set<cmStdString>& tutils = target.GetUtilities();
  548. for(std::set<cmStdString>::const_iterator util = tutils.begin();
  549. util != tutils.end(); ++util)
  550. {
  551. // Don't emit the same utility twice for this target.
  552. if(emitted.insert(*util).second)
  553. {
  554. // Add this dependency.
  555. this->AppendAnyGlobalDepend(depends, util->c_str());
  556. }
  557. }
  558. }
  559. //----------------------------------------------------------------------------
  560. void
  561. cmGlobalUnixMakefileGenerator3
  562. ::AppendAnyGlobalDepend(std::vector<std::string>& depends, const char* name)
  563. {
  564. cmTarget *result;
  565. // search each local generator until a match is found
  566. unsigned int i;
  567. for (i = 0; i < m_LocalGenerators.size(); ++i)
  568. {
  569. // search all targets
  570. result = m_LocalGenerators[i]->GetMakefile()->FindTarget(name);
  571. // if a match was found then ...
  572. if (result)
  573. {
  574. cmLocalUnixMakefileGenerator3 *lg3 =
  575. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  576. std::string tgtName = lg3->GetRelativeTargetDirectory(*result);
  577. tgtName += "/all";
  578. depends.push_back(tgtName);
  579. return;
  580. }
  581. }
  582. }
  583. //----------------------------------------------------------------------------
  584. void
  585. cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
  586. {
  587. cmLocalUnixMakefileGenerator3 *lg =
  588. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  589. // add the help target
  590. std::string path;
  591. std::vector<std::string> no_depends;
  592. std::vector<std::string> commands;
  593. lg->AppendEcho(commands,
  594. "The following are some of the valid targets for this Makefile:");
  595. lg->AppendEcho(commands,"... all (the default if no target is provided)");
  596. lg->AppendEcho(commands,"... clean");
  597. lg->AppendEcho(commands,"... depend");
  598. lg->AppendEcho(commands,"... install");
  599. lg->AppendEcho(commands,"... rebuild_cache");
  600. // for each local generator
  601. unsigned int i;
  602. for (i = 0; i < m_LocalGenerators.size(); ++i)
  603. {
  604. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  605. // for each target Generate the rule files for each target.
  606. const cmTargets& targets = lg->GetMakefile()->GetTargets();
  607. for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
  608. {
  609. if((t->second.GetType() == cmTarget::EXECUTABLE) ||
  610. (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  611. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  612. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  613. (t->second.GetType() == cmTarget::UTILITY))
  614. {
  615. path = "... ";
  616. path += t->second.GetName();
  617. lg->AppendEcho(commands,path.c_str());
  618. }
  619. }
  620. }
  621. lg->WriteMakeRule(ruleFileStream, "Help Target",
  622. "help:",
  623. no_depends, commands);
  624. ruleFileStream << "\n\n";
  625. }
  626. bool cmGlobalUnixMakefileGenerator3
  627. ::NeedRequiresStep(cmLocalUnixMakefileGenerator3 *lg)
  628. {
  629. std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>&
  630. checkSet = lg->GetIntegrityCheckSet();
  631. for(std::map<cmStdString,
  632. cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
  633. l = checkSet.begin(); l != checkSet.end(); ++l)
  634. {
  635. std::string name = "CMAKE_NEEDS_REQUIRES_STEP_";
  636. name += l->first;
  637. name += "_FLAG";
  638. if(lg->GetMakefile()->GetDefinition(name.c_str()))
  639. {
  640. return true;
  641. }
  642. }
  643. return false;
  644. }