cmGlobalUnixMakefileGenerator3.cxx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  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. // now write the support Makefiles
  91. this->WriteDependMakefile();
  92. this->WriteBuildMakefile();
  93. this->WriteCleanMakefile();
  94. }
  95. void cmGlobalUnixMakefileGenerator3::WriteMainMakefile()
  96. {
  97. // Open the output file. This should not be copy-if-different
  98. // because the check-build-system step compares the makefile time to
  99. // see if the build system must be regenerated.
  100. std::string makefileName =
  101. this->GetCMakeInstance()->GetHomeOutputDirectory();
  102. makefileName += "/Makefile";
  103. cmGeneratedFileStream makefileStream(makefileName.c_str());
  104. if(!makefileStream)
  105. {
  106. return;
  107. }
  108. // get a local generator for some useful methods
  109. cmLocalUnixMakefileGenerator3 *lg =
  110. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  111. // Write the do not edit header.
  112. lg->WriteDisclaimer(makefileStream);
  113. // Write the main entry point target. This must be the VERY first
  114. // target so that make with no arguments will run it.
  115. // Just depend on the all target to drive the build.
  116. std::vector<std::string> depends;
  117. std::vector<std::string> no_commands;
  118. depends.push_back("all");
  119. // Write the rule.
  120. lg->WriteMakeRule(makefileStream,
  121. "Default target executed when no arguments are "
  122. "given to make.",
  123. "default_target",
  124. depends,
  125. no_commands);
  126. lg->WriteMakeVariables(makefileStream);
  127. lg->WriteSpecialTargetsTop(makefileStream);
  128. this->WriteAllRules(lg,makefileStream);
  129. // write the target convenience rules
  130. unsigned int i;
  131. for (i = 0; i < m_LocalGenerators.size(); ++i)
  132. {
  133. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  134. this->WriteConvenienceRules(makefileStream,lg);
  135. }
  136. }
  137. //----------------------------------------------------------------------------
  138. void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
  139. {
  140. // Open the output file. This should not be copy-if-different
  141. // because the check-build-system step compares the makefile time to
  142. // see if the build system must be regenerated.
  143. std::string cmakefileName =
  144. this->GetCMakeInstance()->GetHomeOutputDirectory();
  145. cmakefileName += "/Makefile.cmake";
  146. cmGeneratedFileStream cmakefileStream(cmakefileName.c_str());
  147. if(!cmakefileStream)
  148. {
  149. return;
  150. }
  151. std::string makefileName =
  152. this->GetCMakeInstance()->GetHomeOutputDirectory();
  153. makefileName += "/Makefile";
  154. // get a local generator for some useful methods
  155. cmLocalUnixMakefileGenerator3 *lg =
  156. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  157. // Write the do not edit header.
  158. lg->WriteDisclaimer(cmakefileStream);
  159. // for each cmMakefile get its list of dependencies
  160. unsigned int i;
  161. std::vector<std::string> lfiles;
  162. for (i = 0; i < m_LocalGenerators.size(); ++i)
  163. {
  164. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  165. // Get the list of files contributing to this generation step.
  166. lfiles.insert(lfiles.end(),lg->GetMakefile()->GetListFiles().begin(),
  167. lg->GetMakefile()->GetListFiles().end());
  168. }
  169. // Sort the list and remove duplicates.
  170. std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
  171. std::vector<std::string>::iterator new_end =
  172. std::unique(lfiles.begin(),lfiles.end());
  173. lfiles.erase(new_end, lfiles.end());
  174. // reset lg to the first makefile
  175. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  176. // Build the path to the cache file.
  177. std::string cache = this->GetCMakeInstance()->GetHomeOutputDirectory();
  178. cache += "/CMakeCache.txt";
  179. // Save the list to the cmake file.
  180. cmakefileStream
  181. << "# The top level Makefile was generated from the following files:\n"
  182. << "SET(CMAKE_MAKEFILE_DEPENDS\n"
  183. << " \"" << lg->ConvertToRelativePath(cache.c_str()).c_str() << "\"\n";
  184. for(std::vector<std::string>::const_iterator i = lfiles.begin();
  185. i != lfiles.end(); ++i)
  186. {
  187. cmakefileStream
  188. << " \"" << lg->ConvertToRelativePath(i->c_str()).c_str()
  189. << "\"\n";
  190. }
  191. cmakefileStream
  192. << " )\n\n";
  193. // Build the path to the cache check file.
  194. std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory();
  195. check += "/cmake.check_cache";
  196. // Set the corresponding makefile in the cmake file.
  197. cmakefileStream
  198. << "# The corresponding makefile is:\n"
  199. << "SET(CMAKE_MAKEFILE_OUTPUTS\n"
  200. << " \"" << lg->ConvertToRelativePath(makefileName.c_str()).c_str() << "\"\n"
  201. << " \"" << lg->ConvertToRelativePath(check.c_str()).c_str() << "\"\n";
  202. // add in all the directory information files
  203. std::string tmpStr;
  204. for (i = 0; i < m_LocalGenerators.size(); ++i)
  205. {
  206. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  207. tmpStr = lg->GetMakefile()->GetStartOutputDirectory();
  208. tmpStr += "/CMakeDirectoryInformation.cmake";
  209. cmakefileStream
  210. << " \"" << this->ConvertToHomeRelativePath(tmpStr.c_str()).c_str() << "\"\n";
  211. }
  212. cmakefileStream << " )\n\n";
  213. this->WriteMainCMakefileLanguageRules(cmakefileStream);
  214. }
  215. void cmGlobalUnixMakefileGenerator3
  216. ::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream)
  217. {
  218. cmLocalUnixMakefileGenerator3 *lg;
  219. // now write all the language stuff
  220. // Set the set of files to check for dependency integrity.
  221. // loop over all of the local generators to collect this
  222. std::set<cmStdString> checkSetLangs;
  223. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  224. {
  225. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  226. std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& checkSet =
  227. lg->GetIntegrityCheckSet();
  228. for(std::map<cmStdString,
  229. cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
  230. l = checkSet.begin(); l != checkSet.end(); ++l)
  231. {
  232. checkSetLangs.insert(l->first);
  233. }
  234. }
  235. // list the languages
  236. cmakefileStream
  237. << "# The set of files whose dependency integrity should be checked:\n";
  238. cmakefileStream
  239. << "SET(CMAKE_DEPENDS_LANGUAGES\n";
  240. for(std::set<cmStdString>::iterator
  241. l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
  242. {
  243. cmakefileStream << " \"" << l->c_str() << "\"\n";
  244. }
  245. cmakefileStream << " )\n";
  246. // now list the files for each language
  247. for(std::set<cmStdString>::iterator
  248. l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
  249. {
  250. cmakefileStream
  251. << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n";
  252. // now for each local gen get the checkset
  253. for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
  254. {
  255. lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  256. // get the check set for this local gen and language
  257. cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet =
  258. lg->GetIntegrityCheckSet()[*l];
  259. // for each file
  260. for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator csIter =
  261. iCheckSet.begin();
  262. csIter != iCheckSet.end(); ++csIter)
  263. {
  264. cmakefileStream
  265. << " \"" << this->ConvertToHomeRelativePath(csIter->c_str()).c_str() << "\"\n";
  266. }
  267. }
  268. cmakefileStream << " )\n";
  269. }
  270. }
  271. void cmGlobalUnixMakefileGenerator3::WriteDependMakefile()
  272. {
  273. unsigned int i;
  274. // Open the output file. This should not be copy-if-different
  275. // because the check-build-system step compares the makefile time to
  276. // see if the build system must be regenerated.
  277. std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory();
  278. makefileName += "/depend.make";
  279. cmGeneratedFileStream makefileStream(makefileName.c_str());
  280. if(!makefileStream)
  281. {
  282. return;
  283. }
  284. // get a local generator for some useful methods
  285. cmLocalUnixMakefileGenerator3 *lg =
  286. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  287. // Write the do not edit header.
  288. lg->WriteDisclaimer(makefileStream);
  289. lg->WriteMakeVariables(makefileStream);
  290. // add the generic dependency
  291. std::vector<std::string> depends;
  292. std::vector<std::string> no_commands;
  293. lg->WriteMakeRule(makefileStream, 0, "depend", depends, no_commands);
  294. // include the build rules
  295. makefileStream
  296. << "# Include make rules for build targets\n";
  297. makefileStream
  298. << lg->GetIncludeDirective() << " "
  299. << lg->ConvertToOutputForExisting("build.make").c_str()
  300. << "\n\n";
  301. // include all the target depends
  302. for (i = 0; i < m_LocalGenerators.size(); ++i)
  303. {
  304. cmLocalUnixMakefileGenerator3 *lg2 =
  305. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  306. if (!lg2->GetExcludeAll())
  307. {
  308. lg2->WriteTargetIncludes(makefileStream,"depend.make","depend");
  309. }
  310. }
  311. }
  312. void cmGlobalUnixMakefileGenerator3::WriteBuildMakefile()
  313. {
  314. unsigned int i;
  315. // Open the output file. This should not be copy-if-different
  316. // because the check-build-system step compares the makefile time to
  317. // see if the build system must be regenerated.
  318. std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory();
  319. makefileName += "/build.make";
  320. cmGeneratedFileStream makefileStream(makefileName.c_str());
  321. if(!makefileStream)
  322. {
  323. return;
  324. }
  325. // get a local generator for some useful methods
  326. cmLocalUnixMakefileGenerator3 *lg =
  327. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  328. // Write the do not edit header.
  329. lg->WriteDisclaimer(makefileStream);
  330. lg->WriteMakeVariables(makefileStream);
  331. // add the generic dependency
  332. std::vector<std::string> depends;
  333. std::vector<std::string> no_commands;
  334. lg->WriteMakeRule(makefileStream, 0, "build", depends, no_commands);
  335. // include all the target depends
  336. for (i = 0; i < m_LocalGenerators.size(); ++i)
  337. {
  338. cmLocalUnixMakefileGenerator3 *lg2 =
  339. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  340. // are any parents excluded
  341. bool exclude = false;
  342. cmLocalGenerator *lg3 = lg2;
  343. while (lg3)
  344. {
  345. if (lg3->GetExcludeAll())
  346. {
  347. exclude = true;
  348. break;
  349. }
  350. lg3 = lg3->GetParent();
  351. }
  352. if (!exclude)
  353. {
  354. lg2->WriteTargetIncludes(makefileStream,"build.make","build");
  355. }
  356. }
  357. }
  358. void cmGlobalUnixMakefileGenerator3::WriteCleanMakefile()
  359. {
  360. unsigned int i;
  361. // Open the output file. This should not be copy-if-different
  362. // because the check-build-system step compares the makefile time to
  363. // see if the build system must be regenerated.
  364. std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory();
  365. makefileName += "/clean.make";
  366. cmGeneratedFileStream makefileStream(makefileName.c_str());
  367. if(!makefileStream)
  368. {
  369. return;
  370. }
  371. // get a local generator for some useful methods
  372. cmLocalUnixMakefileGenerator3 *lg =
  373. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
  374. // Write the do not edit header.
  375. lg->WriteDisclaimer(makefileStream);
  376. lg->WriteMakeVariables(makefileStream);
  377. // add the generic dependency
  378. std::vector<std::string> depends;
  379. std::vector<std::string> no_commands;
  380. lg->WriteMakeRule(makefileStream, 0, "clean", depends, no_commands);
  381. // include all the target depends
  382. for (i = 0; i < m_LocalGenerators.size(); ++i)
  383. {
  384. cmLocalUnixMakefileGenerator3 *lg2 =
  385. static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
  386. lg2->WriteTargetIncludes(makefileStream,"clean.make","clean");
  387. // add the directory based rules
  388. lg2->WriteLocalCleanRule(makefileStream);
  389. }
  390. }
  391. //----------------------------------------------------------------------------
  392. void cmGlobalUnixMakefileGenerator3
  393. ::WriteAllRules(cmLocalUnixMakefileGenerator3 *lg,
  394. std::ostream& makefileStream)
  395. {
  396. // Write section header.
  397. lg->WriteDivider(makefileStream);
  398. makefileStream
  399. << "# Rules to build dependencies and targets.\n"
  400. << "\n";
  401. std::vector<std::string> depends;
  402. std::vector<std::string> commands;
  403. // Check the build system in this directory.
  404. depends.push_back("cmake_check_build_system");
  405. commands.push_back(this->GetRecursiveMakeCall("depend.make",0));
  406. commands.push_back(this->GetRecursiveMakeCall("build.make",0));
  407. // Write the rule.
  408. lg->WriteMakeRule(makefileStream, "The main all target", "all", depends, commands);
  409. // write the clean
  410. commands.clear();
  411. commands.push_back(this->GetRecursiveMakeCall("clean.make",0));
  412. lg->WriteMakeRule(makefileStream, "default clean target", "clean", depends, commands);
  413. // Write special "cmake_check_build_system" target to run cmake with
  414. // the --check-build-system flag.
  415. // Build command to run CMake to check if anything needs regenerating.
  416. std::string cmakefileName = this->GetCMakeInstance()->GetHomeOutputDirectory();
  417. cmakefileName += "/Makefile.cmake";
  418. std::string runRule = this->GetCMakeInstance()->GetCacheDefinition("CMAKE_COMMAND");
  419. runRule += " -H";
  420. runRule += this->GetCMakeInstance()->GetHomeDirectory();
  421. runRule += " -B";
  422. runRule += this->GetCMakeInstance()->GetHomeOutputDirectory();
  423. runRule += " --check-build-system ";
  424. runRule += lg->ConvertToRelativeOutputPath(cmakefileName.c_str());
  425. std::vector<std::string> no_depends;
  426. commands.clear();
  427. commands.push_back(runRule);
  428. lg->WriteMakeRule(makefileStream,
  429. "Special rule to run CMake to check the build system "
  430. "integrity.\n"
  431. "No rule that depends on this can have "
  432. "commands that come from listfiles\n"
  433. "because they might be regenerated.",
  434. "cmake_check_build_system",
  435. no_depends,
  436. commands);
  437. }
  438. //----------------------------------------------------------------------------
  439. std::string
  440. cmGlobalUnixMakefileGenerator3
  441. ::GetRecursiveMakeCall(const char *Makefile, const char* tgt)
  442. {
  443. cmLocalUnixMakefileGenerator3 *lg =
  444. static_cast<cmLocalUnixMakefileGenerator3*>(m_LocalGenerators[0]);
  445. // Call make on the given file.
  446. std::string cmd;
  447. cmd += "$(MAKE) -f ";
  448. cmd += Makefile;
  449. cmd += " ";
  450. // Pass down verbosity level.
  451. if(lg->GetMakeSilentFlag().size())
  452. {
  453. cmd += lg->GetMakeSilentFlag();
  454. cmd += " ";
  455. }
  456. // Most unix makes will pass the command line flags to make down to
  457. // sub-invoked makes via an environment variable. However, some
  458. // makes do not support that, so you have to pass the flags
  459. // explicitly.
  460. if(lg->GetPassMakeflags())
  461. {
  462. cmd += "-$(MAKEFLAGS) ";
  463. }
  464. // Add the target.
  465. if (tgt && tgt[0] != '\0')
  466. {
  467. cmd += tgt;
  468. }
  469. return cmd;
  470. }
  471. //----------------------------------------------------------------------------
  472. void
  473. cmGlobalUnixMakefileGenerator3
  474. ::WriteConvenienceRules(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *lg)
  475. {
  476. std::vector<std::string> depends;
  477. std::vector<std::string> tgt_depends;
  478. std::vector<std::string> commands;
  479. depends.push_back("cmake_check_build_system");
  480. // for each target
  481. // Generate the rule files for each target.
  482. const cmTargets& targets = lg->GetMakefile()->GetTargets();
  483. std::string localName;
  484. std::string makeTargetName;
  485. for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
  486. {
  487. if((t->second.GetType() == cmTarget::EXECUTABLE) ||
  488. (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  489. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  490. (t->second.GetType() == cmTarget::MODULE_LIBRARY))
  491. {
  492. // Add a rule to build the target by name.
  493. localName = lg->GetRelativeTargetDirectory(t->second);
  494. commands.clear();
  495. makeTargetName = localName;
  496. makeTargetName += "/depend";
  497. commands.push_back(this->GetRecursiveMakeCall("depend.make",makeTargetName.c_str()));
  498. makeTargetName = localName;
  499. makeTargetName += "/build";
  500. commands.push_back(this->GetRecursiveMakeCall("build.make",makeTargetName.c_str()));
  501. // Write the rule.
  502. lg->WriteMakeRule(ruleFileStream, "Convenience name for target.",
  503. localName.c_str(), depends, commands);
  504. // Add a target with the canonical name (no prefix, suffix or path).
  505. if(localName != t->second.GetName())
  506. {
  507. commands.clear();
  508. tgt_depends.clear();
  509. tgt_depends.push_back(localName);
  510. lg->WriteMakeRule(ruleFileStream, "Convenience name for target.",
  511. t->second.GetName(), tgt_depends, commands);
  512. }
  513. }
  514. }
  515. }