cmGlobalUnixMakefileGenerator3.cxx 35 KB

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