cmTarget.cxx 29 KB

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