| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 | 
							- #include "cmOrderLinkDirectories.h"
 
- #include "cmSystemTools.h"
 
- #include "cmsys/RegularExpression.hxx"
 
- //-------------------------------------------------------------------
 
- bool cmOrderLinkDirectories::LibraryInDirectory(const char* dir, 
 
-                                                 const char* libIn)
 
- {
 
-   cmStdString path = dir;
 
-   path += "/";
 
-   path += libIn;
 
-   // first look for the library as given
 
-   if(cmSystemTools::FileExists(path.c_str()))
 
-     {
 
-     return true;
 
-     }
 
-   // next remove the extension (.a, .so ) and look for the library
 
-   // under a different name as the linker can do either
 
-   if(m_RemoveLibraryExtension.find(libIn))
 
-     {
 
-     cmStdString lib = m_RemoveLibraryExtension.match(1);
 
-     cmStdString ext = m_RemoveLibraryExtension.match(2);
 
-     for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin();
 
-         i != m_LinkExtensions.end(); ++i)
 
-       {
 
-       if(ext != *i)
 
-         {
 
-         path = dir;
 
-         path += "/";
 
-         path += lib + *i;
 
-         if(cmSystemTools::FileExists(path.c_str()))
 
-           {
 
-           return true;
 
-           } 
 
-         }
 
-       }
 
-     }
 
-   return false;
 
- }
 
- //-------------------------------------------------------------------
 
- void cmOrderLinkDirectories::FindLibrariesInSeachPaths()
 
- {
 
-   for(std::set<cmStdString>::iterator dir = m_LinkPathSet.begin();
 
-       dir != m_LinkPathSet.end(); ++dir)
 
-     {
 
-     for(std::map<cmStdString, Library>::iterator lib
 
-           = m_FullPathLibraries.begin();
 
-         lib != m_FullPathLibraries.end(); ++lib)
 
-       {
 
-       if(lib->second.Path != *dir)
 
-         {
 
-         if(this->LibraryInDirectory(dir->c_str(), lib->second.File.c_str()))
 
-           {
 
-           m_LibraryToDirectories[lib->second.FullPath].push_back(*dir);
 
-           }
 
-         }
 
-       }
 
-     }
 
- }
 
-                  
 
- //-------------------------------------------------------------------
 
- void cmOrderLinkDirectories::FindIndividualLibraryOrders()
 
- {
 
-   for(std::vector<Library>::iterator lib = m_MultiDirectoryLibraries.begin();
 
-       lib != m_MultiDirectoryLibraries.end(); ++lib)
 
-     {
 
-     std::vector<cmStdString>& dirs = m_LibraryToDirectories[lib->FullPath];
 
-     m_DirectoryToAfterList[lib->Path] = dirs;
 
-     }
 
- }
 
- //-------------------------------------------------------------------
 
- void cmOrderLinkDirectories::CreateRegularExpressions()
 
- {
 
-   cmStdString libext = "(";
 
-   bool first = true;
 
-   for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin();
 
-       i != m_LinkExtensions.end(); ++i)
 
-     {
 
-     if(!first)
 
-       {
 
-       libext += "|";
 
-       }
 
-     first = false;
 
-     libext += "\\";
 
-     libext += *i;
 
-     }
 
-   libext += ").*";
 
-   cmStdString reg("(.*)");
 
-   reg += libext;
 
-   m_RemoveLibraryExtension.compile(reg.c_str());
 
-   reg = "^lib([^/]*)";
 
-   reg += libext;
 
-   m_ExtractBaseLibraryName.compile(reg.c_str());
 
-   reg = "([^/]*)";
 
-   reg += libext;
 
-   m_ExtractBaseLibraryNameNoPrefix.compile(reg.c_str());
 
- }
 
- //-------------------------------------------------------------------
 
- void cmOrderLinkDirectories::PrepareLinkTargets()
 
- {
 
-   for(std::vector<cmStdString>::iterator i = m_LinkItems.begin();
 
-       i != m_LinkItems.end(); ++i)
 
-     {
 
-     // separate the library name from libfoo.a or foo.a
 
-     if(m_ExtractBaseLibraryName.find(*i))
 
-       {
 
-       *i = m_ExtractBaseLibraryName.match(1);
 
-       }
 
-     else if(m_ExtractBaseLibraryNameNoPrefix.find(*i))
 
-       {
 
-       *i = m_ExtractBaseLibraryNameNoPrefix.match(1);
 
-       }
 
-     }
 
- }
 
- //-------------------------------------------------------------------
 
- bool cmOrderLinkDirectories::FindPathNotInDirectoryToAfterList(
 
-   cmStdString& path)
 
- {
 
-   for(std::map<cmStdString, std::vector<cmStdString> >::iterator i
 
-         = m_DirectoryToAfterList.begin();
 
-       i != m_DirectoryToAfterList.end(); ++i)
 
-     {
 
-     const cmStdString& p = i->first;
 
-     bool found = false;
 
-     for(std::map<cmStdString, std::vector<cmStdString> >::iterator j 
 
-           = m_DirectoryToAfterList.begin(); j != m_DirectoryToAfterList.end() 
 
-           && !found; ++j)
 
-       {
 
-       if(j != i)
 
-         {
 
-         found = (std::find(j->second.begin(), j->second.end(), p) != j->second.end());
 
-         }
 
-       }
 
-     if(!found)
 
-       {
 
-       path = p;
 
-       m_DirectoryToAfterList.erase(i);
 
-       return true;
 
-       }
 
-     }
 
-   path = "";
 
-   return false;
 
- }
 
- //-------------------------------------------------------------------
 
- void cmOrderLinkDirectories::OrderPaths(std::vector<cmStdString>&
 
-                                         orderedPaths)
 
- {
 
-   cmStdString path;
 
-   // This is a topological sort implementation
 
-   // One at a time find paths that are not in any other paths after list
 
-   // and put them into the orderedPaths vector in that order
 
-   // FindPathNotInDirectoryToAfterList removes the path from the
 
-   // m_DirectoryToAfterList once it is found
 
-   while(this->FindPathNotInDirectoryToAfterList(path))
 
-     {
 
-     orderedPaths.push_back(path);
 
-     }
 
-   // at this point if there are still paths in m_DirectoryToAfterList
 
-   // then there is a cycle and we are stuck
 
-   if(m_DirectoryToAfterList.size())
 
-     {
 
-     for(std::map<cmStdString, std::vector<cmStdString> >::iterator i
 
-           = m_DirectoryToAfterList.begin();
 
-         i != m_DirectoryToAfterList.end(); ++i)
 
-       {
 
-       m_ImposibleDirectories.insert(i->first);
 
-       // still put it in the path list in the order we find them
 
-       orderedPaths.push_back(i->first);
 
-       }
 
-     
 
-     }
 
- }
 
- //-------------------------------------------------------------------
 
- void cmOrderLinkDirectories::SetLinkInformation(const cmTarget& target,
 
-                                                 cmTarget::LinkLibraryType 
 
-                                                 linktype,
 
-                                                 const char* targetLibrary)
 
- {
 
-     // collect the search paths from the target into paths set
 
-   const std::vector<std::string>& searchPaths = target.GetLinkDirectories();
 
-   std::vector<cmStdString> empty;
 
-   for(std::vector<std::string>::const_iterator p = searchPaths.begin();
 
-       p != searchPaths.end(); ++p)
 
-     {
 
-     m_DirectoryToAfterList[*p] = empty;
 
-     m_LinkPathSet.insert(*p);
 
-     }
 
-   // collect the link items from the target and put it into libs
 
-   const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries();
 
-   std::vector<cmStdString>  libs;
 
-   for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
 
-       lib != tlibs.end(); ++lib)
 
-     {
 
-     // skip zero size library entries, this may happen
 
-     // if a variable expands to nothing.
 
-     if (lib->first.size() == 0)
 
-       {
 
-       continue;
 
-       }
 
-     // Don't link the library against itself!
 
-     if(targetLibrary && (lib->first == targetLibrary))
 
-       {
 
-       continue;
 
-       }  
 
-     // use the correct lib for the current configuration
 
-     if (lib->second == cmTarget::DEBUG && linktype != cmTarget::DEBUG)
 
-       {
 
-       continue;
 
-       }
 
-     if (lib->second == cmTarget::OPTIMIZED && 
 
-         linktype != cmTarget::OPTIMIZED)
 
-       {
 
-       continue;
 
-       }
 
-     m_RawLinkItems.push_back(lib->first);
 
-     }
 
- }
 
- //-------------------------------------------------------------------
 
- bool cmOrderLinkDirectories::DetermineLibraryPathOrder()
 
- {
 
-   // set up all the regular expressions
 
-   this->CreateRegularExpressions();
 
-   std::vector<cmStdString> finalOrderPaths;
 
-   // find all libs that are full paths
 
-   Library aLib;
 
-   cmStdString dir;
 
-   cmStdString file;
 
-   std::vector<cmStdString> empty;
 
-   for(unsigned int i=0; i < m_RawLinkItems.size(); ++i)
 
-     {
 
-     if(cmSystemTools::FileIsFullPath(m_RawLinkItems[i].c_str()))
 
-       {
 
-       cmSystemTools::SplitProgramPath(m_RawLinkItems[i].c_str(),
 
-                                       dir, file);
 
-       m_DirectoryToAfterList[dir] = empty;
 
-       m_LinkPathSet.insert(dir);
 
-       aLib.FullPath = m_RawLinkItems[i];
 
-       aLib.File = file;
 
-       aLib.Path = dir;
 
-       m_FullPathLibraries[aLib.FullPath] = aLib;
 
-       m_LinkItems.push_back(file);
 
-       }
 
-     else
 
-       {
 
-       m_LinkItems.push_back(m_RawLinkItems[i]);
 
-       }
 
-     }
 
-   this->FindLibrariesInSeachPaths();
 
-   for(std::map<cmStdString, std::vector<cmStdString> >::iterator lib =
 
-         m_LibraryToDirectories.begin(); lib!= m_LibraryToDirectories.end(); 
 
-       ++lib)
 
-     {
 
-     if(lib->second.size() > 0)
 
-       {
 
-       m_MultiDirectoryLibraries.push_back(m_FullPathLibraries[lib->first]);
 
-       }
 
-     else
 
-       {
 
-       m_SingleDirectoryLibraries.push_back(m_FullPathLibraries[lib->first]);
 
-       }
 
-     }
 
-   this->FindIndividualLibraryOrders();
 
-   m_SortedSearchPaths.clear();
 
-   
 
-   this->OrderPaths(m_SortedSearchPaths); 
 
-   // now turn libfoo.a into foo and foo.a into foo
 
-   // This will prepare the link items for -litem 
 
-   this->PrepareLinkTargets();
 
-   if(m_ImposibleDirectories.size())
 
-     {
 
-     cmSystemTools::Message(this->GetWarnings().c_str());
 
-     return false;
 
-     }
 
-   return true;
 
- }
 
- std::string cmOrderLinkDirectories::GetWarnings()
 
- {
 
-   std::string warning = "It is impossible to order the linker search path in such a way that libraries specified as full paths will be picked by the linker.\nDirectories and libraries involvied are:\n";
 
-   for(std::set<cmStdString>::iterator i = m_ImposibleDirectories.begin();
 
-       i != m_ImposibleDirectories.end(); ++i)
 
-     {
 
-     warning += "Directory: ";
 
-     warning += *i;
 
-     warning += " contains:\n";
 
-     std::map<cmStdString, std::vector<cmStdString> >::iterator j;
 
-     for(j = m_LibraryToDirectories.begin(); 
 
-         j != m_LibraryToDirectories.end(); ++j)
 
-       {
 
-       if(std::find(j->second.begin(), j->second.end(), *i)
 
-          != j->second.end())
 
-         {
 
-         warning += "Library: ";
 
-         warning += j->first;
 
-         warning += "\n";
 
-         }
 
-       }
 
-     warning += "\n";
 
-     }
 
-   warning += "\n";
 
-   return warning;
 
- }
 
- //-------------------------------------------------------------------
 
- void
 
- cmOrderLinkDirectories::PrintMap(const char* name,
 
-                        std::map<cmStdString, std::vector<cmStdString> >& m)
 
- {
 
-   std::cerr << name << "\n";
 
-   for(std::map<cmStdString, std::vector<cmStdString> >::iterator i =
 
-         m.begin(); i != m.end();
 
-       ++i)
 
-     {
 
-     std::cerr << i->first << ":  ";
 
-     for(std::vector<cmStdString>::iterator l = i->second.begin();
 
-         l != i->second.end(); ++l)
 
-       {
 
-       std::cerr << *l << " ";
 
-       }
 
-     std::cerr << "\n";
 
-     }
 
- }
 
- void cmOrderLinkDirectories::GetFullPathLibraries(std::vector<cmStdString>& 
 
-                                                   libs)
 
- {
 
-   for(std::map<cmStdString, Library>::iterator i = m_FullPathLibraries.begin();
 
-       i != m_FullPathLibraries.end(); ++i)
 
-     {
 
-     libs.push_back(i->first);
 
-     }
 
-   
 
- }
 
 
  |