cmTarget.cxx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  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 "cmTarget.h"
  14. #include "cmMakefile.h"
  15. #include "cmSourceFile.h"
  16. #include "cmGlobalGenerator.h"
  17. #include <map>
  18. #include <set>
  19. #include <queue>
  20. #include <stdlib.h> // required for atof
  21. void cmTarget::SetType(TargetType type, const char* name)
  22. {
  23. m_Name = name;
  24. // only add dependency information for library targets
  25. m_TargetType = type;
  26. if(m_TargetType >= STATIC_LIBRARY && m_TargetType <= MODULE_LIBRARY) {
  27. m_RecordDependencies = true;
  28. } else {
  29. m_RecordDependencies = false;
  30. }
  31. }
  32. void cmTarget::TraceVSDependencies(std::string projFile,
  33. cmMakefile *makefile)
  34. {
  35. // get the classes from the source lists then add them to the groups
  36. std::vector<cmSourceFile*> & classes = this->GetSourceFiles();
  37. // use a deck to keep track of processed source files
  38. std::queue<std::string> srcFilesToProcess;
  39. std::set<cmStdString> srcFilesQueued;
  40. std::string name;
  41. std::vector<cmSourceFile*> newClasses;
  42. for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
  43. i != classes.end(); ++i)
  44. {
  45. name = (*i)->GetSourceName();
  46. if ((*i)->GetSourceExtension() != "rule")
  47. {
  48. name += ".";
  49. name += (*i)->GetSourceExtension();
  50. }
  51. srcFilesToProcess.push(name);
  52. srcFilesQueued.insert(name);
  53. // does this sourcefile have object depends on it?
  54. // If so then add them as well
  55. const char* additionalDeps = (*i)->GetProperty("OBJECT_DEPENDS");
  56. if (additionalDeps)
  57. {
  58. std::vector<std::string> depends;
  59. cmSystemTools::ExpandListArgument(additionalDeps, depends);
  60. for(std::vector<std::string>::iterator id = depends.begin();
  61. id != depends.end(); ++id)
  62. {
  63. // if there is a custom rule to generate that dependency
  64. // then add it to the list
  65. cmSourceFile* outsf =
  66. makefile->GetSourceFileWithOutput(id->c_str());
  67. // if a source file was found then add it
  68. if (outsf &&
  69. (std::find(classes.begin(),classes.end(),outsf) == classes.end()) &&
  70. (std::find(newClasses.begin(),newClasses.end(),outsf) == newClasses.end()))
  71. {
  72. // then add the source to this target and add it to the queue
  73. newClasses.push_back(outsf);
  74. name = outsf->GetSourceName();
  75. if (outsf->GetSourceExtension() != "rule")
  76. {
  77. name += ".";
  78. name += outsf->GetSourceExtension();
  79. }
  80. std::string temp =
  81. cmSystemTools::GetFilenamePath(outsf->GetFullPath());
  82. temp += "/";
  83. temp += name;
  84. // if it hasn't been processed
  85. if (srcFilesQueued.find(temp) == srcFilesQueued.end())
  86. {
  87. srcFilesToProcess.push(temp);
  88. srcFilesQueued.insert(temp);
  89. }
  90. }
  91. }
  92. }
  93. }
  94. for(std::vector<cmSourceFile*>::const_iterator i = newClasses.begin();
  95. i != newClasses.end(); ++i)
  96. {
  97. classes.push_back(*i);
  98. }
  99. // add in the project file itself
  100. srcFilesToProcess.push(projFile);
  101. srcFilesQueued.insert(projFile);
  102. // add in the library depends for custom targets
  103. if (this->GetType() == cmTarget::UTILITY)
  104. {
  105. for (std::vector<cmCustomCommand>::iterator ic =
  106. this->GetPostBuildCommands().begin();
  107. ic != this->GetPostBuildCommands().end(); ++ic)
  108. {
  109. cmCustomCommand &c = *ic;
  110. for (std::vector<std::string>::iterator i = c.GetDepends().begin();
  111. i != c.GetDepends().end(); ++i)
  112. {
  113. srcFilesToProcess.push(*i);
  114. srcFilesQueued.insert(*i);
  115. }
  116. }
  117. }
  118. while (!srcFilesToProcess.empty())
  119. {
  120. // is this source the output of a custom command
  121. cmSourceFile* outsf =
  122. makefile->GetSourceFileWithOutput(srcFilesToProcess.front().c_str());
  123. if (outsf)
  124. {
  125. // is it not already in the target?
  126. if (std::find(classes.begin(),classes.end(),outsf) == classes.end())
  127. {
  128. // then add the source to this target and add it to the queue
  129. classes.push_back(outsf);
  130. name = outsf->GetSourceName();
  131. if (outsf->GetSourceExtension() != "rule")
  132. {
  133. name += ".";
  134. name += outsf->GetSourceExtension();
  135. }
  136. std::string temp =
  137. cmSystemTools::GetFilenamePath(outsf->GetFullPath());
  138. temp += "/";
  139. temp += name;
  140. // if it hasn't been processed
  141. if (srcFilesQueued.find(temp) == srcFilesQueued.end())
  142. {
  143. srcFilesToProcess.push(temp);
  144. srcFilesQueued.insert(temp);
  145. }
  146. }
  147. // add its dependencies to the list to check
  148. unsigned int i;
  149. for (i = 0; i < outsf->GetCustomCommand()->GetDepends().size(); ++i)
  150. {
  151. std::string dep = cmSystemTools::GetFilenameName(
  152. outsf->GetCustomCommand()->GetDepends()[i]);
  153. if (cmSystemTools::GetFilenameLastExtension(dep) == ".exe")
  154. {
  155. dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
  156. }
  157. // watch for target dependencies,
  158. std::string libPath = dep + "_CMAKE_PATH";
  159. const char* cacheValue = makefile->GetDefinition(libPath.c_str());
  160. if (cacheValue && *cacheValue)
  161. {
  162. // add the depend as a utility on the target
  163. this->AddUtility(dep.c_str());
  164. }
  165. else
  166. {
  167. if (srcFilesQueued.find(outsf->GetCustomCommand()->GetDepends()[i])
  168. == srcFilesQueued.end())
  169. {
  170. srcFilesToProcess.push(outsf->GetCustomCommand()->GetDepends()[i]);
  171. srcFilesQueued.insert(outsf->GetCustomCommand()->GetDepends()[i]);
  172. }
  173. }
  174. }
  175. }
  176. // finished with this SF move to the next
  177. srcFilesToProcess.pop();
  178. }
  179. }
  180. void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf)
  181. {
  182. // this is only done for non install targets
  183. if ((this->m_TargetType == cmTarget::INSTALL_FILES)
  184. || (this->m_TargetType == cmTarget::INSTALL_PROGRAMS))
  185. {
  186. return;
  187. }
  188. // for each src lists add the classes
  189. for (std::vector<std::string>::const_iterator s = m_SourceLists.begin();
  190. s != m_SourceLists.end(); ++s)
  191. {
  192. int done = 0;
  193. // replace any variables
  194. std::string temps = *s;
  195. mf.ExpandVariablesInString(temps);
  196. // Next if one wasn't found then assume it is a single class
  197. // check to see if it is an existing source file
  198. if (!done && mf.GetSource(temps.c_str()))
  199. {
  200. m_SourceFiles.push_back(mf.GetSource(temps.c_str()));
  201. done = 1;
  202. }
  203. // if it wasn't a source file listed with the makefile
  204. // see if it is a variable. This is for old CMake 1.2 compatability
  205. // where a source list would be passed into here, by making it
  206. // a vector we need to possibly lookup the variable to maintain
  207. // CMake 1.2 compatability.
  208. const char* versionValue
  209. = mf.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
  210. if (!done)
  211. {
  212. if (!versionValue || atof(versionValue) <= 1.2)
  213. {
  214. const char* varValue =
  215. mf.GetDefinition(temps.c_str());
  216. // if the definition exists
  217. if (varValue)
  218. {
  219. std::vector<std::string> args;
  220. cmSystemTools::ExpandListArgument(varValue, args);
  221. unsigned int i;
  222. for (i = 0; i < args.size(); ++i)
  223. {
  224. if (mf.GetSource(args[i].c_str()))
  225. {
  226. m_SourceFiles.push_back(mf.GetSource(args[i].c_str()));
  227. }
  228. else
  229. {
  230. cmSourceFile file;
  231. file.SetProperty("ABSTRACT","0");
  232. file.SetName(args[i].c_str(), mf.GetCurrentDirectory(),
  233. mf.GetSourceExtensions(),
  234. mf.GetHeaderExtensions());
  235. m_SourceFiles.push_back(mf.AddSource(file));
  236. }
  237. }
  238. done = 1;
  239. }
  240. }
  241. }
  242. // if we still are not done, try to create the SourceFile structure
  243. if (!done)
  244. {
  245. cmSourceFile file;
  246. file.SetProperty("ABSTRACT","0");
  247. file.SetName(temps.c_str(), mf.GetCurrentDirectory(),
  248. mf.GetSourceExtensions(),
  249. mf.GetHeaderExtensions());
  250. m_SourceFiles.push_back(mf.AddSource(file));
  251. }
  252. }
  253. // expand any link library variables whle we are at it
  254. LinkLibraries::iterator p = m_LinkLibraries.begin();
  255. for (;p != m_LinkLibraries.end(); ++p)
  256. {
  257. mf.ExpandVariablesInString(p->first);
  258. }
  259. }
  260. void cmTarget::MergeLinkLibraries( cmMakefile& mf,
  261. const char *selfname,
  262. const LinkLibraries& libs )
  263. {
  264. // Only add on libraries we haven't added on before.
  265. // Assumption: the global link libraries could only grow, never shrink
  266. LinkLibraries::const_iterator i = libs.begin();
  267. i += m_PrevLinkedLibraries.size();
  268. for( ; i != libs.end(); ++i )
  269. {
  270. // We call this so that the dependencies get written to the cache
  271. this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second );
  272. }
  273. m_PrevLinkedLibraries = libs;
  274. }
  275. void cmTarget::AddLinkDirectory(const char* d)
  276. {
  277. // Make sure we don't add unnecessary search directories.
  278. if( std::find( m_LinkDirectories.begin(), m_LinkDirectories.end(), d )
  279. == m_LinkDirectories.end() )
  280. m_LinkDirectories.push_back( d );
  281. }
  282. void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target )
  283. {
  284. // Clear the dependencies. The cache variable must exist iff we are
  285. // recording dependency information for this target.
  286. std::string depname = target;
  287. depname += "_LIB_DEPENDS";
  288. if (m_RecordDependencies)
  289. {
  290. mf.AddCacheDefinition(depname.c_str(), "",
  291. "Dependencies for target", cmCacheManager::STATIC);
  292. }
  293. else
  294. {
  295. if (mf.GetDefinition( depname.c_str() ))
  296. {
  297. std::string message = "Target ";
  298. message += target;
  299. message += " has dependency information when it shouldn't.\n";
  300. message += "Your cache is probably stale. Please remove the entry\n ";
  301. message += depname;
  302. message += "\nfrom the cache.";
  303. cmSystemTools::Error( message.c_str() );
  304. }
  305. }
  306. }
  307. void cmTarget::AddLinkLibrary(const std::string& lib,
  308. LinkLibraryType llt)
  309. {
  310. m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
  311. }
  312. void cmTarget::AddLinkLibrary(cmMakefile& mf,
  313. const char *target, const char* lib,
  314. LinkLibraryType llt)
  315. {
  316. // Never add a self dependency, even if the user asks for it.
  317. if(strcmp( target, lib ) == 0)
  318. {
  319. return;
  320. }
  321. m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
  322. if(llt != cmTarget::GENERAL)
  323. {
  324. // Store the library's link type in the cache. If it is a
  325. // conflicting type then assume it is always used. This is the
  326. // case when the user sets the cache entries for debug and
  327. // optimized versions of the library to the same value.
  328. std::string linkTypeName = lib;
  329. linkTypeName += "_LINK_TYPE";
  330. switch(llt)
  331. {
  332. case cmTarget::DEBUG:
  333. {
  334. const char* def = mf.GetDefinition(linkTypeName.c_str());
  335. if(!def || strcmp(def, "debug") == 0)
  336. {
  337. mf.AddCacheDefinition(linkTypeName.c_str(),
  338. "debug", "Library is used for debug links only",
  339. cmCacheManager::STATIC);
  340. }
  341. else
  342. {
  343. mf.AddCacheDefinition(linkTypeName.c_str(),
  344. "general", "Library is used for both debug and optimized links",
  345. cmCacheManager::STATIC);
  346. }
  347. }
  348. break;
  349. case cmTarget::OPTIMIZED:
  350. {
  351. const char* def = mf.GetDefinition(linkTypeName.c_str());
  352. if(!def || strcmp(def, "optimized") == 0)
  353. {
  354. mf.AddCacheDefinition(linkTypeName.c_str(),
  355. "optimized", "Library is used for debug links only",
  356. cmCacheManager::STATIC);
  357. }
  358. else
  359. {
  360. mf.AddCacheDefinition(linkTypeName.c_str(),
  361. "general", "Library is used for both debug and optimized links",
  362. cmCacheManager::STATIC);
  363. }
  364. }
  365. break;
  366. case cmTarget::GENERAL:
  367. break;
  368. }
  369. }
  370. // Add the explicit dependency information for this target. This is
  371. // simply a set of libraries separated by ";". There should always
  372. // be a trailing ";". These library names are not canonical, in that
  373. // they may be "-framework x", "-ly", "/path/libz.a", etc.
  374. // We shouldn't remove duplicates here because external libraries
  375. // may be purposefully duplicated to handle recursive dependencies,
  376. // and we removing one instance will break the link line. Duplicates
  377. // will be appropriately eliminated at emit time.
  378. if(m_RecordDependencies)
  379. {
  380. std::string targetEntry = target;
  381. targetEntry += "_LIB_DEPENDS";
  382. std::string dependencies;
  383. const char* old_val = mf.GetDefinition( targetEntry.c_str() );
  384. if( old_val )
  385. {
  386. dependencies += old_val;
  387. }
  388. dependencies += lib;
  389. dependencies += ";";
  390. mf.AddCacheDefinition( targetEntry.c_str(), dependencies.c_str(),
  391. "Dependencies for the target",
  392. cmCacheManager::STATIC );
  393. }
  394. }
  395. void
  396. cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
  397. {
  398. // There are two key parts of the dependency analysis: (1)
  399. // determining the libraries in the link line, and (2) constructing
  400. // the dependency graph for those libraries.
  401. //
  402. // The latter is done using the cache entries that record the
  403. // dependencies of each library.
  404. //
  405. // The former is a more thorny issue, since it is not clear how to
  406. // determine if two libraries listed on the link line refer to the a
  407. // single library or not. For example, consider the link "libraries"
  408. // /usr/lib/libtiff.so -ltiff
  409. // Is this one library or two? The solution implemented here is the
  410. // simplest (and probably the only practical) one: two libraries are
  411. // the same if their "link strings" are identical. Thus, the two
  412. // libraries above are considered distinct. This also means that for
  413. // dependency analysis to be effective, the CMake user must specify
  414. // libraries build by his project without using any linker flags or
  415. // file extensions. That is,
  416. // LINK_LIBRARIES( One Two )
  417. // instead of
  418. // LINK_LIBRARIES( -lOne ${binarypath}/libTwo.a )
  419. // The former is probably what most users would do, but it never
  420. // hurts to document the assumptions. :-) Therefore, in the analysis
  421. // code, the "canonical name" of a library is simply its name as
  422. // given to a LINK_LIBRARIES command.
  423. //
  424. // Also, we will leave the original link line intact; we will just add any
  425. // dependencies that were missing.
  426. //
  427. // There is a problem with recursive external libraries
  428. // (i.e. libraries with no dependency information that are
  429. // recursively dependent). We must make sure that the we emit one of
  430. // the libraries twice to satisfy the recursion, but we shouldn't
  431. // emit it more times than necessary. In particular, we must make
  432. // sure that handling this improbable case doesn't cost us when
  433. // dealing with the common case of non-recursive libraries. The
  434. // solution is to assume that the recursion is satisfied at one node
  435. // of the dependency tree. To illustrate, assume libA and libB are
  436. // extrenal and mutually dependent. Suppose libX depends on
  437. // libA, and libY on libA and libX. Then
  438. // TARGET_LINK_LIBRARIES( Y X A B A )
  439. // TARGET_LINK_LIBRARIES( X A B A )
  440. // TARGET_LINK_LIBRARIES( Exec Y )
  441. // would result in "-lY -lX -lA -lB -lA". This is the correct way to
  442. // specify the dependencies, since the mutual dependency of A and B
  443. // is resolved *every time libA is specified*.
  444. //
  445. // Something like
  446. // TARGET_LINK_LIBRARIES( Y X A B A )
  447. // TARGET_LINK_LIBRARIES( X A B )
  448. // TARGET_LINK_LIBRARIES( Exec Y )
  449. // would result in "-lY -lX -lA -lB", and the mutual dependency
  450. // information is lost. This is because in some case (Y), the mutual
  451. // dependency of A and B is listed, while in another other case (X),
  452. // it is not. Depending on which line actually emits A, the mutual
  453. // dependency may or may not be on the final link line. We can't
  454. // handle this pathalogical case cleanly without emitting extra
  455. // libraries for the normal cases. Besides, the dependency
  456. // information for X is wrong anyway: if we build an executable
  457. // depending on X alone, we would not have the mutual dependency on
  458. // A and B resolved.
  459. //
  460. // IMPROVEMENTS:
  461. // -- The current algorithm will not always pick the "optimal" link line
  462. // when recursive dependencies are present. It will instead break the
  463. // cycles at an aribtrary point. The majority of projects won't have
  464. // cyclic dependencies, so this is probably not a big deal. Note that
  465. // the link line is always correct, just not necessary optimal.
  466. typedef std::vector< std::string > LinkLine;
  467. // The dependency map.
  468. DependencyMap dep_map;
  469. // If LIBRARY_OUTPUT_PATH is not set, then we must add search paths
  470. // for all the new libraries added by the dependency analysis.
  471. const char* libOutPath = mf.GetDefinition("LIBRARY_OUTPUT_PATH");
  472. bool addLibDirs = (libOutPath==0 || strcmp(libOutPath,"")==0);
  473. // 1. Build the dependency graph
  474. //
  475. for(LinkLibraries::reverse_iterator lib = m_LinkLibraries.rbegin();
  476. lib != m_LinkLibraries.rend(); ++lib)
  477. {
  478. this->GatherDependencies( mf, lib->first, dep_map );
  479. }
  480. // 2. Remove any dependencies that are already satisfied in the original
  481. // link line.
  482. //
  483. for(LinkLibraries::iterator lib = m_LinkLibraries.begin();
  484. lib != m_LinkLibraries.end(); ++lib)
  485. {
  486. for( LinkLibraries::iterator lib2 = lib;
  487. lib2 != m_LinkLibraries.end(); ++lib2)
  488. {
  489. DeleteDependency( dep_map, lib->first, lib2->first );
  490. }
  491. }
  492. // 3. Create the new link line by simply emitting any dependencies that are
  493. // missing. Start from the back and keep adding.
  494. //
  495. std::set<cmStdString> done, visited;
  496. std::vector<std::string> newLinkLibraries;
  497. for(LinkLibraries::reverse_iterator lib = m_LinkLibraries.rbegin();
  498. lib != m_LinkLibraries.rend(); ++lib)
  499. {
  500. // skip zero size library entries, this may happen
  501. // if a variable expands to nothing.
  502. if (lib->first.size() != 0)
  503. {
  504. Emit( lib->first, dep_map, done, visited, newLinkLibraries );
  505. }
  506. }
  507. // 4. Add the new libraries to the link line.
  508. //
  509. for( std::vector<std::string>::reverse_iterator k = newLinkLibraries.rbegin();
  510. k != newLinkLibraries.rend(); ++k )
  511. {
  512. if( addLibDirs )
  513. {
  514. // who the hell knows what this is, I think that K contains the
  515. // name of a library but ... Ken
  516. // k contains the same stuff that are on the LINK_LIBRARIES
  517. // commands. Normally, they would just be library names. -- Amitha.
  518. std::string libPathStr = *k + "_CMAKE_PATH";
  519. const char* libpath = mf.GetDefinition( libPathStr.c_str() );
  520. if( libpath )
  521. {
  522. // Don't add a link directory that is already present.
  523. if(std::find(m_LinkDirectories.begin(),
  524. m_LinkDirectories.end(), libpath) == m_LinkDirectories.end())
  525. {
  526. m_LinkDirectories.push_back(libpath);
  527. }
  528. }
  529. }
  530. std::string linkType = *k;
  531. linkType += "_LINK_TYPE";
  532. cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
  533. const char* linkTypeString = mf.GetDefinition( linkType.c_str() );
  534. if(linkTypeString)
  535. {
  536. if(strcmp(linkTypeString, "debug") == 0)
  537. {
  538. llt = cmTarget::DEBUG;
  539. }
  540. if(strcmp(linkTypeString, "optimized") == 0)
  541. {
  542. llt = cmTarget::OPTIMIZED;
  543. }
  544. }
  545. m_LinkLibraries.push_back( std::make_pair(*k,llt) );
  546. }
  547. }
  548. void cmTarget::InsertDependency( DependencyMap& depMap,
  549. const cmStdString& lib,
  550. const cmStdString& dep ) const
  551. {
  552. depMap[lib].push_back(dep);
  553. }
  554. void cmTarget::DeleteDependency( DependencyMap& depMap,
  555. const cmStdString& lib,
  556. const cmStdString& dep ) const
  557. {
  558. // Make sure there is an entry in the map for lib. If so, delete all
  559. // dependencies to dep. There may be repeated entries because of
  560. // external libraries that are specified multiple times.
  561. DependencyMap::iterator map_itr = depMap.find( lib );
  562. if( map_itr != depMap.end() )
  563. {
  564. DependencyList& depList = map_itr->second;
  565. DependencyList::iterator itr;
  566. while( (itr = std::find(depList.begin(), depList.end(), dep)) != depList.end() )
  567. {
  568. depList.erase( itr );
  569. }
  570. }
  571. }
  572. void cmTarget::Emit( const std::string& lib,
  573. const DependencyMap& dep_map,
  574. std::set<cmStdString>& emitted,
  575. std::set<cmStdString>& visited,
  576. std::vector<std::string>& link_line ) const
  577. {
  578. // It's already been emitted
  579. if( emitted.find(lib) != emitted.end() )
  580. return;
  581. // Emit the dependencies only if this library node hasn't been
  582. // visited before. If it has, then we have a cycle. The recursion
  583. // that got us here should take care of everything.
  584. if( visited.insert(lib).second )
  585. {
  586. if( dep_map.find(lib) != dep_map.end() ) // does it have dependencies?
  587. {
  588. const DependencyList& dep_on = dep_map.find( lib )->second;
  589. DependencyList::const_reverse_iterator i;
  590. // To cater for recursive external libraries, we must emit
  591. // duplicates on this link line *unless* they were emitted by
  592. // some other node, in which case we assume that the recursion
  593. // was resolved then. We making the simplifying assumption that
  594. // any duplicates on a single link line are on purpose, and must
  595. // be preserved.
  596. // This variable will keep track of the libraries that were
  597. // emitted directory from the current node, and not from a
  598. // recursive call. This way, if we come across a library that
  599. // has already been emitted, we repeat it iff it has been
  600. // emitted here.
  601. std::set<cmStdString> emitted_here;
  602. for( i = dep_on.rbegin(); i != dep_on.rend(); ++i )
  603. {
  604. if( emitted_here.find(*i) != emitted_here.end() )
  605. {
  606. // a repeat. Must emit.
  607. emitted.insert(*i);
  608. link_line.push_back( *i );
  609. }
  610. else
  611. {
  612. // Emit only if no-one else has
  613. if( emitted.find(*i) == emitted.end() )
  614. {
  615. // emit dependencies
  616. Emit( *i, dep_map, emitted, visited, link_line );
  617. // emit self
  618. emitted.insert(*i);
  619. emitted_here.insert(*i);
  620. link_line.push_back( *i );
  621. }
  622. }
  623. }
  624. }
  625. }
  626. }
  627. void cmTarget::GatherDependencies( const cmMakefile& mf,
  628. const std::string& lib,
  629. DependencyMap& dep_map )
  630. {
  631. // If the library is already in the dependency map, then it has
  632. // already been fully processed.
  633. if( dep_map.find(lib) != dep_map.end() )
  634. return;
  635. const char* deps = mf.GetDefinition( (lib+"_LIB_DEPENDS").c_str() );
  636. if( deps && strcmp(deps,"") != 0 )
  637. {
  638. // Make sure this library is in the map, even if it has an empty
  639. // set of dependencies. This distinguishes the case of explicitly
  640. // no dependencies with that of unspecified dependencies.
  641. dep_map[lib];
  642. // Parse the dependency information, which is simply a set of
  643. // libraries separated by ";". There is always a trailing ";".
  644. std::string depline = deps;
  645. std::string::size_type start = 0;
  646. std::string::size_type end;
  647. end = depline.find( ";", start );
  648. while( end != std::string::npos )
  649. {
  650. std::string l = depline.substr( start, end-start );
  651. if( l.size() != 0 )
  652. {
  653. InsertDependency( dep_map, lib, l );
  654. GatherDependencies( mf, l, dep_map );
  655. }
  656. start = end+1; // skip the ;
  657. end = depline.find( ";", start );
  658. }
  659. DeleteDependency( dep_map, lib, lib); // cannot depend on itself
  660. }
  661. }
  662. void cmTarget::SetProperty(const char* prop, const char* value)
  663. {
  664. if (!prop)
  665. {
  666. return;
  667. }
  668. if (!value)
  669. {
  670. value = "NOTFOUND";
  671. }
  672. m_Properties[prop] = value;
  673. }
  674. const char *cmTarget::GetProperty(const char* prop) const
  675. {
  676. std::map<cmStdString,cmStdString>::const_iterator i =
  677. m_Properties.find(prop);
  678. if (i != m_Properties.end())
  679. {
  680. return i->second.c_str();
  681. }
  682. return 0;
  683. }
  684. bool cmTarget::GetPropertyAsBool(const char* prop) const
  685. {
  686. std::map<cmStdString,cmStdString>::const_iterator i =
  687. m_Properties.find(prop);
  688. if (i != m_Properties.end())
  689. {
  690. return cmSystemTools::IsOn(i->second.c_str());
  691. }
  692. return false;
  693. }
  694. const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg) const
  695. {
  696. if(this->GetProperty("HAS_CXX"))
  697. {
  698. const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX");
  699. }
  700. const char* linkerLang = this->GetProperty("LINKER_LANGUAGE");
  701. if(linkerLang)
  702. {
  703. return linkerLang;
  704. }
  705. std::set<cmStdString> languages;
  706. for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin();
  707. i != m_SourceFiles.end(); ++i)
  708. {
  709. const char* lang =
  710. gg->GetLanguageFromExtension((*i)->GetSourceExtension().c_str());
  711. if(lang)
  712. {
  713. languages.insert(lang);
  714. }
  715. }
  716. if(languages.size() == 0)
  717. {
  718. return 0;
  719. }
  720. if(languages.size() == 1)
  721. {
  722. const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", languages.begin()->c_str());
  723. return this->GetProperty("LINKER_LANGUAGE");
  724. }
  725. const char* prefLang = 0;
  726. for(std::set<cmStdString>::const_iterator s = languages.begin();
  727. s != languages.end(); ++s)
  728. {
  729. const char* lpref = gg->GetLinkerPreference(s->c_str());
  730. if(lpref[0] == 'P')
  731. {
  732. if(prefLang && !(*s == prefLang))
  733. {
  734. std::string m = "Error Target: ";
  735. m += m_Name + " Contains more than one Prefered language: ";
  736. m += *s;
  737. m += " and ";
  738. m += prefLang;
  739. m += "\nYou must set the LINKER_LANGUAGE property for this target.";
  740. cmSystemTools::Error(m.c_str());
  741. }
  742. else
  743. {
  744. prefLang = s->c_str();
  745. }
  746. }
  747. }
  748. if(!prefLang)
  749. {
  750. prefLang = languages.begin()->c_str();
  751. }
  752. const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", prefLang);
  753. return this->GetProperty("LINKER_LANGUAGE");
  754. }
  755. const char* cmTarget::GetCreateRuleVariable()
  756. {
  757. switch(this->GetType())
  758. {
  759. case cmTarget::STATIC_LIBRARY:
  760. return "_CREATE_STATIC_LIBRARY";
  761. case cmTarget::SHARED_LIBRARY:
  762. return "_CREATE_SHARED_LIBRARY";
  763. case cmTarget::MODULE_LIBRARY:
  764. return "_CREATE_SHARED_MODULE";
  765. case cmTarget::EXECUTABLE:
  766. return "_LINK_EXECUTABLE";
  767. case cmTarget::UTILITY:
  768. case cmTarget::INSTALL_FILES:
  769. case cmTarget::INSTALL_PROGRAMS:
  770. break;
  771. }
  772. return "";
  773. }
  774. const char* cmTarget::GetSuffixVariable() const
  775. {
  776. switch(this->GetType())
  777. {
  778. case cmTarget::STATIC_LIBRARY:
  779. return "CMAKE_STATIC_LIBRARY_SUFFIX";
  780. case cmTarget::SHARED_LIBRARY:
  781. return "CMAKE_SHARED_LIBRARY_SUFFIX";
  782. case cmTarget::MODULE_LIBRARY:
  783. return "CMAKE_SHARED_MODULE_SUFFIX";
  784. case cmTarget::EXECUTABLE:
  785. return cmSystemTools::GetExecutableExtension();
  786. case cmTarget::UTILITY:
  787. case cmTarget::INSTALL_FILES:
  788. case cmTarget::INSTALL_PROGRAMS:
  789. break;
  790. }
  791. return "";
  792. }
  793. const char* cmTarget::GetPrefixVariable() const
  794. {
  795. switch(this->GetType())
  796. {
  797. case cmTarget::STATIC_LIBRARY:
  798. return "CMAKE_STATIC_LIBRARY_PREFIX";
  799. case cmTarget::SHARED_LIBRARY:
  800. return "CMAKE_SHARED_LIBRARY_PREFIX";
  801. case cmTarget::MODULE_LIBRARY:
  802. return "CMAKE_SHARED_MODULE_PREFIX";
  803. case cmTarget::EXECUTABLE:
  804. return cmSystemTools::GetExecutableExtension();
  805. case cmTarget::UTILITY:
  806. case cmTarget::INSTALL_FILES:
  807. case cmTarget::INSTALL_PROGRAMS:
  808. break;
  809. }
  810. return "";
  811. }