cmOrderLinkDirectories.cxx 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. #include "cmOrderLinkDirectories.h"
  2. #include "cmSystemTools.h"
  3. #include "cmsys/RegularExpression.hxx"
  4. #include <ctype.h>
  5. //#define CM_ORDER_LINK_DIRECTORIES_DEBUG
  6. //-------------------------------------------------------------------
  7. cmOrderLinkDirectories::cmOrderLinkDirectories()
  8. {
  9. this->StartLinkType = LinkUnknown;
  10. this->LinkTypeEnabled = false;
  11. this->Debug = false;
  12. }
  13. //-------------------------------------------------------------------
  14. void
  15. cmOrderLinkDirectories
  16. ::SetLinkTypeInformation(LinkType start_link_type,
  17. const char* static_link_type_flag,
  18. const char* shared_link_type_flag)
  19. {
  20. // We can support link type switching only if all needed flags are
  21. // known.
  22. this->StartLinkType = start_link_type;
  23. if(static_link_type_flag && *static_link_type_flag &&
  24. shared_link_type_flag && *shared_link_type_flag)
  25. {
  26. this->LinkTypeEnabled = true;
  27. this->StaticLinkTypeFlag = static_link_type_flag;
  28. this->SharedLinkTypeFlag = shared_link_type_flag;
  29. }
  30. else
  31. {
  32. this->LinkTypeEnabled = false;
  33. this->StaticLinkTypeFlag = "";
  34. this->SharedLinkTypeFlag = "";
  35. }
  36. }
  37. //-------------------------------------------------------------------
  38. void cmOrderLinkDirectories::SetCurrentLinkType(LinkType lt)
  39. {
  40. if(this->CurrentLinkType != lt)
  41. {
  42. this->CurrentLinkType = lt;
  43. if(this->LinkTypeEnabled)
  44. {
  45. switch(this->CurrentLinkType)
  46. {
  47. case LinkStatic:
  48. this->LinkItems.push_back(this->StaticLinkTypeFlag); break;
  49. case LinkShared:
  50. this->LinkItems.push_back(this->SharedLinkTypeFlag); break;
  51. default: break;
  52. }
  53. }
  54. }
  55. }
  56. //-------------------------------------------------------------------
  57. bool cmOrderLinkDirectories::LibraryInDirectory(const char* desiredLib,
  58. const char* dir,
  59. const char* libIn)
  60. {
  61. // first look for the library as given
  62. if(this->LibraryMayConflict(desiredLib, dir, libIn))
  63. {
  64. return true;
  65. }
  66. // next remove the extension (.a, .so ) and look for the library
  67. // under a different name as the linker can do either
  68. if(this->RemoveLibraryExtension.find(libIn))
  69. {
  70. cmStdString lib = this->RemoveLibraryExtension.match(1);
  71. cmStdString ext = this->RemoveLibraryExtension.match(2);
  72. for(std::vector<cmStdString>::iterator i = this->LinkExtensions.begin();
  73. i != this->LinkExtensions.end(); ++i)
  74. {
  75. if(ext != *i)
  76. {
  77. std::string fname = lib;
  78. lib += *i;
  79. if(this->LibraryMayConflict(desiredLib, dir, fname.c_str()))
  80. {
  81. return true;
  82. }
  83. }
  84. }
  85. }
  86. return false;
  87. }
  88. //-------------------------------------------------------------------
  89. void cmOrderLinkDirectories::FindLibrariesInSearchPaths()
  90. {
  91. for(std::set<cmStdString>::iterator dir = this->LinkPathSet.begin();
  92. dir != this->LinkPathSet.end(); ++dir)
  93. {
  94. for(std::map<cmStdString, Library>::iterator lib
  95. = this->FullPathLibraries.begin();
  96. lib != this->FullPathLibraries.end(); ++lib)
  97. {
  98. if(lib->second.Path != *dir)
  99. {
  100. if(this->LibraryInDirectory(lib->second.FullPath.c_str(),
  101. dir->c_str(), lib->second.File.c_str()))
  102. {
  103. this->LibraryToDirectories[lib->second.FullPath].push_back(*dir);
  104. }
  105. }
  106. }
  107. }
  108. }
  109. //-------------------------------------------------------------------
  110. void cmOrderLinkDirectories::FindIndividualLibraryOrders()
  111. {
  112. for(std::vector<Library>::iterator lib =
  113. this->MultiDirectoryLibraries.begin();
  114. lib != this->MultiDirectoryLibraries.end(); ++lib)
  115. {
  116. std::vector<cmStdString>& dirs =
  117. this->LibraryToDirectories[lib->FullPath];
  118. std::vector<std::pair<cmStdString, std::vector<cmStdString> >
  119. >::iterator i;
  120. for(i = this->DirectoryToAfterList.begin();
  121. i != this->DirectoryToAfterList.end(); ++i)
  122. {
  123. if(i->first == lib->Path)
  124. {
  125. break;
  126. }
  127. }
  128. if(i == this->DirectoryToAfterList.end())
  129. {
  130. std::cerr << "ERROR: should not happen\n";
  131. }
  132. else
  133. {
  134. for(std::vector<cmStdString>::iterator d = dirs.begin();
  135. d != dirs.end(); ++d)
  136. {
  137. i->second.push_back(*d);
  138. }
  139. }
  140. }
  141. }
  142. //-------------------------------------------------------------------
  143. std::string cmOrderLinkDirectories::NoCaseExpression(const char* str)
  144. {
  145. std::string ret;
  146. const char* s = str;
  147. while(*s)
  148. {
  149. if(*s == '.')
  150. {
  151. ret += *s;
  152. }
  153. else
  154. {
  155. ret += "[";
  156. ret += tolower(*s);
  157. ret += toupper(*s);
  158. ret += "]";
  159. }
  160. s++;
  161. }
  162. return ret;
  163. }
  164. //-------------------------------------------------------------------
  165. void cmOrderLinkDirectories::CreateRegularExpressions()
  166. {
  167. this->SplitFramework.compile("(.*)/(.*)\\.framework$");
  168. // Compute a regex to match link extensions.
  169. cmStdString libext = this->CreateExtensionRegex(this->LinkExtensions);
  170. // Create regex to remove any library extension.
  171. cmStdString reg("(.*)");
  172. reg += libext;
  173. this->RemoveLibraryExtension.compile(reg.c_str());
  174. // Create a regex to match a library name. Match index 1 will be
  175. // the prefix if it exists and empty otherwise. Match index 2 will
  176. // be the library name. Match index 3 will be the library
  177. // extension.
  178. reg = "^(";
  179. for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
  180. p != this->LinkPrefixes.end(); ++p)
  181. {
  182. reg += *p;
  183. reg += "|";
  184. }
  185. reg += ")";
  186. reg += "([^/]*)";
  187. // Create a regex to match any library name.
  188. cmStdString reg_any = reg;
  189. reg_any += libext;
  190. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  191. fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
  192. #endif
  193. this->ExtractAnyLibraryName.compile(reg_any.c_str());
  194. // Create a regex to match static library names.
  195. if(!this->StaticLinkExtensions.empty())
  196. {
  197. cmStdString reg_static = reg;
  198. reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
  199. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  200. fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
  201. #endif
  202. this->ExtractStaticLibraryName.compile(reg_static.c_str());
  203. }
  204. // Create a regex to match shared library names.
  205. if(!this->SharedLinkExtensions.empty())
  206. {
  207. cmStdString reg_shared = reg;
  208. reg_shared += this->CreateExtensionRegex(this->SharedLinkExtensions);
  209. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  210. fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
  211. #endif
  212. this->ExtractSharedLibraryName.compile(reg_shared.c_str());
  213. }
  214. }
  215. //-------------------------------------------------------------------
  216. std::string
  217. cmOrderLinkDirectories::CreateExtensionRegex(
  218. std::vector<cmStdString> const& exts)
  219. {
  220. // Build a list of extension choices.
  221. cmStdString libext = "(";
  222. const char* sep = "";
  223. for(std::vector<cmStdString>::const_iterator i = exts.begin();
  224. i != exts.end(); ++i)
  225. {
  226. // Separate this choice from the previous one.
  227. libext += sep;
  228. sep = "|";
  229. // Store this extension choice with the "." escaped.
  230. libext += "\\";
  231. #if defined(_WIN32) && !defined(__CYGWIN__)
  232. libext += this->NoCaseExpression(i->c_str());
  233. #else
  234. libext += *i;
  235. #endif
  236. }
  237. // Finish the list.
  238. libext += ").*";
  239. return libext;
  240. }
  241. //-------------------------------------------------------------------
  242. void cmOrderLinkDirectories::PrepareLinkTargets()
  243. {
  244. std::vector<cmStdString> originalLinkItems = this->LinkItems;
  245. this->LinkItems.clear();
  246. this->CurrentLinkType = this->StartLinkType;
  247. for(std::vector<cmStdString>::iterator i = originalLinkItems.begin();
  248. i != originalLinkItems.end(); ++i)
  249. {
  250. // Parse out the prefix, base, and suffix components of the
  251. // library name. If the name matches that of a shared or static
  252. // library then set the link type accordingly.
  253. //
  254. // Search for shared library names first because some platforms
  255. // have shared libraries with names that match the static library
  256. // pattern. For example cygwin and msys use the convention
  257. // libfoo.dll.a for import libraries and libfoo.a for static
  258. // libraries. On AIX a library with the name libfoo.a can be
  259. // shared!
  260. if(this->ExtractSharedLibraryName.find(*i))
  261. {
  262. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  263. fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
  264. this->ExtractSharedLibraryName.match(1).c_str(),
  265. this->ExtractSharedLibraryName.match(2).c_str(),
  266. this->ExtractSharedLibraryName.match(3).c_str());
  267. #endif
  268. this->SetCurrentLinkType(LinkShared);
  269. this->LinkItems.push_back(this->ExtractSharedLibraryName.match(2));
  270. }
  271. else if(this->ExtractStaticLibraryName.find(*i))
  272. {
  273. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  274. fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
  275. this->ExtractStaticLibraryName.match(1).c_str(),
  276. this->ExtractStaticLibraryName.match(2).c_str(),
  277. this->ExtractStaticLibraryName.match(3).c_str());
  278. #endif
  279. this->SetCurrentLinkType(LinkStatic);
  280. this->LinkItems.push_back(this->ExtractStaticLibraryName.match(2));
  281. }
  282. else if(this->ExtractAnyLibraryName.find(*i))
  283. {
  284. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  285. fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
  286. this->ExtractAnyLibraryName.match(1).c_str(),
  287. this->ExtractAnyLibraryName.match(2).c_str(),
  288. this->ExtractAnyLibraryName.match(3).c_str());
  289. #endif
  290. this->SetCurrentLinkType(this->StartLinkType);
  291. this->LinkItems.push_back(this->ExtractAnyLibraryName.match(2));
  292. }
  293. else
  294. {
  295. this->SetCurrentLinkType(this->StartLinkType);
  296. this->LinkItems.push_back(*i);
  297. }
  298. }
  299. // Restore the original linking type so system runtime libraries are
  300. // linked properly.
  301. this->SetCurrentLinkType(this->StartLinkType);
  302. }
  303. //-------------------------------------------------------------------
  304. bool cmOrderLinkDirectories::FindPathNotInDirectoryToAfterList(
  305. cmStdString& path)
  306. {
  307. for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
  308. >::iterator i = this->DirectoryToAfterList.begin();
  309. i != this->DirectoryToAfterList.end(); ++i)
  310. {
  311. const cmStdString& p = i->first;
  312. bool found = false;
  313. for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
  314. >::iterator j = this->DirectoryToAfterList.begin();
  315. j != this->DirectoryToAfterList.end() && !found; ++j)
  316. {
  317. if(j != i)
  318. {
  319. found = (std::find(j->second.begin(), j->second.end(), p)
  320. != j->second.end());
  321. }
  322. }
  323. if(!found)
  324. {
  325. path = p;
  326. this->DirectoryToAfterList.erase(i);
  327. return true;
  328. }
  329. }
  330. path = "";
  331. return false;
  332. }
  333. //-------------------------------------------------------------------
  334. void cmOrderLinkDirectories::OrderPaths(std::vector<cmStdString>&
  335. orderedPaths)
  336. {
  337. cmStdString path;
  338. // This is a topological sort implementation
  339. // One at a time find paths that are not in any other paths after list
  340. // and put them into the orderedPaths vector in that order
  341. // FindPathNotInDirectoryToAfterList removes the path from the
  342. // this->DirectoryToAfterList once it is found
  343. while(this->FindPathNotInDirectoryToAfterList(path))
  344. {
  345. orderedPaths.push_back(path);
  346. }
  347. // at this point if there are still paths in this->DirectoryToAfterList
  348. // then there is a cycle and we are stuck
  349. if(this->DirectoryToAfterList.size())
  350. {
  351. for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
  352. >::iterator i = this->DirectoryToAfterList.begin();
  353. i != this->DirectoryToAfterList.end(); ++i)
  354. {
  355. this->ImpossibleDirectories.insert(i->first);
  356. // still put it in the path list in the order we find them
  357. orderedPaths.push_back(i->first);
  358. }
  359. }
  360. }
  361. //-------------------------------------------------------------------
  362. void cmOrderLinkDirectories::SetLinkInformation(
  363. const char* targetName,
  364. const std::vector<std::string>& linkLibraries,
  365. const std::vector<std::string>& linkDirectories,
  366. const cmTargetManifest& manifest,
  367. const char* configSubdir
  368. )
  369. {
  370. // Save the target name.
  371. this->TargetName = targetName;
  372. // Save the subdirectory used for linking in this configuration.
  373. this->ConfigSubdir = configSubdir? configSubdir : "";
  374. // Merge the link directory search path given into our path set.
  375. std::vector<cmStdString> empty;
  376. for(std::vector<std::string>::const_iterator p = linkDirectories.begin();
  377. p != linkDirectories.end(); ++p)
  378. {
  379. std::string dir = *p;
  380. #ifdef _WIN32
  381. // Avoid case problems for windows paths.
  382. if(dir.size() > 2 && dir[1] == ':')
  383. {
  384. if(dir[0] >= 'A' && dir[0] <= 'Z')
  385. {
  386. dir[0] += 'a' - 'A';
  387. }
  388. }
  389. dir = cmSystemTools::GetActualCaseForPath(dir.c_str());
  390. #endif
  391. if(this->DirectoryToAfterListEmitted.insert(dir).second)
  392. {
  393. std::pair<cmStdString, std::vector<cmStdString> > dp;
  394. dp.first = dir;
  395. this->DirectoryToAfterList.push_back(dp);
  396. this->LinkPathSet.insert(dir);
  397. }
  398. }
  399. // Append the link library list into our raw list.
  400. for(std::vector<std::string>::const_iterator l = linkLibraries.begin();
  401. l != linkLibraries.end(); ++l)
  402. {
  403. this->RawLinkItems.push_back(*l);
  404. }
  405. // Construct a set of files that will exist after building.
  406. for(cmTargetManifest::const_iterator i = manifest.begin();
  407. i != manifest.end(); ++i)
  408. {
  409. for(cmTargetSet::const_iterator j = i->second.begin();
  410. j != i->second.end(); ++j)
  411. {
  412. this->ManifestFiles.insert(*j);
  413. }
  414. }
  415. }
  416. //-------------------------------------------------------------------
  417. bool cmOrderLinkDirectories::DetermineLibraryPathOrder()
  418. {
  419. // set up all the regular expressions
  420. this->CreateRegularExpressions();
  421. std::vector<cmStdString> finalOrderPaths;
  422. // find all libs that are full paths
  423. Library aLib;
  424. cmStdString dir;
  425. cmStdString file;
  426. std::vector<cmStdString> empty;
  427. // do not add a -F for the system frameworks
  428. this->EmittedFrameworkPaths.insert("/System/Library/Frameworks");
  429. for(unsigned int i=0; i < this->RawLinkItems.size(); ++i)
  430. {
  431. bool framework = false;
  432. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  433. fprintf(stderr, "Raw link item [%s]\n", this->RawLinkItems[i].c_str());
  434. #endif
  435. // check to see if the file is a full path or just contains
  436. // a / in it and is a path to something
  437. if(cmSystemTools::FileIsFullPath(this->RawLinkItems[i].c_str())
  438. || this->RawLinkItems[i].find("/") != cmStdString.npos)
  439. {
  440. if(cmSystemTools::FileIsDirectory(this->RawLinkItems[i].c_str()))
  441. {
  442. if(cmSystemTools::IsPathToFramework(this->RawLinkItems[i].c_str()))
  443. {
  444. this->SplitFramework.find(this->RawLinkItems[i]);
  445. cmStdString path = this->SplitFramework.match(1);
  446. // Add the -F path if we have not yet done so
  447. if(this->EmittedFrameworkPaths.insert(path).second)
  448. {
  449. std::string fpath = "-F";
  450. fpath += cmSystemTools::ConvertToOutputPath(path.c_str());
  451. this->LinkItems.push_back(fpath);
  452. }
  453. // now add the -framework option
  454. std::string frame = "-framework ";
  455. frame += this->SplitFramework.match(2);
  456. this->LinkItems.push_back(frame);
  457. framework = true;
  458. }
  459. else
  460. {
  461. // A full path to a directory was found as a link item
  462. // warn user
  463. std::string message =
  464. "Warning: Ignoring path found in link libraries for target: ";
  465. message += this->TargetName;
  466. message += ", path is: ";
  467. message += this->RawLinkItems[i];
  468. message +=
  469. ". Expected a library name or a full path to a library name.";
  470. cmSystemTools::Message(message.c_str());
  471. continue;
  472. }
  473. } // is it a directory
  474. if(!framework)
  475. {
  476. dir = cmSystemTools::GetFilenamePath(this->RawLinkItems[i]);
  477. file = cmSystemTools::GetFilenameName(this->RawLinkItems[i]);
  478. #ifdef _WIN32
  479. // Avoid case problems for windows paths.
  480. if(dir.size() > 2 && dir[1] == ':')
  481. {
  482. if(dir[0] >= 'A' && dir[0] <= 'Z')
  483. {
  484. dir[0] += 'a' - 'A';
  485. }
  486. }
  487. dir = cmSystemTools::GetActualCaseForPath(dir.c_str());
  488. #endif
  489. if(this->DirectoryToAfterListEmitted.insert(dir).second)
  490. {
  491. std::pair<cmStdString, std::vector<cmStdString> > dp;
  492. dp.first = dir;
  493. this->DirectoryToAfterList.push_back(dp);
  494. }
  495. this->LinkPathSet.insert(dir);
  496. aLib.FullPath = this->RawLinkItems[i];
  497. aLib.File = file;
  498. aLib.Path = dir;
  499. this->FullPathLibraries[aLib.FullPath] = aLib;
  500. #ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
  501. fprintf(stderr, "Storing item [%s]\n", file.c_str());
  502. #endif
  503. this->LinkItems.push_back(file);
  504. }
  505. }
  506. else
  507. {
  508. this->LinkItems.push_back(this->RawLinkItems[i]);
  509. }
  510. }
  511. this->FindLibrariesInSearchPaths();
  512. for(std::map<cmStdString, std::vector<cmStdString> >::iterator lib =
  513. this->LibraryToDirectories.begin();
  514. lib!= this->LibraryToDirectories.end();
  515. ++lib)
  516. {
  517. if(lib->second.size() > 0)
  518. {
  519. this->MultiDirectoryLibraries.push_back
  520. (this->FullPathLibraries[lib->first]);
  521. }
  522. else
  523. {
  524. this->SingleDirectoryLibraries.push_back
  525. (this->FullPathLibraries[lib->first]);
  526. }
  527. }
  528. this->FindIndividualLibraryOrders();
  529. this->SortedSearchPaths.clear();
  530. if(this->Debug)
  531. {
  532. this->PrintMap("this->LibraryToDirectories", this->LibraryToDirectories);
  533. this->PrintVector("this->DirectoryToAfterList",
  534. this->DirectoryToAfterList);
  535. }
  536. this->OrderPaths(this->SortedSearchPaths);
  537. // now turn libfoo.a into foo and foo.a into foo
  538. // This will prepare the link items for -litem
  539. this->PrepareLinkTargets();
  540. if(this->ImpossibleDirectories.size())
  541. {
  542. cmSystemTools::Message(this->GetWarnings().c_str());
  543. return false;
  544. }
  545. return true;
  546. }
  547. std::string cmOrderLinkDirectories::GetWarnings()
  548. {
  549. std::string warning =
  550. "It is impossible to order the linker search path in such a way "
  551. "that libraries specified as full paths will be picked by the "
  552. "linker.\nDirectories and libraries involved are:\n";
  553. for(std::set<cmStdString>::iterator i = this->ImpossibleDirectories.begin();
  554. i != this->ImpossibleDirectories.end(); ++i)
  555. {
  556. warning += "Directory: ";
  557. warning += *i;
  558. warning += " contains:\n";
  559. std::map<cmStdString, std::vector<cmStdString> >::iterator j;
  560. for(j = this->LibraryToDirectories.begin();
  561. j != this->LibraryToDirectories.end(); ++j)
  562. {
  563. if(std::find(j->second.begin(), j->second.end(), *i)
  564. != j->second.end())
  565. {
  566. warning += "Library: ";
  567. warning += j->first;
  568. warning += "\n";
  569. }
  570. }
  571. warning += "\n";
  572. }
  573. warning += "\n";
  574. return warning;
  575. }
  576. //-------------------------------------------------------------------
  577. void
  578. cmOrderLinkDirectories::PrintMap(const char* name,
  579. std::map<cmStdString, std::vector<cmStdString> >& m)
  580. {
  581. std::cout << name << "\n";
  582. for(std::map<cmStdString, std::vector<cmStdString> >::iterator i =
  583. m.begin(); i != m.end();
  584. ++i)
  585. {
  586. std::cout << i->first << ": ";
  587. for(std::vector<cmStdString>::iterator l = i->second.begin();
  588. l != i->second.end(); ++l)
  589. {
  590. std::cout << *l << " ";
  591. }
  592. std::cout << "\n";
  593. }
  594. }
  595. //-------------------------------------------------------------------
  596. void
  597. cmOrderLinkDirectories::PrintVector(const char* name,
  598. std::vector<std::pair<cmStdString,
  599. std::vector<cmStdString> > >& m)
  600. {
  601. std::cout << name << "\n";
  602. for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
  603. >::iterator i = m.begin(); i != m.end(); ++i)
  604. {
  605. std::cout << i->first << ": ";
  606. for(std::vector<cmStdString>::iterator l = i->second.begin();
  607. l != i->second.end(); ++l)
  608. {
  609. std::cout << *l << " ";
  610. }
  611. std::cout << "\n";
  612. }
  613. }
  614. void cmOrderLinkDirectories::GetFullPathLibraries(std::vector<cmStdString>&
  615. libs)
  616. {
  617. for(std::map<cmStdString, Library>::iterator i =
  618. this->FullPathLibraries.begin();
  619. i != this->FullPathLibraries.end(); ++i)
  620. {
  621. libs.push_back(i->first);
  622. }
  623. }
  624. //----------------------------------------------------------------------------
  625. bool cmOrderLinkDirectories::LibraryMayConflict(const char* desiredLib,
  626. const char* dir,
  627. const char* fname)
  628. {
  629. // We need to check whether the given file may be picked up by the
  630. // linker. This will occur if it exists as given or may be built
  631. // using the name given.
  632. bool found = false;
  633. std::string path = dir;
  634. path += "/";
  635. path += fname;
  636. if(this->ManifestFiles.find(path) != this->ManifestFiles.end())
  637. {
  638. found = true;
  639. }
  640. else if(cmSystemTools::FileExists(path.c_str()))
  641. {
  642. found = true;
  643. }
  644. // When linking with a multi-configuration build tool the
  645. // per-configuration subdirectory is added to each link path. Check
  646. // this subdirectory too.
  647. if(!found && !this->ConfigSubdir.empty())
  648. {
  649. path = dir;
  650. path += "/";
  651. path += this->ConfigSubdir;
  652. path += "/";
  653. path += fname;
  654. if(this->ManifestFiles.find(path) != this->ManifestFiles.end())
  655. {
  656. found = true;
  657. }
  658. else if(cmSystemTools::FileExists(path.c_str()))
  659. {
  660. found = true;
  661. }
  662. }
  663. // A library conflicts if it is found and is not a symlink back to
  664. // the desired library.
  665. if(found)
  666. {
  667. return !cmSystemTools::SameFile(desiredLib, path.c_str());
  668. }
  669. return false;
  670. }