cmGeneratorTarget.cxx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmGeneratorTarget.h"
  11. #include "cmTarget.h"
  12. #include "cmMakefile.h"
  13. #include "cmLocalGenerator.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmSourceFile.h"
  16. #include "cmGeneratorExpression.h"
  17. #include "cmGeneratorExpressionDAGChecker.h"
  18. #include "cmComputeLinkInformation.h"
  19. #include <queue>
  20. #include "assert.h"
  21. //----------------------------------------------------------------------------
  22. cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
  23. {
  24. this->Makefile = this->Target->GetMakefile();
  25. this->LocalGenerator = this->Makefile->GetLocalGenerator();
  26. this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
  27. }
  28. //----------------------------------------------------------------------------
  29. int cmGeneratorTarget::GetType() const
  30. {
  31. return this->Target->GetType();
  32. }
  33. //----------------------------------------------------------------------------
  34. const char *cmGeneratorTarget::GetName() const
  35. {
  36. return this->Target->GetName();
  37. }
  38. //----------------------------------------------------------------------------
  39. const char *cmGeneratorTarget::GetProperty(const char *prop) const
  40. {
  41. return this->Target->GetProperty(prop);
  42. }
  43. //----------------------------------------------------------------------------
  44. std::vector<cmSourceFile*> const*
  45. cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const
  46. {
  47. SourceEntriesType::const_iterator i = this->SourceEntries.find(sf);
  48. if(i != this->SourceEntries.end())
  49. {
  50. return &i->second.Depends;
  51. }
  52. return 0;
  53. }
  54. static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name,
  55. const char *config, cmTarget *headTarget,
  56. cmGeneratorExpressionDAGChecker *dagChecker,
  57. std::vector<std::string>& result)
  58. {
  59. cmTarget* depTgt = mf->FindTargetToUse(name.c_str());
  60. if (!depTgt)
  61. {
  62. return;
  63. }
  64. cmListFileBacktrace lfbt;
  65. if (const char* dirs =
  66. depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"))
  67. {
  68. cmGeneratorExpression ge(lfbt);
  69. cmSystemTools::ExpandListArgument(ge.Parse(dirs)
  70. ->Evaluate(mf,
  71. config, false, headTarget,
  72. depTgt, dagChecker), result);
  73. }
  74. if (!depTgt->IsImported())
  75. {
  76. return;
  77. }
  78. if (const char* dirs =
  79. depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES"))
  80. {
  81. cmGeneratorExpression ge(lfbt);
  82. cmSystemTools::ExpandListArgument(ge.Parse(dirs)
  83. ->Evaluate(mf,
  84. config, false, headTarget,
  85. depTgt, dagChecker), result);
  86. }
  87. }
  88. //----------------------------------------------------------------------------
  89. bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
  90. const char *config) const
  91. {
  92. assert(this->GetType() != cmTarget::INTERFACE_LIBRARY);
  93. std::string config_upper;
  94. if(config && *config)
  95. {
  96. config_upper = cmSystemTools::UpperCase(config);
  97. }
  98. typedef std::map<std::string, std::vector<std::string> > IncludeCacheType;
  99. IncludeCacheType::const_iterator iter =
  100. this->SystemIncludesCache.find(config_upper);
  101. if (iter == this->SystemIncludesCache.end())
  102. {
  103. cmTarget::LinkImplementation const* impl
  104. = this->Target->GetLinkImplementation(config, this->Target);
  105. if(!impl)
  106. {
  107. return false;
  108. }
  109. cmListFileBacktrace lfbt;
  110. cmGeneratorExpressionDAGChecker dagChecker(lfbt,
  111. this->GetName(),
  112. "SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
  113. std::vector<std::string> result;
  114. for (std::set<cmStdString>::const_iterator
  115. it = this->Target->GetSystemIncludeDirectories().begin();
  116. it != this->Target->GetSystemIncludeDirectories().end(); ++it)
  117. {
  118. cmGeneratorExpression ge(lfbt);
  119. cmSystemTools::ExpandListArgument(ge.Parse(*it)
  120. ->Evaluate(this->Makefile,
  121. config, false, this->Target,
  122. &dagChecker), result);
  123. }
  124. std::set<cmStdString> uniqueDeps;
  125. for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
  126. li != impl->Libraries.end(); ++li)
  127. {
  128. if (uniqueDeps.insert(*li).second)
  129. {
  130. cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str());
  131. if (!tgt)
  132. {
  133. continue;
  134. }
  135. handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
  136. &dagChecker, result);
  137. std::vector<std::string> deps;
  138. tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps);
  139. for(std::vector<std::string>::const_iterator di = deps.begin();
  140. di != deps.end(); ++di)
  141. {
  142. if (uniqueDeps.insert(*di).second)
  143. {
  144. handleSystemIncludesDep(this->Makefile, *di, config, this->Target,
  145. &dagChecker, result);
  146. }
  147. }
  148. }
  149. }
  150. std::set<cmStdString> unique;
  151. for(std::vector<std::string>::iterator li = result.begin();
  152. li != result.end(); ++li)
  153. {
  154. cmSystemTools::ConvertToUnixSlashes(*li);
  155. unique.insert(*li);
  156. }
  157. result.clear();
  158. for(std::set<cmStdString>::iterator li = unique.begin();
  159. li != unique.end(); ++li)
  160. {
  161. result.push_back(*li);
  162. }
  163. IncludeCacheType::value_type entry(config_upper, result);
  164. iter = this->SystemIncludesCache.insert(entry).first;
  165. }
  166. std::string dirString = dir;
  167. return std::binary_search(iter->second.begin(), iter->second.end(),
  168. dirString);
  169. }
  170. //----------------------------------------------------------------------------
  171. bool cmGeneratorTarget::GetPropertyAsBool(const char *prop) const
  172. {
  173. return this->Target->GetPropertyAsBool(prop);
  174. }
  175. //----------------------------------------------------------------------------
  176. std::vector<cmSourceFile*> const& cmGeneratorTarget::GetSourceFiles() const
  177. {
  178. return this->Target->GetSourceFiles();
  179. }
  180. //----------------------------------------------------------------------------
  181. void cmGeneratorTarget::ClassifySources()
  182. {
  183. cmsys::RegularExpression header(CM_HEADER_REGEX);
  184. cmTarget::TargetType targetType = this->Target->GetType();
  185. bool isObjLib = targetType == cmTarget::OBJECT_LIBRARY;
  186. std::vector<cmSourceFile*> badObjLib;
  187. std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
  188. for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
  189. si != sources.end(); ++si)
  190. {
  191. cmSourceFile* sf = *si;
  192. std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
  193. if(sf->GetCustomCommand())
  194. {
  195. this->CustomCommands.push_back(sf);
  196. }
  197. else if(targetType == cmTarget::UTILITY)
  198. {
  199. this->ExtraSources.push_back(sf);
  200. }
  201. else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
  202. {
  203. this->HeaderSources.push_back(sf);
  204. }
  205. else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
  206. {
  207. this->ExternalObjects.push_back(sf);
  208. if(isObjLib) { badObjLib.push_back(sf); }
  209. }
  210. else if(sf->GetLanguage())
  211. {
  212. this->ObjectSources.push_back(sf);
  213. }
  214. else if(ext == "def")
  215. {
  216. this->ModuleDefinitionFile = sf->GetFullPath();
  217. if(isObjLib) { badObjLib.push_back(sf); }
  218. }
  219. else if(ext == "idl")
  220. {
  221. this->IDLSources.push_back(sf);
  222. if(isObjLib) { badObjLib.push_back(sf); }
  223. }
  224. else if(ext == "resx")
  225. {
  226. // Build and save the name of the corresponding .h file
  227. // This relationship will be used later when building the project files.
  228. // Both names would have been auto generated from Visual Studio
  229. // where the user supplied the file name and Visual Studio
  230. // appended the suffix.
  231. std::string resx = sf->GetFullPath();
  232. std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
  233. this->ExpectedResxHeaders.insert(hFileName);
  234. this->ResxSources.push_back(sf);
  235. }
  236. else if(header.find(sf->GetFullPath().c_str()))
  237. {
  238. this->HeaderSources.push_back(sf);
  239. }
  240. else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
  241. {
  242. // We only get here if a source file is not an external object
  243. // and has an extension that is listed as an ignored file type.
  244. // No message or diagnosis should be given.
  245. this->ExtraSources.push_back(sf);
  246. }
  247. else
  248. {
  249. this->ExtraSources.push_back(sf);
  250. if(isObjLib && ext != "txt")
  251. {
  252. badObjLib.push_back(sf);
  253. }
  254. }
  255. }
  256. if(!badObjLib.empty())
  257. {
  258. cmOStringStream e;
  259. e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
  260. for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
  261. i != badObjLib.end(); ++i)
  262. {
  263. e << " " << (*i)->GetLocation().GetName() << "\n";
  264. }
  265. e << "but may contain only headers and sources that compile.";
  266. this->GlobalGenerator->GetCMakeInstance()
  267. ->IssueMessage(cmake::FATAL_ERROR, e.str(),
  268. this->Target->GetBacktrace());
  269. }
  270. }
  271. //----------------------------------------------------------------------------
  272. void cmGeneratorTarget::LookupObjectLibraries()
  273. {
  274. std::vector<std::string> const& objLibs =
  275. this->Target->GetObjectLibraries();
  276. for(std::vector<std::string>::const_iterator oli = objLibs.begin();
  277. oli != objLibs.end(); ++oli)
  278. {
  279. std::string const& objLibName = *oli;
  280. if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
  281. {
  282. if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
  283. {
  284. if(this->Target->GetType() != cmTarget::EXECUTABLE &&
  285. this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
  286. this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
  287. this->Target->GetType() != cmTarget::MODULE_LIBRARY)
  288. {
  289. this->GlobalGenerator->GetCMakeInstance()
  290. ->IssueMessage(cmake::FATAL_ERROR,
  291. "Only executables and non-OBJECT libraries may "
  292. "reference target objects.",
  293. this->Target->GetBacktrace());
  294. return;
  295. }
  296. this->Target->AddUtility(objLib->GetName());
  297. this->ObjectLibraries.push_back(objLib);
  298. }
  299. else
  300. {
  301. cmOStringStream e;
  302. e << "Objects of target \"" << objLibName
  303. << "\" referenced but is not an OBJECT library.";
  304. this->GlobalGenerator->GetCMakeInstance()
  305. ->IssueMessage(cmake::FATAL_ERROR, e.str(),
  306. this->Target->GetBacktrace());
  307. return;
  308. }
  309. }
  310. else
  311. {
  312. cmOStringStream e;
  313. e << "Objects of target \"" << objLibName
  314. << "\" referenced but no such target exists.";
  315. this->GlobalGenerator->GetCMakeInstance()
  316. ->IssueMessage(cmake::FATAL_ERROR, e.str(),
  317. this->Target->GetBacktrace());
  318. return;
  319. }
  320. }
  321. }
  322. //----------------------------------------------------------------------------
  323. void
  324. cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
  325. {
  326. for(std::vector<cmTarget*>::const_iterator
  327. ti = this->ObjectLibraries.begin();
  328. ti != this->ObjectLibraries.end(); ++ti)
  329. {
  330. cmTarget* objLib = *ti;
  331. cmGeneratorTarget* ogt =
  332. this->GlobalGenerator->GetGeneratorTarget(objLib);
  333. for(std::vector<cmSourceFile*>::const_iterator
  334. si = ogt->ObjectSources.begin();
  335. si != ogt->ObjectSources.end(); ++si)
  336. {
  337. std::string obj = ogt->ObjectDirectory;
  338. obj += ogt->Objects[*si];
  339. objs.push_back(obj);
  340. }
  341. }
  342. }
  343. //----------------------------------------------------------------------------
  344. class cmTargetTraceDependencies
  345. {
  346. public:
  347. cmTargetTraceDependencies(cmGeneratorTarget* target);
  348. void Trace();
  349. private:
  350. cmTarget* Target;
  351. cmGeneratorTarget* GeneratorTarget;
  352. cmMakefile* Makefile;
  353. cmGlobalGenerator* GlobalGenerator;
  354. typedef cmGeneratorTarget::SourceEntry SourceEntry;
  355. SourceEntry* CurrentEntry;
  356. std::queue<cmSourceFile*> SourceQueue;
  357. std::set<cmSourceFile*> SourcesQueued;
  358. typedef std::map<cmStdString, cmSourceFile*> NameMapType;
  359. NameMapType NameMap;
  360. void QueueSource(cmSourceFile* sf);
  361. void FollowName(std::string const& name);
  362. void FollowNames(std::vector<std::string> const& names);
  363. bool IsUtility(std::string const& dep);
  364. void CheckCustomCommand(cmCustomCommand const& cc);
  365. void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
  366. };
  367. //----------------------------------------------------------------------------
  368. cmTargetTraceDependencies
  369. ::cmTargetTraceDependencies(cmGeneratorTarget* target):
  370. Target(target->Target), GeneratorTarget(target)
  371. {
  372. // Convenience.
  373. this->Makefile = this->Target->GetMakefile();
  374. this->GlobalGenerator =
  375. this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
  376. this->CurrentEntry = 0;
  377. // Queue all the source files already specified for the target.
  378. std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
  379. for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
  380. si != sources.end(); ++si)
  381. {
  382. this->QueueSource(*si);
  383. }
  384. // Queue pre-build, pre-link, and post-build rule dependencies.
  385. this->CheckCustomCommands(this->Target->GetPreBuildCommands());
  386. this->CheckCustomCommands(this->Target->GetPreLinkCommands());
  387. this->CheckCustomCommands(this->Target->GetPostBuildCommands());
  388. }
  389. //----------------------------------------------------------------------------
  390. void cmTargetTraceDependencies::Trace()
  391. {
  392. // Process one dependency at a time until the queue is empty.
  393. while(!this->SourceQueue.empty())
  394. {
  395. // Get the next source from the queue.
  396. cmSourceFile* sf = this->SourceQueue.front();
  397. this->SourceQueue.pop();
  398. this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
  399. // Queue dependencies added explicitly by the user.
  400. if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
  401. {
  402. std::vector<std::string> objDeps;
  403. cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
  404. this->FollowNames(objDeps);
  405. }
  406. // Queue the source needed to generate this file, if any.
  407. this->FollowName(sf->GetFullPath());
  408. // Queue dependencies added programatically by commands.
  409. this->FollowNames(sf->GetDepends());
  410. // Queue custom command dependencies.
  411. if(cmCustomCommand const* cc = sf->GetCustomCommand())
  412. {
  413. this->CheckCustomCommand(*cc);
  414. }
  415. }
  416. this->CurrentEntry = 0;
  417. }
  418. //----------------------------------------------------------------------------
  419. void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
  420. {
  421. if(this->SourcesQueued.insert(sf).second)
  422. {
  423. this->SourceQueue.push(sf);
  424. // Make sure this file is in the target.
  425. this->Target->AddSourceFile(sf);
  426. }
  427. }
  428. //----------------------------------------------------------------------------
  429. void cmTargetTraceDependencies::FollowName(std::string const& name)
  430. {
  431. NameMapType::iterator i = this->NameMap.find(name);
  432. if(i == this->NameMap.end())
  433. {
  434. // Check if we know how to generate this file.
  435. cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name.c_str());
  436. NameMapType::value_type entry(name, sf);
  437. i = this->NameMap.insert(entry).first;
  438. }
  439. if(cmSourceFile* sf = i->second)
  440. {
  441. // Record the dependency we just followed.
  442. if(this->CurrentEntry)
  443. {
  444. this->CurrentEntry->Depends.push_back(sf);
  445. }
  446. this->QueueSource(sf);
  447. }
  448. }
  449. //----------------------------------------------------------------------------
  450. void
  451. cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
  452. {
  453. for(std::vector<std::string>::const_iterator i = names.begin();
  454. i != names.end(); ++i)
  455. {
  456. this->FollowName(*i);
  457. }
  458. }
  459. //----------------------------------------------------------------------------
  460. bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
  461. {
  462. // Dependencies on targets (utilities) are supposed to be named by
  463. // just the target name. However for compatibility we support
  464. // naming the output file generated by the target (assuming there is
  465. // no output-name property which old code would not have set). In
  466. // that case the target name will be the file basename of the
  467. // dependency.
  468. std::string util = cmSystemTools::GetFilenameName(dep);
  469. if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
  470. {
  471. util = cmSystemTools::GetFilenameWithoutLastExtension(util);
  472. }
  473. // Check for a target with this name.
  474. if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str()))
  475. {
  476. // If we find the target and the dep was given as a full path,
  477. // then make sure it was not a full path to something else, and
  478. // the fact that the name matched a target was just a coincidence.
  479. if(cmSystemTools::FileIsFullPath(dep.c_str()))
  480. {
  481. if(t->GetType() >= cmTarget::EXECUTABLE &&
  482. t->GetType() <= cmTarget::MODULE_LIBRARY)
  483. {
  484. // This is really only for compatibility so we do not need to
  485. // worry about configuration names and output names.
  486. std::string tLocation = t->GetLocation(0);
  487. tLocation = cmSystemTools::GetFilenamePath(tLocation);
  488. std::string depLocation = cmSystemTools::GetFilenamePath(dep);
  489. depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
  490. tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
  491. if(depLocation == tLocation)
  492. {
  493. this->Target->AddUtility(util.c_str());
  494. return true;
  495. }
  496. }
  497. }
  498. else
  499. {
  500. // The original name of the dependency was not a full path. It
  501. // must name a target, so add the target-level dependency.
  502. this->Target->AddUtility(util.c_str());
  503. return true;
  504. }
  505. }
  506. // The dependency does not name a target built in this project.
  507. return false;
  508. }
  509. //----------------------------------------------------------------------------
  510. void
  511. cmTargetTraceDependencies
  512. ::CheckCustomCommand(cmCustomCommand const& cc)
  513. {
  514. // Transform command names that reference targets built in this
  515. // project to corresponding target-level dependencies.
  516. cmGeneratorExpression ge(cc.GetBacktrace());
  517. // Add target-level dependencies referenced by generator expressions.
  518. std::set<cmTarget*> targets;
  519. for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
  520. cit != cc.GetCommandLines().end(); ++cit)
  521. {
  522. std::string const& command = *cit->begin();
  523. // Check for a target with this name.
  524. if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str()))
  525. {
  526. if(t->GetType() == cmTarget::EXECUTABLE)
  527. {
  528. // The command refers to an executable target built in
  529. // this project. Add the target-level dependency to make
  530. // sure the executable is up to date before this custom
  531. // command possibly runs.
  532. this->Target->AddUtility(command.c_str());
  533. }
  534. }
  535. // Check for target references in generator expressions.
  536. for(cmCustomCommandLine::const_iterator cli = cit->begin();
  537. cli != cit->end(); ++cli)
  538. {
  539. const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
  540. = ge.Parse(*cli);
  541. cge->Evaluate(this->Makefile, 0, true);
  542. std::set<cmTarget*> geTargets = cge->GetTargets();
  543. for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
  544. it != geTargets.end(); ++it)
  545. {
  546. targets.insert(*it);
  547. }
  548. }
  549. }
  550. for(std::set<cmTarget*>::iterator ti = targets.begin();
  551. ti != targets.end(); ++ti)
  552. {
  553. this->Target->AddUtility((*ti)->GetName());
  554. }
  555. // Queue the custom command dependencies.
  556. std::vector<std::string> const& depends = cc.GetDepends();
  557. for(std::vector<std::string>::const_iterator di = depends.begin();
  558. di != depends.end(); ++di)
  559. {
  560. std::string const& dep = *di;
  561. if(!this->IsUtility(dep))
  562. {
  563. // The dependency does not name a target and may be a file we
  564. // know how to generate. Queue it.
  565. this->FollowName(dep);
  566. }
  567. }
  568. }
  569. //----------------------------------------------------------------------------
  570. void
  571. cmTargetTraceDependencies
  572. ::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
  573. {
  574. for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
  575. cli != commands.end(); ++cli)
  576. {
  577. this->CheckCustomCommand(*cli);
  578. }
  579. }
  580. //----------------------------------------------------------------------------
  581. void cmGeneratorTarget::TraceDependencies()
  582. {
  583. // CMake-generated targets have no dependencies to trace. Normally tracing
  584. // would find nothing anyway, but when building CMake itself the "install"
  585. // target command ends up referencing the "cmake" target but we do not
  586. // really want the dependency because "install" depend on "all" anyway.
  587. if(this->GetType() == cmTarget::GLOBAL_TARGET)
  588. {
  589. return;
  590. }
  591. // Use a helper object to trace the dependencies.
  592. cmTargetTraceDependencies tracer(this);
  593. tracer.Trace();
  594. }
  595. //----------------------------------------------------------------------------
  596. void cmGeneratorTarget::GetAppleArchs(const char* config,
  597. std::vector<std::string>& archVec) const
  598. {
  599. const char* archs = 0;
  600. if(config && *config)
  601. {
  602. std::string defVarName = "OSX_ARCHITECTURES_";
  603. defVarName += cmSystemTools::UpperCase(config);
  604. archs = this->Target->GetProperty(defVarName.c_str());
  605. }
  606. if(!archs)
  607. {
  608. archs = this->Target->GetProperty("OSX_ARCHITECTURES");
  609. }
  610. if(archs)
  611. {
  612. cmSystemTools::ExpandListArgument(std::string(archs), archVec);
  613. }
  614. }
  615. //----------------------------------------------------------------------------
  616. const char* cmGeneratorTarget::GetCreateRuleVariable() const
  617. {
  618. switch(this->GetType())
  619. {
  620. case cmTarget::STATIC_LIBRARY:
  621. return "_CREATE_STATIC_LIBRARY";
  622. case cmTarget::SHARED_LIBRARY:
  623. return "_CREATE_SHARED_LIBRARY";
  624. case cmTarget::MODULE_LIBRARY:
  625. return "_CREATE_SHARED_MODULE";
  626. case cmTarget::EXECUTABLE:
  627. return "_LINK_EXECUTABLE";
  628. default:
  629. break;
  630. }
  631. return "";
  632. }
  633. //----------------------------------------------------------------------------
  634. std::vector<std::string>
  635. cmGeneratorTarget::GetIncludeDirectories(const char *config) const
  636. {
  637. return this->Target->GetIncludeDirectories(config);
  638. }
  639. //----------------------------------------------------------------------------
  640. void cmGeneratorTarget::GenerateTargetManifest(const char* config) const
  641. {
  642. if (this->Target->IsImported())
  643. {
  644. return;
  645. }
  646. cmMakefile* mf = this->Target->GetMakefile();
  647. cmLocalGenerator* lg = mf->GetLocalGenerator();
  648. cmGlobalGenerator* gg = lg->GetGlobalGenerator();
  649. // Get the names.
  650. std::string name;
  651. std::string soName;
  652. std::string realName;
  653. std::string impName;
  654. std::string pdbName;
  655. if(this->GetType() == cmTarget::EXECUTABLE)
  656. {
  657. this->Target->GetExecutableNames(name, realName, impName, pdbName,
  658. config);
  659. }
  660. else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
  661. this->GetType() == cmTarget::SHARED_LIBRARY ||
  662. this->GetType() == cmTarget::MODULE_LIBRARY)
  663. {
  664. this->Target->GetLibraryNames(name, soName, realName, impName, pdbName,
  665. config);
  666. }
  667. else
  668. {
  669. return;
  670. }
  671. // Get the directory.
  672. std::string dir = this->Target->GetDirectory(config, false);
  673. // Add each name.
  674. std::string f;
  675. if(!name.empty())
  676. {
  677. f = dir;
  678. f += "/";
  679. f += name;
  680. gg->AddToManifest(config? config:"", f);
  681. }
  682. if(!soName.empty())
  683. {
  684. f = dir;
  685. f += "/";
  686. f += soName;
  687. gg->AddToManifest(config? config:"", f);
  688. }
  689. if(!realName.empty())
  690. {
  691. f = dir;
  692. f += "/";
  693. f += realName;
  694. gg->AddToManifest(config? config:"", f);
  695. }
  696. if(!pdbName.empty())
  697. {
  698. f = dir;
  699. f += "/";
  700. f += pdbName;
  701. gg->AddToManifest(config? config:"", f);
  702. }
  703. if(!impName.empty())
  704. {
  705. f = this->Target->GetDirectory(config, true);
  706. f += "/";
  707. f += impName;
  708. gg->AddToManifest(config? config:"", f);
  709. }
  710. }
  711. bool cmStrictTargetComparison::operator()(cmTarget const* t1,
  712. cmTarget const* t2) const
  713. {
  714. int nameResult = strcmp(t1->GetName(), t2->GetName());
  715. if (nameResult == 0)
  716. {
  717. return strcmp(t1->GetMakefile()->GetStartOutputDirectory(),
  718. t2->GetMakefile()->GetStartOutputDirectory()) < 0;
  719. }
  720. return nameResult < 0;
  721. }