cmTarget.cxx 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518
  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 "cmLocalGenerator.h"
  17. #include "cmGlobalGenerator.h"
  18. #include <map>
  19. #include <set>
  20. #include <queue>
  21. #include <stdlib.h> // required for atof
  22. //----------------------------------------------------------------------------
  23. cmTarget::cmTarget()
  24. {
  25. m_Makefile = 0;
  26. m_LinkLibrariesAnalyzed = false;
  27. m_LinkDirectoriesComputed = false;
  28. m_HaveInstallRule = false;
  29. }
  30. void cmTarget::SetType(TargetType type, const char* name)
  31. {
  32. m_Name = name;
  33. // only add dependency information for library targets
  34. m_TargetType = type;
  35. if(m_TargetType >= STATIC_LIBRARY && m_TargetType <= MODULE_LIBRARY) {
  36. m_RecordDependencies = true;
  37. } else {
  38. m_RecordDependencies = false;
  39. }
  40. }
  41. //----------------------------------------------------------------------------
  42. void cmTarget::SetMakefile(cmMakefile* mf)
  43. {
  44. // Set our makefile.
  45. m_Makefile = mf;
  46. // Setup default property values.
  47. this->SetPropertyDefault("INSTALL_NAME_DIR", "");
  48. this->SetPropertyDefault("INSTALL_RPATH", "");
  49. this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
  50. this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
  51. // Collect the set of configuration types.
  52. std::vector<std::string> configNames;
  53. if(const char* configurationTypes =
  54. mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
  55. {
  56. cmSystemTools::ExpandListArgument(configurationTypes, configNames);
  57. }
  58. else if(const char* buildType = mf->GetDefinition("CMAKE_BUILD_TYPE"))
  59. {
  60. if(*buildType)
  61. {
  62. configNames.push_back(buildType);
  63. }
  64. }
  65. // Setup per-configuration property default values.
  66. for(std::vector<std::string>::iterator ci = configNames.begin();
  67. ci != configNames.end(); ++ci)
  68. {
  69. // Initialize per-configuration name postfix property from the
  70. // variable only for non-executable targets. This preserves
  71. // compatibility with previous CMake versions in which executables
  72. // did not support this variable. Projects may still specify the
  73. // property directly. TODO: Make this depend on backwards
  74. // compatibility setting.
  75. if(m_TargetType != cmTarget::EXECUTABLE)
  76. {
  77. std::string property = cmSystemTools::UpperCase(*ci);
  78. property += "_POSTFIX";
  79. this->SetPropertyDefault(property.c_str(), 0);
  80. }
  81. }
  82. }
  83. void cmTarget::TraceVSDependencies(std::string projFile,
  84. cmMakefile *makefile)
  85. {
  86. // get the classes from the source lists then add them to the groups
  87. std::vector<cmSourceFile*> & classes = this->GetSourceFiles();
  88. // use a deck to keep track of processed source files
  89. std::queue<std::string> srcFilesToProcess;
  90. std::set<cmStdString> srcFilesQueued;
  91. std::string name;
  92. std::vector<cmSourceFile*> newClasses;
  93. for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
  94. i != classes.end(); ++i)
  95. {
  96. name = (*i)->GetSourceName();
  97. if ((*i)->GetSourceExtension() != "rule")
  98. {
  99. name += ".";
  100. name += (*i)->GetSourceExtension();
  101. }
  102. srcFilesToProcess.push(name);
  103. srcFilesQueued.insert(name);
  104. // does this sourcefile have object depends on it?
  105. // If so then add them as well
  106. const char* additionalDeps = (*i)->GetProperty("OBJECT_DEPENDS");
  107. std::vector<std::string> depends = (*i)->GetDepends();
  108. if (additionalDeps || depends.size())
  109. {
  110. if(additionalDeps)
  111. {
  112. cmSystemTools::ExpandListArgument(additionalDeps, depends);
  113. }
  114. for(std::vector<std::string>::iterator id = depends.begin();
  115. id != depends.end(); ++id)
  116. {
  117. // if there is a custom rule to generate that dependency
  118. // then add it to the list
  119. cmSourceFile* outsf =
  120. makefile->GetSourceFileWithOutput(id->c_str());
  121. // if a source file was found then add it
  122. if (outsf &&
  123. (std::find(classes.begin(),classes.end(),outsf) == classes.end()) &&
  124. (std::find(newClasses.begin(),newClasses.end(),outsf) == newClasses.end()))
  125. {
  126. // then add the source to this target and add it to the queue
  127. newClasses.push_back(outsf);
  128. name = outsf->GetSourceName();
  129. if (outsf->GetSourceExtension() != "rule")
  130. {
  131. name += ".";
  132. name += outsf->GetSourceExtension();
  133. }
  134. std::string temp =
  135. cmSystemTools::GetFilenamePath(outsf->GetFullPath());
  136. temp += "/";
  137. temp += name;
  138. // if it hasn't been processed
  139. if (srcFilesQueued.find(temp) == srcFilesQueued.end())
  140. {
  141. srcFilesToProcess.push(temp);
  142. srcFilesQueued.insert(temp);
  143. }
  144. }
  145. }
  146. }
  147. }
  148. for(std::vector<cmSourceFile*>::const_iterator i = newClasses.begin();
  149. i != newClasses.end(); ++i)
  150. {
  151. classes.push_back(*i);
  152. }
  153. // add in the project file itself
  154. if (projFile.size())
  155. {
  156. srcFilesToProcess.push(projFile);
  157. srcFilesQueued.insert(projFile);
  158. }
  159. // add in the library depends for custom targets
  160. if (this->GetType() == cmTarget::UTILITY || this->GetType() == cmTarget::GLOBAL_TARGET)
  161. {
  162. for (std::vector<cmCustomCommand>::iterator ic =
  163. this->GetPostBuildCommands().begin();
  164. ic != this->GetPostBuildCommands().end(); ++ic)
  165. {
  166. cmCustomCommand &c = *ic;
  167. for (std::vector<std::string>::const_iterator i = c.GetDepends().begin();
  168. i != c.GetDepends().end(); ++i)
  169. {
  170. srcFilesToProcess.push(*i);
  171. srcFilesQueued.insert(*i);
  172. }
  173. }
  174. }
  175. while (!srcFilesToProcess.empty())
  176. {
  177. // is this source the output of a custom command
  178. cmSourceFile* outsf =
  179. makefile->GetSourceFileWithOutput(srcFilesToProcess.front().c_str());
  180. if (outsf)
  181. {
  182. // is it not already in the target?
  183. if (std::find(classes.begin(),classes.end(),outsf) == classes.end())
  184. {
  185. // then add the source to this target and add it to the queue
  186. classes.push_back(outsf);
  187. name = outsf->GetSourceName();
  188. if (outsf->GetSourceExtension() != "rule")
  189. {
  190. name += ".";
  191. name += outsf->GetSourceExtension();
  192. }
  193. std::string temp =
  194. cmSystemTools::GetFilenamePath(outsf->GetFullPath());
  195. temp += "/";
  196. temp += name;
  197. // if it hasn't been processed
  198. if (srcFilesQueued.find(temp) == srcFilesQueued.end())
  199. {
  200. srcFilesToProcess.push(temp);
  201. srcFilesQueued.insert(temp);
  202. }
  203. }
  204. // add its dependencies to the list to check
  205. unsigned int i;
  206. for (i = 0; i < outsf->GetCustomCommand()->GetDepends().size(); ++i)
  207. {
  208. std::string dep = cmSystemTools::GetFilenameName(
  209. outsf->GetCustomCommand()->GetDepends()[i]);
  210. if (cmSystemTools::GetFilenameLastExtension(dep) == ".exe")
  211. {
  212. dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
  213. }
  214. // watch for target dependencies,
  215. if(m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, dep.c_str()))
  216. {
  217. // add the depend as a utility on the target
  218. this->AddUtility(dep.c_str());
  219. }
  220. else
  221. {
  222. if (srcFilesQueued.find(outsf->GetCustomCommand()->GetDepends()[i])
  223. == srcFilesQueued.end())
  224. {
  225. srcFilesToProcess.push(outsf->GetCustomCommand()->GetDepends()[i]);
  226. srcFilesQueued.insert(outsf->GetCustomCommand()->GetDepends()[i]);
  227. }
  228. }
  229. }
  230. }
  231. // finished with this SF move to the next
  232. srcFilesToProcess.pop();
  233. }
  234. // mark all custom commands in the targets list of source files as used.
  235. for(std::vector<cmSourceFile*>::iterator i = m_SourceFiles.begin();
  236. i != m_SourceFiles.end(); ++i)
  237. {
  238. cmCustomCommand* cc = (*i)->GetCustomCommand();
  239. if(cc)
  240. {
  241. cc->Used();
  242. }
  243. }
  244. }
  245. void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf)
  246. {
  247. // this is only done for non install targets
  248. if ((this->m_TargetType == cmTarget::INSTALL_FILES)
  249. || (this->m_TargetType == cmTarget::INSTALL_PROGRAMS))
  250. {
  251. return;
  252. }
  253. // for each src lists add the classes
  254. for (std::vector<std::string>::const_iterator s = m_SourceLists.begin();
  255. s != m_SourceLists.end(); ++s)
  256. {
  257. int done = 0;
  258. // replace any variables
  259. std::string temps = *s;
  260. mf.ExpandVariablesInString(temps);
  261. // Next if one wasn't found then assume it is a single class
  262. // check to see if it is an existing source file
  263. if (!done)
  264. {
  265. cmSourceFile* sourceFile = mf.GetSource(temps.c_str());
  266. if ( sourceFile )
  267. {
  268. m_SourceFiles.push_back(sourceFile);
  269. done = 1;
  270. }
  271. }
  272. // if we still are not done, try to create the SourceFile structure
  273. if (!done)
  274. {
  275. cmSourceFile file;
  276. file.SetProperty("ABSTRACT","0");
  277. file.SetName(temps.c_str(), mf.GetCurrentDirectory(),
  278. mf.GetSourceExtensions(),
  279. mf.GetHeaderExtensions());
  280. m_SourceFiles.push_back(mf.AddSource(file));
  281. }
  282. }
  283. // expand any link library variables whle we are at it
  284. LinkLibraries::iterator p = m_LinkLibraries.begin();
  285. for (;p != m_LinkLibraries.end(); ++p)
  286. {
  287. mf.ExpandVariablesInString(p->first, true, true);
  288. }
  289. }
  290. void cmTarget::MergeLinkLibraries( cmMakefile& mf,
  291. const char *selfname,
  292. const LinkLibraries& libs )
  293. {
  294. // Only add on libraries we haven't added on before.
  295. // Assumption: the global link libraries could only grow, never shrink
  296. LinkLibraries::const_iterator i = libs.begin();
  297. i += m_PrevLinkedLibraries.size();
  298. for( ; i != libs.end(); ++i )
  299. {
  300. // We call this so that the dependencies get written to the cache
  301. this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second );
  302. }
  303. m_PrevLinkedLibraries = libs;
  304. }
  305. //----------------------------------------------------------------------------
  306. void cmTarget::AddLinkDirectory(const char* d)
  307. {
  308. // Make sure we don't add unnecessary search directories.
  309. if(std::find(m_ExplicitLinkDirectories.begin(),
  310. m_ExplicitLinkDirectories.end(), d)
  311. == m_ExplicitLinkDirectories.end() )
  312. {
  313. m_ExplicitLinkDirectories.push_back( d );
  314. m_LinkDirectoriesComputed = false;
  315. }
  316. }
  317. //----------------------------------------------------------------------------
  318. const std::vector<std::string>& cmTarget::GetLinkDirectories()
  319. {
  320. // Make sure all library dependencies have been analyzed.
  321. if(!m_LinkLibrariesAnalyzed && !m_LinkLibraries.empty())
  322. {
  323. cmSystemTools::Error(
  324. "cmTarget::GetLinkDirectories called before cmTarget::AnalyzeLibDependencies on target ",
  325. m_Name.c_str());
  326. }
  327. // Make sure the complete set of link directories has been computed.
  328. if(!m_LinkDirectoriesComputed)
  329. {
  330. // Compute the full set of link directories including the
  331. // locations of targets that have been linked in. Start with the
  332. // link directories given explicitly.
  333. m_LinkDirectories = m_ExplicitLinkDirectories;
  334. for(LinkLibraries::iterator ll = m_LinkLibraries.begin();
  335. ll != m_LinkLibraries.end(); ++ll)
  336. {
  337. // If this library is a CMake target then add its location as a
  338. // link directory.
  339. std::string lib = ll->first;
  340. cmTarget* tgt = 0;
  341. if(m_Makefile && m_Makefile->GetLocalGenerator() &&
  342. m_Makefile->GetLocalGenerator()->GetGlobalGenerator())
  343. {
  344. tgt = (m_Makefile->GetLocalGenerator()->GetGlobalGenerator()
  345. ->FindTarget(0, lib.c_str()));
  346. }
  347. if(tgt)
  348. {
  349. // Add the directory only if it is not already present. This
  350. // is an N^2 algorithm for adding the directories, but N
  351. // should not get very big.
  352. const char* libpath = tgt->GetDirectory();
  353. if(std::find(m_LinkDirectories.begin(), m_LinkDirectories.end(),
  354. libpath) == m_LinkDirectories.end())
  355. {
  356. m_LinkDirectories.push_back(libpath);
  357. }
  358. }
  359. }
  360. // The complete set of link directories has now been computed.
  361. m_LinkDirectoriesComputed = true;
  362. }
  363. // Return the complete set of link directories.
  364. return m_LinkDirectories;
  365. }
  366. void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target )
  367. {
  368. // Clear the dependencies. The cache variable must exist iff we are
  369. // recording dependency information for this target.
  370. std::string depname = target;
  371. depname += "_LIB_DEPENDS";
  372. if (m_RecordDependencies)
  373. {
  374. mf.AddCacheDefinition(depname.c_str(), "",
  375. "Dependencies for target", cmCacheManager::STATIC);
  376. }
  377. else
  378. {
  379. if (mf.GetDefinition( depname.c_str() ))
  380. {
  381. std::string message = "Target ";
  382. message += target;
  383. message += " has dependency information when it shouldn't.\n";
  384. message += "Your cache is probably stale. Please remove the entry\n ";
  385. message += depname;
  386. message += "\nfrom the cache.";
  387. cmSystemTools::Error( message.c_str() );
  388. }
  389. }
  390. }
  391. void cmTarget::AddLinkLibrary(const std::string& lib,
  392. LinkLibraryType llt)
  393. {
  394. this->AddFramework(lib.c_str(), llt);
  395. m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
  396. }
  397. bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType llt)
  398. {
  399. (void)llt; // TODO: What is this?
  400. if(cmSystemTools::IsPathToFramework(libname.c_str()))
  401. {
  402. std::string frameworkDir = libname;
  403. frameworkDir += "/../";
  404. frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
  405. std::vector<std::string>::iterator i =
  406. std::find(m_Frameworks.begin(),
  407. m_Frameworks.end(), frameworkDir);
  408. if(i == m_Frameworks.end())
  409. {
  410. m_Frameworks.push_back(frameworkDir);
  411. }
  412. return true;
  413. }
  414. return false;
  415. }
  416. void cmTarget::AddLinkLibrary(cmMakefile& mf,
  417. const char *target, const char* lib,
  418. LinkLibraryType llt)
  419. {
  420. // Never add a self dependency, even if the user asks for it.
  421. if(strcmp( target, lib ) == 0)
  422. {
  423. return;
  424. }
  425. this->AddFramework(lib, llt);
  426. m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
  427. if(llt != cmTarget::GENERAL)
  428. {
  429. // Store the library's link type in the cache. If it is a
  430. // conflicting type then assume it is always used. This is the
  431. // case when the user sets the cache entries for debug and
  432. // optimized versions of the library to the same value.
  433. std::string linkTypeName = lib;
  434. linkTypeName += "_LINK_TYPE";
  435. switch(llt)
  436. {
  437. case cmTarget::DEBUG:
  438. {
  439. const char* def = mf.GetDefinition(linkTypeName.c_str());
  440. if(!def || strcmp(def, "debug") == 0)
  441. {
  442. mf.AddCacheDefinition(linkTypeName.c_str(),
  443. "debug", "Library is used for debug links only",
  444. cmCacheManager::STATIC);
  445. }
  446. else
  447. {
  448. mf.AddCacheDefinition(linkTypeName.c_str(),
  449. "general", "Library is used for both debug and optimized links",
  450. cmCacheManager::STATIC);
  451. }
  452. }
  453. break;
  454. case cmTarget::OPTIMIZED:
  455. {
  456. const char* def = mf.GetDefinition(linkTypeName.c_str());
  457. if(!def || strcmp(def, "optimized") == 0)
  458. {
  459. mf.AddCacheDefinition(linkTypeName.c_str(),
  460. "optimized", "Library is used for debug links only",
  461. cmCacheManager::STATIC);
  462. }
  463. else
  464. {
  465. mf.AddCacheDefinition(linkTypeName.c_str(),
  466. "general", "Library is used for both debug and optimized links",
  467. cmCacheManager::STATIC);
  468. }
  469. }
  470. break;
  471. case cmTarget::GENERAL:
  472. break;
  473. }
  474. }
  475. // Add the explicit dependency information for this target. This is
  476. // simply a set of libraries separated by ";". There should always
  477. // be a trailing ";". These library names are not canonical, in that
  478. // they may be "-framework x", "-ly", "/path/libz.a", etc.
  479. // We shouldn't remove duplicates here because external libraries
  480. // may be purposefully duplicated to handle recursive dependencies,
  481. // and we removing one instance will break the link line. Duplicates
  482. // will be appropriately eliminated at emit time.
  483. if(m_RecordDependencies)
  484. {
  485. std::string targetEntry = target;
  486. targetEntry += "_LIB_DEPENDS";
  487. std::string dependencies;
  488. const char* old_val = mf.GetDefinition( targetEntry.c_str() );
  489. if( old_val )
  490. {
  491. dependencies += old_val;
  492. }
  493. dependencies += lib;
  494. dependencies += ";";
  495. mf.AddCacheDefinition( targetEntry.c_str(), dependencies.c_str(),
  496. "Dependencies for the target",
  497. cmCacheManager::STATIC );
  498. }
  499. }
  500. void
  501. cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
  502. {
  503. // There are two key parts of the dependency analysis: (1)
  504. // determining the libraries in the link line, and (2) constructing
  505. // the dependency graph for those libraries.
  506. //
  507. // The latter is done using the cache entries that record the
  508. // dependencies of each library.
  509. //
  510. // The former is a more thorny issue, since it is not clear how to
  511. // determine if two libraries listed on the link line refer to the a
  512. // single library or not. For example, consider the link "libraries"
  513. // /usr/lib/libtiff.so -ltiff
  514. // Is this one library or two? The solution implemented here is the
  515. // simplest (and probably the only practical) one: two libraries are
  516. // the same if their "link strings" are identical. Thus, the two
  517. // libraries above are considered distinct. This also means that for
  518. // dependency analysis to be effective, the CMake user must specify
  519. // libraries build by his project without using any linker flags or
  520. // file extensions. That is,
  521. // LINK_LIBRARIES( One Two )
  522. // instead of
  523. // LINK_LIBRARIES( -lOne ${binarypath}/libTwo.a )
  524. // The former is probably what most users would do, but it never
  525. // hurts to document the assumptions. :-) Therefore, in the analysis
  526. // code, the "canonical name" of a library is simply its name as
  527. // given to a LINK_LIBRARIES command.
  528. //
  529. // Also, we will leave the original link line intact; we will just add any
  530. // dependencies that were missing.
  531. //
  532. // There is a problem with recursive external libraries
  533. // (i.e. libraries with no dependency information that are
  534. // recursively dependent). We must make sure that the we emit one of
  535. // the libraries twice to satisfy the recursion, but we shouldn't
  536. // emit it more times than necessary. In particular, we must make
  537. // sure that handling this improbable case doesn't cost us when
  538. // dealing with the common case of non-recursive libraries. The
  539. // solution is to assume that the recursion is satisfied at one node
  540. // of the dependency tree. To illustrate, assume libA and libB are
  541. // extrenal and mutually dependent. Suppose libX depends on
  542. // libA, and libY on libA and libX. Then
  543. // TARGET_LINK_LIBRARIES( Y X A B A )
  544. // TARGET_LINK_LIBRARIES( X A B A )
  545. // TARGET_LINK_LIBRARIES( Exec Y )
  546. // would result in "-lY -lX -lA -lB -lA". This is the correct way to
  547. // specify the dependencies, since the mutual dependency of A and B
  548. // is resolved *every time libA is specified*.
  549. //
  550. // Something like
  551. // TARGET_LINK_LIBRARIES( Y X A B A )
  552. // TARGET_LINK_LIBRARIES( X A B )
  553. // TARGET_LINK_LIBRARIES( Exec Y )
  554. // would result in "-lY -lX -lA -lB", and the mutual dependency
  555. // information is lost. This is because in some case (Y), the mutual
  556. // dependency of A and B is listed, while in another other case (X),
  557. // it is not. Depending on which line actually emits A, the mutual
  558. // dependency may or may not be on the final link line. We can't
  559. // handle this pathalogical case cleanly without emitting extra
  560. // libraries for the normal cases. Besides, the dependency
  561. // information for X is wrong anyway: if we build an executable
  562. // depending on X alone, we would not have the mutual dependency on
  563. // A and B resolved.
  564. //
  565. // IMPROVEMENTS:
  566. // -- The current algorithm will not always pick the "optimal" link line
  567. // when recursive dependencies are present. It will instead break the
  568. // cycles at an aribtrary point. The majority of projects won't have
  569. // cyclic dependencies, so this is probably not a big deal. Note that
  570. // the link line is always correct, just not necessary optimal.
  571. typedef std::vector< std::string > LinkLine;
  572. // The dependency map.
  573. DependencyMap dep_map;
  574. // 1. Build the dependency graph
  575. //
  576. for(LinkLibraries::reverse_iterator lib = m_LinkLibraries.rbegin();
  577. lib != m_LinkLibraries.rend(); ++lib)
  578. {
  579. this->GatherDependencies( mf, lib->first, dep_map );
  580. }
  581. // 2. Remove any dependencies that are already satisfied in the original
  582. // link line.
  583. //
  584. for(LinkLibraries::iterator lib = m_LinkLibraries.begin();
  585. lib != m_LinkLibraries.end(); ++lib)
  586. {
  587. for( LinkLibraries::iterator lib2 = lib;
  588. lib2 != m_LinkLibraries.end(); ++lib2)
  589. {
  590. DeleteDependency( dep_map, lib->first, lib2->first );
  591. }
  592. }
  593. // 3. Create the new link line by simply emitting any dependencies that are
  594. // missing. Start from the back and keep adding.
  595. //
  596. std::set<cmStdString> done, visited;
  597. std::vector<std::string> newLinkLibraries;
  598. for(LinkLibraries::reverse_iterator lib = m_LinkLibraries.rbegin();
  599. lib != m_LinkLibraries.rend(); ++lib)
  600. {
  601. // skip zero size library entries, this may happen
  602. // if a variable expands to nothing.
  603. if (lib->first.size() != 0)
  604. {
  605. Emit( lib->first, dep_map, done, visited, newLinkLibraries );
  606. }
  607. }
  608. // 4. Add the new libraries to the link line.
  609. //
  610. for( std::vector<std::string>::reverse_iterator k = newLinkLibraries.rbegin();
  611. k != newLinkLibraries.rend(); ++k )
  612. {
  613. std::string linkType = *k;
  614. linkType += "_LINK_TYPE";
  615. cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
  616. const char* linkTypeString = mf.GetDefinition( linkType.c_str() );
  617. if(linkTypeString)
  618. {
  619. if(strcmp(linkTypeString, "debug") == 0)
  620. {
  621. llt = cmTarget::DEBUG;
  622. }
  623. if(strcmp(linkTypeString, "optimized") == 0)
  624. {
  625. llt = cmTarget::OPTIMIZED;
  626. }
  627. }
  628. m_LinkLibraries.push_back( std::make_pair(*k,llt) );
  629. }
  630. m_LinkLibrariesAnalyzed = true;
  631. }
  632. void cmTarget::InsertDependency( DependencyMap& depMap,
  633. const cmStdString& lib,
  634. const cmStdString& dep )
  635. {
  636. depMap[lib].push_back(dep);
  637. }
  638. void cmTarget::DeleteDependency( DependencyMap& depMap,
  639. const cmStdString& lib,
  640. const cmStdString& dep )
  641. {
  642. // Make sure there is an entry in the map for lib. If so, delete all
  643. // dependencies to dep. There may be repeated entries because of
  644. // external libraries that are specified multiple times.
  645. DependencyMap::iterator map_itr = depMap.find( lib );
  646. if( map_itr != depMap.end() )
  647. {
  648. DependencyList& depList = map_itr->second;
  649. DependencyList::iterator itr;
  650. while( (itr = std::find(depList.begin(), depList.end(), dep)) != depList.end() )
  651. {
  652. depList.erase( itr );
  653. }
  654. }
  655. }
  656. void cmTarget::Emit( const std::string& lib,
  657. const DependencyMap& dep_map,
  658. std::set<cmStdString>& emitted,
  659. std::set<cmStdString>& visited,
  660. std::vector<std::string>& link_line )
  661. {
  662. // It's already been emitted
  663. if( emitted.find(lib) != emitted.end() )
  664. return;
  665. // Emit the dependencies only if this library node hasn't been
  666. // visited before. If it has, then we have a cycle. The recursion
  667. // that got us here should take care of everything.
  668. if( visited.insert(lib).second )
  669. {
  670. if( dep_map.find(lib) != dep_map.end() ) // does it have dependencies?
  671. {
  672. const DependencyList& dep_on = dep_map.find( lib )->second;
  673. DependencyList::const_reverse_iterator i;
  674. // To cater for recursive external libraries, we must emit
  675. // duplicates on this link line *unless* they were emitted by
  676. // some other node, in which case we assume that the recursion
  677. // was resolved then. We making the simplifying assumption that
  678. // any duplicates on a single link line are on purpose, and must
  679. // be preserved.
  680. // This variable will keep track of the libraries that were
  681. // emitted directory from the current node, and not from a
  682. // recursive call. This way, if we come across a library that
  683. // has already been emitted, we repeat it iff it has been
  684. // emitted here.
  685. std::set<cmStdString> emitted_here;
  686. for( i = dep_on.rbegin(); i != dep_on.rend(); ++i )
  687. {
  688. if( emitted_here.find(*i) != emitted_here.end() )
  689. {
  690. // a repeat. Must emit.
  691. emitted.insert(*i);
  692. link_line.push_back( *i );
  693. }
  694. else
  695. {
  696. // Emit only if no-one else has
  697. if( emitted.find(*i) == emitted.end() )
  698. {
  699. // emit dependencies
  700. Emit( *i, dep_map, emitted, visited, link_line );
  701. // emit self
  702. emitted.insert(*i);
  703. emitted_here.insert(*i);
  704. link_line.push_back( *i );
  705. }
  706. }
  707. }
  708. }
  709. }
  710. }
  711. void cmTarget::GatherDependencies( const cmMakefile& mf,
  712. const std::string& lib,
  713. DependencyMap& dep_map )
  714. {
  715. // If the library is already in the dependency map, then it has
  716. // already been fully processed.
  717. if( dep_map.find(lib) != dep_map.end() )
  718. return;
  719. const char* deps = mf.GetDefinition( (lib+"_LIB_DEPENDS").c_str() );
  720. if( deps && strcmp(deps,"") != 0 )
  721. {
  722. // Make sure this library is in the map, even if it has an empty
  723. // set of dependencies. This distinguishes the case of explicitly
  724. // no dependencies with that of unspecified dependencies.
  725. dep_map[lib];
  726. // Parse the dependency information, which is simply a set of
  727. // libraries separated by ";". There is always a trailing ";".
  728. std::string depline = deps;
  729. std::string::size_type start = 0;
  730. std::string::size_type end;
  731. end = depline.find( ";", start );
  732. while( end != std::string::npos )
  733. {
  734. std::string l = depline.substr( start, end-start );
  735. if( l.size() != 0 )
  736. {
  737. InsertDependency( dep_map, lib, l );
  738. GatherDependencies( mf, l, dep_map );
  739. }
  740. start = end+1; // skip the ;
  741. end = depline.find( ";", start );
  742. }
  743. DeleteDependency( dep_map, lib, lib); // cannot depend on itself
  744. }
  745. }
  746. void cmTarget::SetProperty(const char* prop, const char* value)
  747. {
  748. if (!prop)
  749. {
  750. return;
  751. }
  752. if (!value)
  753. {
  754. value = "NOTFOUND";
  755. }
  756. m_Properties[prop] = value;
  757. }
  758. const char* cmTarget::GetDirectory(const char* config)
  759. {
  760. switch( this->GetType() )
  761. {
  762. case cmTarget::STATIC_LIBRARY:
  763. case cmTarget::MODULE_LIBRARY:
  764. case cmTarget::SHARED_LIBRARY:
  765. m_Directory = m_Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
  766. break;
  767. case cmTarget::EXECUTABLE:
  768. m_Directory = m_Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
  769. break;
  770. default:
  771. return 0;
  772. }
  773. if(m_Directory.empty())
  774. {
  775. m_Directory = m_Makefile->GetStartOutputDirectory();
  776. }
  777. if(config)
  778. {
  779. // Add the configuration's subdirectory.
  780. m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->
  781. AppendDirectoryForConfig("/", config, "", m_Directory);
  782. }
  783. return m_Directory.c_str();
  784. }
  785. const char* cmTarget::GetLocation(const char* config)
  786. {
  787. m_Location = this->GetDirectory();
  788. if(!m_Location.empty())
  789. {
  790. m_Location += "/";
  791. }
  792. const char* cfgid = m_Makefile->GetDefinition("CMAKE_CFG_INTDIR");
  793. if(cfgid && strcmp(cfgid, ".") != 0)
  794. {
  795. m_Location += cfgid;
  796. m_Location += "/";
  797. }
  798. m_Location += this->GetFullName(config, false);
  799. return m_Location.c_str();
  800. }
  801. void cmTarget::UpdateLocation()
  802. {
  803. // make sure we have a makefile
  804. if (!m_Makefile)
  805. {
  806. return;
  807. }
  808. // set the LOCATION property of the target
  809. std::string target_location;
  810. switch( this->GetType() )
  811. {
  812. case cmTarget::STATIC_LIBRARY:
  813. case cmTarget::MODULE_LIBRARY:
  814. case cmTarget::SHARED_LIBRARY:
  815. target_location =
  816. m_Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
  817. break;
  818. case cmTarget::EXECUTABLE:
  819. target_location =
  820. m_Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
  821. break;
  822. default:
  823. return;
  824. }
  825. if ( target_location.size() == 0 )
  826. {
  827. target_location += m_Makefile->GetStartOutputDirectory();
  828. }
  829. if ( target_location.size() > 0 )
  830. {
  831. target_location += "/";
  832. }
  833. const char* cfgid = m_Makefile->GetDefinition("CMAKE_CFG_INTDIR");
  834. if ( cfgid && strcmp(cfgid, ".") != 0 )
  835. {
  836. target_location += cfgid;
  837. target_location += "/";
  838. }
  839. target_location += this->GetFullName();
  840. this->SetProperty("LOCATION",target_location.c_str());
  841. }
  842. const char *cmTarget::GetProperty(const char* prop)
  843. {
  844. // watch for special "computed" properties that are dependent on other
  845. // properties or variables, always recompute them
  846. if (!strcmp(prop,"LOCATION"))
  847. {
  848. this->UpdateLocation();
  849. }
  850. // the type property returns what type the target is
  851. if (!strcmp(prop,"TYPE"))
  852. {
  853. switch( this->GetType() )
  854. {
  855. case cmTarget::STATIC_LIBRARY:
  856. return "STATIC_LIBRARY";
  857. break;
  858. case cmTarget::MODULE_LIBRARY:
  859. return "MODULE_LIBRARY";
  860. break;
  861. case cmTarget::SHARED_LIBRARY:
  862. return "SHARED_LIBRARY";
  863. break;
  864. case cmTarget::EXECUTABLE:
  865. return "EXECUTABLE";
  866. break;
  867. case cmTarget::UTILITY:
  868. return "UTILITY";
  869. break;
  870. case cmTarget::GLOBAL_TARGET:
  871. return "GLOBAL_TARGET";
  872. break;
  873. case cmTarget::INSTALL_FILES:
  874. return "INSTALL_FILES";
  875. break;
  876. case cmTarget::INSTALL_PROGRAMS:
  877. return "INSTALL_PROGRAMS";
  878. break;
  879. }
  880. return 0;
  881. }
  882. std::map<cmStdString,cmStdString>::const_iterator i =
  883. m_Properties.find(prop);
  884. if (i != m_Properties.end())
  885. {
  886. return i->second.c_str();
  887. }
  888. return 0;
  889. }
  890. bool cmTarget::GetPropertyAsBool(const char* prop)
  891. {
  892. std::map<cmStdString,cmStdString>::const_iterator i =
  893. m_Properties.find(prop);
  894. if (i != m_Properties.end())
  895. {
  896. return cmSystemTools::IsOn(i->second.c_str());
  897. }
  898. return false;
  899. }
  900. const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg)
  901. {
  902. if(this->GetProperty("HAS_CXX"))
  903. {
  904. const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX");
  905. }
  906. const char* linkerLang = this->GetProperty("LINKER_LANGUAGE");
  907. if(linkerLang)
  908. {
  909. return linkerLang;
  910. }
  911. std::set<cmStdString> languages;
  912. for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin();
  913. i != m_SourceFiles.end(); ++i)
  914. {
  915. const char* lang =
  916. gg->GetLanguageFromExtension((*i)->GetSourceExtension().c_str());
  917. if(lang)
  918. {
  919. languages.insert(lang);
  920. }
  921. }
  922. if(languages.size() == 0)
  923. {
  924. return 0;
  925. }
  926. if(languages.size() == 1)
  927. {
  928. const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", languages.begin()->c_str());
  929. return this->GetProperty("LINKER_LANGUAGE");
  930. }
  931. const char* prefLang = 0;
  932. for(std::set<cmStdString>::const_iterator s = languages.begin();
  933. s != languages.end(); ++s)
  934. {
  935. const char* lpref = gg->GetLinkerPreference(s->c_str());
  936. if(lpref[0] == 'P')
  937. {
  938. if(prefLang && !(*s == prefLang))
  939. {
  940. std::string m = "Error Target: ";
  941. m += m_Name + " Contains more than one Prefered language: ";
  942. m += *s;
  943. m += " and ";
  944. m += prefLang;
  945. m += "\nYou must set the LINKER_LANGUAGE property for this target.";
  946. cmSystemTools::Error(m.c_str());
  947. }
  948. else
  949. {
  950. prefLang = s->c_str();
  951. }
  952. }
  953. }
  954. if(!prefLang)
  955. {
  956. prefLang = languages.begin()->c_str();
  957. }
  958. const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", prefLang);
  959. return this->GetProperty("LINKER_LANGUAGE");
  960. }
  961. const char* cmTarget::GetCreateRuleVariable()
  962. {
  963. switch(this->GetType())
  964. {
  965. case cmTarget::STATIC_LIBRARY:
  966. return "_CREATE_STATIC_LIBRARY";
  967. case cmTarget::SHARED_LIBRARY:
  968. return "_CREATE_SHARED_LIBRARY";
  969. case cmTarget::MODULE_LIBRARY:
  970. return "_CREATE_SHARED_MODULE";
  971. case cmTarget::EXECUTABLE:
  972. return "_LINK_EXECUTABLE";
  973. case cmTarget::UTILITY:
  974. case cmTarget::GLOBAL_TARGET:
  975. case cmTarget::INSTALL_FILES:
  976. case cmTarget::INSTALL_PROGRAMS:
  977. break;
  978. }
  979. return "";
  980. }
  981. const char* cmTarget::GetSuffixVariableInternal(TargetType type,
  982. bool implib)
  983. {
  984. switch(type)
  985. {
  986. case cmTarget::STATIC_LIBRARY:
  987. return "CMAKE_STATIC_LIBRARY_SUFFIX";
  988. case cmTarget::SHARED_LIBRARY:
  989. return (implib
  990. ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
  991. : "CMAKE_SHARED_LIBRARY_SUFFIX");
  992. case cmTarget::MODULE_LIBRARY:
  993. return "CMAKE_SHARED_MODULE_SUFFIX";
  994. case cmTarget::EXECUTABLE:
  995. return "CMAKE_EXECUTABLE_SUFFIX";
  996. case cmTarget::UTILITY:
  997. case cmTarget::GLOBAL_TARGET:
  998. case cmTarget::INSTALL_FILES:
  999. case cmTarget::INSTALL_PROGRAMS:
  1000. break;
  1001. }
  1002. return "";
  1003. }
  1004. const char* cmTarget::GetPrefixVariableInternal(TargetType type,
  1005. bool implib)
  1006. {
  1007. switch(type)
  1008. {
  1009. case cmTarget::STATIC_LIBRARY:
  1010. return "CMAKE_STATIC_LIBRARY_PREFIX";
  1011. case cmTarget::SHARED_LIBRARY:
  1012. return (implib
  1013. ? "CMAKE_IMPORT_LIBRARY_PREFIX"
  1014. : "CMAKE_SHARED_LIBRARY_PREFIX");
  1015. case cmTarget::MODULE_LIBRARY:
  1016. return "CMAKE_SHARED_MODULE_PREFIX";
  1017. case cmTarget::EXECUTABLE:
  1018. case cmTarget::UTILITY:
  1019. case cmTarget::GLOBAL_TARGET:
  1020. case cmTarget::INSTALL_FILES:
  1021. case cmTarget::INSTALL_PROGRAMS:
  1022. break;
  1023. }
  1024. return "";
  1025. }
  1026. //----------------------------------------------------------------------------
  1027. std::string cmTarget::GetFullName(const char* config, bool implib)
  1028. {
  1029. return this->GetFullNameInternal(this->GetType(), config, implib);
  1030. }
  1031. //----------------------------------------------------------------------------
  1032. void cmTarget::GetFullName(std::string& prefix, std::string& base,
  1033. std::string& suffix, const char* config,
  1034. bool implib)
  1035. {
  1036. this->GetFullNameInternal(this->GetType(), config, implib,
  1037. prefix, base, suffix);
  1038. }
  1039. //----------------------------------------------------------------------------
  1040. std::string cmTarget::GetFullPath(const char* config, bool implib)
  1041. {
  1042. // Start with the output directory for the target.
  1043. std::string fpath = this->GetDirectory(config);
  1044. fpath += "/";
  1045. // Add the full name of the target.
  1046. fpath += this->GetFullName(config, implib);
  1047. return fpath;
  1048. }
  1049. //----------------------------------------------------------------------------
  1050. std::string cmTarget::GetFullNameInternal(TargetType type, const char* config,
  1051. bool implib)
  1052. {
  1053. std::string prefix;
  1054. std::string base;
  1055. std::string suffix;
  1056. this->GetFullNameInternal(type, config, implib, prefix, base, suffix);
  1057. return prefix+base+suffix;
  1058. }
  1059. //----------------------------------------------------------------------------
  1060. void cmTarget::GetFullNameInternal(TargetType type,
  1061. const char* config,
  1062. bool implib,
  1063. std::string& outPrefix,
  1064. std::string& outBase,
  1065. std::string& outSuffix)
  1066. {
  1067. // Use just the target name for non-main target types.
  1068. if(type != cmTarget::STATIC_LIBRARY &&
  1069. type != cmTarget::SHARED_LIBRARY &&
  1070. type != cmTarget::MODULE_LIBRARY &&
  1071. type != cmTarget::EXECUTABLE)
  1072. {
  1073. outPrefix = "";
  1074. outBase = this->GetName();
  1075. outSuffix = "";
  1076. return;
  1077. }
  1078. // The implib option is only allowed for shared libraries.
  1079. if(type != cmTarget::SHARED_LIBRARY)
  1080. {
  1081. implib = false;
  1082. }
  1083. // Compute the full name for main target types.
  1084. const char* targetPrefix = (implib
  1085. ? this->GetProperty("IMPORT_PREFIX")
  1086. : this->GetProperty("PREFIX"));
  1087. const char* targetSuffix = (implib
  1088. ? this->GetProperty("IMPORT_SUFFIX")
  1089. : this->GetProperty("SUFFIX"));
  1090. const char* configPostfix = 0;
  1091. if(config && *config)
  1092. {
  1093. std::string configProp = cmSystemTools::UpperCase(config);
  1094. configProp += "_POSTFIX";
  1095. configPostfix = this->GetProperty(configProp.c_str());
  1096. }
  1097. const char* prefixVar = this->GetPrefixVariableInternal(type, implib);
  1098. const char* suffixVar = this->GetSuffixVariableInternal(type, implib);
  1099. const char* ll =
  1100. this->GetLinkerLanguage(
  1101. m_Makefile->GetLocalGenerator()->GetGlobalGenerator());
  1102. // first try language specific suffix
  1103. if(ll)
  1104. {
  1105. if(!targetSuffix && suffixVar && *suffixVar)
  1106. {
  1107. std::string langSuff = suffixVar + std::string("_") + ll;
  1108. targetSuffix = m_Makefile->GetDefinition(langSuff.c_str());
  1109. }
  1110. if(!targetPrefix && prefixVar && *prefixVar)
  1111. {
  1112. std::string langPrefix = prefixVar + std::string("_") + ll;
  1113. targetPrefix = m_Makefile->GetDefinition(langPrefix.c_str());
  1114. }
  1115. }
  1116. // if there is no prefix on the target use the cmake definition
  1117. if(!targetPrefix && prefixVar)
  1118. {
  1119. targetPrefix = m_Makefile->GetSafeDefinition(prefixVar);
  1120. }
  1121. // if there is no suffix on the target use the cmake definition
  1122. if(!targetSuffix && suffixVar)
  1123. {
  1124. targetSuffix = m_Makefile->GetSafeDefinition(suffixVar);
  1125. }
  1126. // Begin the final name with the prefix.
  1127. outPrefix = targetPrefix?targetPrefix:"";
  1128. // Append the target name or property-specified name.
  1129. if(const char* outname = this->GetProperty("OUTPUT_NAME"))
  1130. {
  1131. outBase = outname;
  1132. }
  1133. else
  1134. {
  1135. outBase = this->GetName();
  1136. }
  1137. // Append the per-configuration postfix.
  1138. outBase += configPostfix?configPostfix:"";
  1139. // Append the suffix.
  1140. outSuffix = targetSuffix?targetSuffix:"";
  1141. }
  1142. void cmTarget::GetLibraryNames(std::string& name,
  1143. std::string& soName,
  1144. std::string& realName,
  1145. std::string& impName,
  1146. const char* config)
  1147. {
  1148. // Get the names based on the real type of the library.
  1149. this->GetLibraryNamesInternal(name, soName, realName, impName,
  1150. this->GetType(), config);
  1151. }
  1152. void cmTarget::GetLibraryCleanNames(std::string& staticName,
  1153. std::string& sharedName,
  1154. std::string& sharedSOName,
  1155. std::string& sharedRealName,
  1156. std::string& importName,
  1157. const char* config)
  1158. {
  1159. // Get the name as if this were a static library.
  1160. std::string soName;
  1161. std::string realName;
  1162. std::string impName;
  1163. this->GetLibraryNamesInternal(staticName, soName, realName, impName,
  1164. cmTarget::STATIC_LIBRARY, config);
  1165. // Get the names as if this were a shared library.
  1166. if(this->GetType() == cmTarget::STATIC_LIBRARY)
  1167. {
  1168. // Since the real type is static then the user either specified
  1169. // STATIC or did not specify a type. In the former case the
  1170. // shared library will never be present. In the latter case the
  1171. // type will never be MODULE. Either way the only names that
  1172. // might have to be cleaned are the shared library names.
  1173. this->GetLibraryNamesInternal(sharedName, sharedSOName, sharedRealName,
  1174. importName, cmTarget::SHARED_LIBRARY,
  1175. config);
  1176. }
  1177. else
  1178. {
  1179. // Use the name of the real type of the library (shared or module).
  1180. this->GetLibraryNamesInternal(sharedName, sharedSOName, sharedRealName,
  1181. importName, this->GetType(), config);
  1182. }
  1183. }
  1184. void cmTarget::GetLibraryNamesInternal(std::string& name,
  1185. std::string& soName,
  1186. std::string& realName,
  1187. std::string& impName,
  1188. TargetType type,
  1189. const char* config)
  1190. {
  1191. // Construct the name of the soname flag variable for this language.
  1192. const char* ll =
  1193. this->GetLinkerLanguage(
  1194. m_Makefile->GetLocalGenerator()->GetGlobalGenerator());
  1195. std::string sonameFlag = "CMAKE_SHARED_LIBRARY_SONAME";
  1196. if(ll)
  1197. {
  1198. sonameFlag += "_";
  1199. sonameFlag += ll;
  1200. }
  1201. sonameFlag += "_FLAG";
  1202. // Check for library version properties.
  1203. const char* version = this->GetProperty("VERSION");
  1204. const char* soversion = this->GetProperty("SOVERSION");
  1205. if((type != cmTarget::SHARED_LIBRARY && type != cmTarget::MODULE_LIBRARY) ||
  1206. !m_Makefile->GetDefinition(sonameFlag.c_str()))
  1207. {
  1208. // Versioning is supported only for shared libraries and modules,
  1209. // and then only when the platform supports an soname flag.
  1210. version = 0;
  1211. soversion = 0;
  1212. }
  1213. if(version && !soversion)
  1214. {
  1215. // The soversion must be set if the library version is set. Use
  1216. // the library version as the soversion.
  1217. soversion = version;
  1218. }
  1219. // The library name.
  1220. name = this->GetFullNameInternal(type, config, false);
  1221. // The library's soname.
  1222. soName = name;
  1223. if(soversion)
  1224. {
  1225. soName += ".";
  1226. soName += soversion;
  1227. }
  1228. // The library's real name on disk.
  1229. realName = name;
  1230. if(version)
  1231. {
  1232. realName += ".";
  1233. realName += version;
  1234. }
  1235. else if(soversion)
  1236. {
  1237. realName += ".";
  1238. realName += soversion;
  1239. }
  1240. // The import library name.
  1241. if(type == cmTarget::SHARED_LIBRARY)
  1242. {
  1243. impName = this->GetFullNameInternal(type, config, true);
  1244. }
  1245. else
  1246. {
  1247. impName = "";
  1248. }
  1249. }
  1250. void cmTarget::GetExecutableNames(std::string& name,
  1251. std::string& realName,
  1252. const char* config)
  1253. {
  1254. // Get the names based on the real type of the executable.
  1255. this->GetExecutableNamesInternal(name, realName, this->GetType(), config);
  1256. }
  1257. void cmTarget::GetExecutableCleanNames(std::string& name,
  1258. std::string& realName,
  1259. const char* config)
  1260. {
  1261. // Get the name and versioned name of this executable.
  1262. this->GetExecutableNamesInternal(name, realName, cmTarget::EXECUTABLE,
  1263. config);
  1264. }
  1265. void cmTarget::GetExecutableNamesInternal(std::string& name,
  1266. std::string& realName,
  1267. TargetType type,
  1268. const char* config)
  1269. {
  1270. // This versioning is supported only for executables and then only
  1271. // when the platform supports symbolic links.
  1272. #if defined(_WIN32) && !defined(__CYGWIN__)
  1273. const char* version = 0;
  1274. #else
  1275. // Check for executable version properties.
  1276. const char* version = this->GetProperty("VERSION");
  1277. if(type != cmTarget::EXECUTABLE)
  1278. {
  1279. version = 0;
  1280. }
  1281. #endif
  1282. // The executable name.
  1283. name = this->GetFullNameInternal(type, config, false);
  1284. // The executable's real name on disk.
  1285. realName = name;
  1286. if(version)
  1287. {
  1288. realName += "-";
  1289. realName += version;
  1290. }
  1291. }
  1292. //----------------------------------------------------------------------------
  1293. void cmTarget::SetPropertyDefault(const char* property,
  1294. const char* default_value)
  1295. {
  1296. // Compute the name of the variable holding the default value.
  1297. std::string var = "CMAKE_";
  1298. var += property;
  1299. if(const char* value = m_Makefile->GetDefinition(var.c_str()))
  1300. {
  1301. this->SetProperty(property, value);
  1302. }
  1303. else if(default_value)
  1304. {
  1305. this->SetProperty(property, default_value);
  1306. }
  1307. }
  1308. //----------------------------------------------------------------------------
  1309. bool cmTarget::HaveBuildTreeRPATH()
  1310. {
  1311. return (!this->GetPropertyAsBool("SKIP_BUILD_RPATH") &&
  1312. !m_LinkLibraries.empty());
  1313. }
  1314. //----------------------------------------------------------------------------
  1315. bool cmTarget::HaveInstallTreeRPATH()
  1316. {
  1317. const char* install_rpath = this->GetProperty("INSTALL_RPATH");
  1318. return install_rpath && *install_rpath;
  1319. }
  1320. //----------------------------------------------------------------------------
  1321. bool cmTarget::NeedRelinkBeforeInstall()
  1322. {
  1323. // Only executables and shared libraries can have an rpath and may
  1324. // need relinking.
  1325. if(m_TargetType != cmTarget::EXECUTABLE &&
  1326. m_TargetType != cmTarget::SHARED_LIBRARY &&
  1327. m_TargetType != cmTarget::MODULE_LIBRARY)
  1328. {
  1329. return false;
  1330. }
  1331. // If there is no install location this target will not be installed
  1332. // and therefore does not need relinking.
  1333. if(!this->GetHaveInstallRule())
  1334. {
  1335. return false;
  1336. }
  1337. // If skipping all rpaths completely then no relinking is needed.
  1338. if(m_Makefile->IsOn("CMAKE_SKIP_RPATH"))
  1339. {
  1340. return false;
  1341. }
  1342. // If building with the install-tree rpath no relinking is needed.
  1343. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
  1344. {
  1345. return false;
  1346. }
  1347. // Check for rpath support on this platform.
  1348. if(const char* ll = this->GetLinkerLanguage(
  1349. m_Makefile->GetLocalGenerator()->GetGlobalGenerator()))
  1350. {
  1351. std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
  1352. flagVar += ll;
  1353. flagVar += "_FLAG";
  1354. if(!m_Makefile->IsSet(flagVar.c_str()))
  1355. {
  1356. // There is no rpath support on this platform so nothing needs
  1357. // relinking.
  1358. return false;
  1359. }
  1360. }
  1361. else
  1362. {
  1363. // No linker language is known. This error will be reported by
  1364. // other code.
  1365. return false;
  1366. }
  1367. // If either a build or install tree rpath is set then the rpath
  1368. // will likely change between the build tree and install tree and
  1369. // this target must be relinked.
  1370. return this->HaveBuildTreeRPATH() || this->HaveInstallTreeRPATH();
  1371. }
  1372. //----------------------------------------------------------------------------
  1373. std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
  1374. {
  1375. // If building directly for installation then the build tree install_name
  1376. // is the same as the install tree.
  1377. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
  1378. {
  1379. return GetInstallNameDirForInstallTree(config);
  1380. }
  1381. // Use the build tree directory for the target.
  1382. if(m_Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
  1383. !m_Makefile->IsOn("CMAKE_SKIP_RPATH") &&
  1384. !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
  1385. {
  1386. std::string dir = this->GetDirectory(config);
  1387. dir += "/";
  1388. return dir;
  1389. }
  1390. else
  1391. {
  1392. return "";
  1393. }
  1394. }
  1395. //----------------------------------------------------------------------------
  1396. std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
  1397. {
  1398. // Lookup the target property.
  1399. const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
  1400. if(m_Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
  1401. !m_Makefile->IsOn("CMAKE_SKIP_RPATH") &&
  1402. install_name_dir && *install_name_dir)
  1403. {
  1404. std::string dir = install_name_dir;
  1405. dir += "/";
  1406. return dir;
  1407. }
  1408. else
  1409. {
  1410. return "";
  1411. }
  1412. }