cmGlobalUnixMakefileGenerator3.cxx 35 KB

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