diff options
Diffstat (limited to 'Source/cmOrderDirectories.cxx')
-rw-r--r-- | Source/cmOrderDirectories.cxx | 374 |
1 files changed, 156 insertions, 218 deletions
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index a4d9558..00606c7 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -31,84 +31,77 @@ Directory ordering computation. class cmOrderDirectoriesConstraint { public: - cmOrderDirectoriesConstraint(cmOrderDirectories* od, - std::string const& file): - OD(od), GlobalGenerator(od->GlobalGenerator) - { + cmOrderDirectoriesConstraint(cmOrderDirectories* od, std::string const& file) + : OD(od) + , GlobalGenerator(od->GlobalGenerator) + { this->FullPath = file; - if(file.rfind(".framework") != std::string::npos) - { - static cmsys::RegularExpression - splitFramework("^(.*)/(.*).framework/(.*)$"); - if(splitFramework.find(file) && - (std::string::npos != - splitFramework.match(3).find(splitFramework.match(2)))) - { + if (file.rfind(".framework") != std::string::npos) { + static cmsys::RegularExpression splitFramework( + "^(.*)/(.*).framework/(.*)$"); + if (splitFramework.find(file) && + (std::string::npos != + splitFramework.match(3).find(splitFramework.match(2)))) { this->Directory = splitFramework.match(1); this->FileName = std::string(file.begin() + this->Directory.size() + 1, file.end()); - } } + } - if(this->FileName.empty()) - { + if (this->FileName.empty()) { this->Directory = cmSystemTools::GetFilenamePath(file); this->FileName = cmSystemTools::GetFilenameName(file); - } } + } virtual ~cmOrderDirectoriesConstraint() {} void AddDirectory() - { + { this->DirectoryIndex = this->OD->AddOriginalDirectory(this->Directory); - } + } virtual void Report(std::ostream& e) = 0; void FindConflicts(unsigned int index) - { - for(unsigned int i=0; i < this->OD->OriginalDirectories.size(); ++i) - { + { + for (unsigned int i = 0; i < this->OD->OriginalDirectories.size(); ++i) { // Check if this directory conflicts with the entry. std::string const& dir = this->OD->OriginalDirectories[i]; if (!this->OD->IsSameDirectory(dir, this->Directory) && - this->FindConflict(dir)) - { + this->FindConflict(dir)) { // The library will be found in this directory but this is not // the directory named for it. Add an entry to make sure the // desired directory comes before this one. cmOrderDirectories::ConflictPair p(this->DirectoryIndex, index); this->OD->ConflictGraph[i].push_back(p); - } } } + } void FindImplicitConflicts(std::ostringstream& w) - { + { bool first = true; - for(unsigned int i=0; i < this->OD->OriginalDirectories.size(); ++i) - { + for (unsigned int i = 0; i < this->OD->OriginalDirectories.size(); ++i) { // Check if this directory conflicts with the entry. std::string const& dir = this->OD->OriginalDirectories[i]; - if(dir != this->Directory && - cmSystemTools::GetRealPath(dir) != - cmSystemTools::GetRealPath(this->Directory) && - this->FindConflict(dir)) - { + if (dir != this->Directory && + cmSystemTools::GetRealPath(dir) != + cmSystemTools::GetRealPath(this->Directory) && + this->FindConflict(dir)) { // The library will be found in this directory but it is // supposed to be found in an implicit search directory. - if(first) - { + if (first) { first = false; w << " "; this->Report(w); w << " in " << this->Directory << " may be hidden by files in:\n"; - } - w << " " << dir << "\n"; } + w << " " << dir << "\n"; } } + } + protected: virtual bool FindConflict(std::string const& dir) = 0; @@ -133,12 +126,11 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir, std::string file = dir; file += "/"; file += name; - if(cmSystemTools::FileExists(file.c_str(), true)) - { + if (cmSystemTools::FileExists(file.c_str(), true)) { // The file conflicts only if it is not the same as the original // file due to a symlink or hardlink. return !cmSystemTools::SameFile(this->FullPath, file); - } + } // Check if the file will be built by cmake. std::set<std::string> const& files = @@ -147,40 +139,37 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir, return fi != files.end(); } -class cmOrderDirectoriesConstraintSOName: public cmOrderDirectoriesConstraint +class cmOrderDirectoriesConstraintSOName : public cmOrderDirectoriesConstraint { public: cmOrderDirectoriesConstraintSOName(cmOrderDirectories* od, std::string const& file, - const char* soname): - cmOrderDirectoriesConstraint(od, file), SOName(soname? soname : "") - { - if(this->SOName.empty()) - { + const char* soname) + : cmOrderDirectoriesConstraint(od, file) + , SOName(soname ? soname : "") + { + if (this->SOName.empty()) { // Try to guess the soname. std::string soguess; - if(cmSystemTools::GuessLibrarySOName(file, soguess)) - { + if (cmSystemTools::GuessLibrarySOName(file, soguess)) { this->SOName = soguess; - } } } + } virtual void Report(std::ostream& e) - { + { e << "runtime library ["; - if(this->SOName.empty()) - { + if (this->SOName.empty()) { e << this->FileName; - } - else - { + } else { e << this->SOName; - } - e << "]"; } + e << "]"; + } virtual bool FindConflict(std::string const& dir); + private: // The soname of the shared library if it is known. std::string SOName; @@ -189,50 +178,44 @@ private: bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir) { // Determine which type of check to do. - if(!this->SOName.empty()) - { + if (!this->SOName.empty()) { // We have the library soname. Check if it will be found. - if(this->FileMayConflict(dir, this->SOName)) - { + if (this->FileMayConflict(dir, this->SOName)) { return true; - } } - else - { + } else { // We do not have the soname. Look for files in the directory // that may conflict. std::set<std::string> const& files = - (this->GlobalGenerator - ->GetDirectoryContent(dir, true)); + (this->GlobalGenerator->GetDirectoryContent(dir, true)); // Get the set of files that might conflict. Since we do not // know the soname just look at all files that start with the // file name. Usually the soname starts with the library name. std::string base = this->FileName; std::set<std::string>::const_iterator first = files.lower_bound(base); - ++base[base.size()-1]; + ++base[base.size() - 1]; std::set<std::string>::const_iterator last = files.upper_bound(base); - if(first != last) - { + if (first != last) { return true; - } } + } return false; } -class cmOrderDirectoriesConstraintLibrary: public cmOrderDirectoriesConstraint +class cmOrderDirectoriesConstraintLibrary : public cmOrderDirectoriesConstraint { public: cmOrderDirectoriesConstraintLibrary(cmOrderDirectories* od, - std::string const& file): - cmOrderDirectoriesConstraint(od, file) - { - } + std::string const& file) + : cmOrderDirectoriesConstraint(od, file) + { + } virtual void Report(std::ostream& e) - { + { e << "link library [" << this->FileName << "]"; - } + } virtual bool FindConflict(std::string const& dir); }; @@ -240,33 +223,28 @@ public: bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir) { // We have the library file name. Check if it will be found. - if(this->FileMayConflict(dir, this->FileName)) - { + if (this->FileMayConflict(dir, this->FileName)) { return true; - } + } // Now check if the file exists with other extensions the linker // might consider. - if(!this->OD->LinkExtensions.empty() && - this->OD->RemoveLibraryExtension.find(this->FileName)) - { + if (!this->OD->LinkExtensions.empty() && + this->OD->RemoveLibraryExtension.find(this->FileName)) { std::string lib = this->OD->RemoveLibraryExtension.match(1); std::string ext = this->OD->RemoveLibraryExtension.match(2); - for(std::vector<std::string>::iterator - i = this->OD->LinkExtensions.begin(); - i != this->OD->LinkExtensions.end(); ++i) - { - if(*i != ext) - { + for (std::vector<std::string>::iterator i = + this->OD->LinkExtensions.begin(); + i != this->OD->LinkExtensions.end(); ++i) { + if (*i != ext) { std::string fname = lib; fname += *i; - if(this->FileMayConflict(dir, fname)) - { + if (this->FileMayConflict(dir, fname)) { return true; - } } } } + } return false; } @@ -288,13 +266,12 @@ cmOrderDirectories::~cmOrderDirectories() std::vector<std::string> const& cmOrderDirectories::GetOrderedDirectories() { - if(!this->Computed) - { + if (!this->Computed) { this->Computed = true; this->CollectOriginalDirectories(); this->FindConflicts(); this->OrderDirectories(); - } + } return this->OrderedDirectories; } @@ -302,45 +279,38 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath, const char* soname) { // Add the runtime library at most once. - if(this->EmmittedConstraintSOName.insert(fullPath).second) - { + if (this->EmmittedConstraintSOName.insert(fullPath).second) { // Implicit link directories need special handling. - if(!this->ImplicitDirectories.empty()) - { + if (!this->ImplicitDirectories.empty()) { std::string dir = cmSystemTools::GetFilenamePath(fullPath); - if(fullPath.rfind(".framework") != std::string::npos) - { - static cmsys::RegularExpression - splitFramework("^(.*)/(.*).framework/(.*)$"); - if(splitFramework.find(fullPath) && - (std::string::npos != - splitFramework.match(3).find(splitFramework.match(2)))) - { + if (fullPath.rfind(".framework") != std::string::npos) { + static cmsys::RegularExpression splitFramework( + "^(.*)/(.*).framework/(.*)$"); + if (splitFramework.find(fullPath) && + (std::string::npos != + splitFramework.match(3).find(splitFramework.match(2)))) { dir = splitFramework.match(1); - } } + } - if(this->ImplicitDirectories.find(dir) != - this->ImplicitDirectories.end()) - { + if (this->ImplicitDirectories.find(dir) != + this->ImplicitDirectories.end()) { this->ImplicitDirEntries.push_back( new cmOrderDirectoriesConstraintSOName(this, fullPath, soname)); return; - } } + } // Construct the runtime information entry for this library. this->ConstraintEntries.push_back( new cmOrderDirectoriesConstraintSOName(this, fullPath, soname)); - } - else - { + } else { // This can happen if the same library is linked multiple times. // In that case the runtime information check need be done only // once anyway. For shared libs we could add a check in AddItem // to not repeat them. - } + } } void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath) @@ -349,54 +319,47 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath) assert(!this->LinkExtensions.empty()); // Add the link library at most once. - if(this->EmmittedConstraintLibrary.insert(fullPath).second) - { + if (this->EmmittedConstraintLibrary.insert(fullPath).second) { // Implicit link directories need special handling. - if(!this->ImplicitDirectories.empty()) - { + if (!this->ImplicitDirectories.empty()) { std::string dir = cmSystemTools::GetFilenamePath(fullPath); - if(this->ImplicitDirectories.find(dir) != - this->ImplicitDirectories.end()) - { + if (this->ImplicitDirectories.find(dir) != + this->ImplicitDirectories.end()) { this->ImplicitDirEntries.push_back( new cmOrderDirectoriesConstraintLibrary(this, fullPath)); return; - } } + } // Construct the link library entry. this->ConstraintEntries.push_back( new cmOrderDirectoriesConstraintLibrary(this, fullPath)); - } + } } -void -cmOrderDirectories -::AddUserDirectories(std::vector<std::string> const& extra) +void cmOrderDirectories::AddUserDirectories( + std::vector<std::string> const& extra) { - this->UserDirectories.insert(this->UserDirectories.end(), - extra.begin(), extra.end()); + this->UserDirectories.insert(this->UserDirectories.end(), extra.begin(), + extra.end()); } -void -cmOrderDirectories -::AddLanguageDirectories(std::vector<std::string> const& dirs) +void cmOrderDirectories::AddLanguageDirectories( + std::vector<std::string> const& dirs) { this->LanguageDirectories.insert(this->LanguageDirectories.end(), dirs.begin(), dirs.end()); } -void -cmOrderDirectories -::SetImplicitDirectories(std::set<std::string> const& implicitDirs) +void cmOrderDirectories::SetImplicitDirectories( + std::set<std::string> const& implicitDirs) { this->ImplicitDirectories = implicitDirs; } -void -cmOrderDirectories -::SetLinkExtensionInfo(std::vector<std::string> const& linkExtensions, - std::string const& removeExtRegex) +void cmOrderDirectories::SetLinkExtensionInfo( + std::vector<std::string> const& linkExtensions, + std::string const& removeExtRegex) { this->LinkExtensions = linkExtensions; this->RemoveLibraryExtension.compile(removeExtRegex.c_str()); @@ -410,10 +373,9 @@ void cmOrderDirectories::CollectOriginalDirectories() this->AddOriginalDirectories(this->UserDirectories); // Add directories containing constraints. - for(unsigned int i=0; i < this->ConstraintEntries.size(); ++i) - { + for (unsigned int i = 0; i < this->ConstraintEntries.size(); ++i) { this->ConstraintEntries[i]->AddDirectory(); - } + } // Add language runtime directories last. this->AddOriginalDirectories(this->LanguageDirectories); @@ -422,42 +384,36 @@ void cmOrderDirectories::CollectOriginalDirectories() int cmOrderDirectories::AddOriginalDirectory(std::string const& dir) { // Add the runtime directory with a unique index. - std::map<std::string, int>::iterator i = - this->DirectoryIndex.find(dir); - if(i == this->DirectoryIndex.end()) - { - std::map<std::string, int>::value_type - entry(dir, static_cast<int>(this->OriginalDirectories.size())); + std::map<std::string, int>::iterator i = this->DirectoryIndex.find(dir); + if (i == this->DirectoryIndex.end()) { + std::map<std::string, int>::value_type entry( + dir, static_cast<int>(this->OriginalDirectories.size())); i = this->DirectoryIndex.insert(entry).first; this->OriginalDirectories.push_back(dir); - } + } return i->second; } -void -cmOrderDirectories -::AddOriginalDirectories(std::vector<std::string> const& dirs) +void cmOrderDirectories::AddOriginalDirectories( + std::vector<std::string> const& dirs) { - for(std::vector<std::string>::const_iterator di = dirs.begin(); - di != dirs.end(); ++di) - { + for (std::vector<std::string>::const_iterator di = dirs.begin(); + di != dirs.end(); ++di) { // We never explicitly specify implicit link directories. - if(this->ImplicitDirectories.find(*di) != - this->ImplicitDirectories.end()) - { + if (this->ImplicitDirectories.find(*di) != + this->ImplicitDirectories.end()) { continue; - } + } // Skip the empty string. - if(di->empty()) - { + if (di->empty()) { continue; - } + } // Add this directory. this->AddOriginalDirectory(*di); - } + } } struct cmOrderDirectoriesCompare @@ -467,11 +423,10 @@ struct cmOrderDirectoriesCompare // The conflict pair is unique based on just the directory // (first). The second element is only used for displaying // information about why the entry is present. - bool operator()(ConflictPair const& l, - ConflictPair const& r) - { + bool operator()(ConflictPair const& l, ConflictPair const& r) + { return l.first == r.first; - } + } }; void cmOrderDirectories::FindConflicts() @@ -481,16 +436,13 @@ void cmOrderDirectories::FindConflicts() this->DirectoryVisited.resize(this->OriginalDirectories.size(), 0); // Find directories conflicting with each entry. - for(unsigned int i=0; i < this->ConstraintEntries.size(); ++i) - { + for (unsigned int i = 0; i < this->ConstraintEntries.size(); ++i) { this->ConstraintEntries[i]->FindConflicts(i); - } + } // Clean up the conflict graph representation. - for(std::vector<ConflictList>::iterator - i = this->ConflictGraph.begin(); - i != this->ConflictGraph.end(); ++i) - { + for (std::vector<ConflictList>::iterator i = this->ConflictGraph.begin(); + i != this->ConflictGraph.end(); ++i) { // Sort the outgoing edges for each graph node so that the // original order will be preserved as much as possible. std::sort(i->begin(), i->end()); @@ -499,7 +451,7 @@ void cmOrderDirectories::FindConflicts() ConflictList::iterator last = std::unique(i->begin(), i->end(), cmOrderDirectoriesCompare()); i->erase(last, i->end()); - } + } // Check items in implicit link directories. this->FindImplicitConflicts(); @@ -510,29 +462,25 @@ void cmOrderDirectories::FindImplicitConflicts() // Check for items in implicit link directories that have conflicts // in the explicit directories. std::ostringstream conflicts; - for(unsigned int i=0; i < this->ImplicitDirEntries.size(); ++i) - { + for (unsigned int i = 0; i < this->ImplicitDirEntries.size(); ++i) { this->ImplicitDirEntries[i]->FindImplicitConflicts(conflicts); - } + } // Skip warning if there were no conflicts. std::string text = conflicts.str(); - if(text.empty()) - { + if (text.empty()) { return; - } + } // Warn about the conflicts. std::ostringstream w; - w << "Cannot generate a safe " << this->Purpose - << " for target " << this->Target->GetName() + w << "Cannot generate a safe " << this->Purpose << " for target " + << this->Target->GetName() << " because files in some directories may conflict with " << " libraries in implicit directories:\n" - << text - << "Some of these libraries may not be found correctly."; - this->GlobalGenerator->GetCMakeInstance() - ->IssueMessage(cmake::WARNING, w.str(), - this->Target->GetBacktrace()); + << text << "Some of these libraries may not be found correctly."; + this->GlobalGenerator->GetCMakeInstance()->IssueMessage( + cmake::WARNING, w.str(), this->Target->GetBacktrace()); } void cmOrderDirectories::OrderDirectories() @@ -542,38 +490,33 @@ void cmOrderDirectories::OrderDirectories() this->WalkId = 0; // Iterate through the directories in the original order. - for(unsigned int i=0; i < this->OriginalDirectories.size(); ++i) - { + for (unsigned int i = 0; i < this->OriginalDirectories.size(); ++i) { // Start a new DFS from this node. ++this->WalkId; this->VisitDirectory(i); - } + } } void cmOrderDirectories::VisitDirectory(unsigned int i) { // Skip nodes already visited. - if(this->DirectoryVisited[i]) - { - if(this->DirectoryVisited[i] == this->WalkId) - { + if (this->DirectoryVisited[i]) { + if (this->DirectoryVisited[i] == this->WalkId) { // We have reached a node previously visited on this DFS. // There is a cycle. this->DiagnoseCycle(); - } - return; } + return; + } // We are now visiting this node so mark it. this->DirectoryVisited[i] = this->WalkId; // Visit the neighbors of the node first. ConflictList const& clist = this->ConflictGraph[i]; - for(ConflictList::const_iterator j = clist.begin(); - j != clist.end(); ++j) - { + for (ConflictList::const_iterator j = clist.begin(); j != clist.end(); ++j) { this->VisitDirectory(j->first); - } + } // Now that all directories required to come before this one have // been emmitted, emit this directory. @@ -583,35 +526,31 @@ void cmOrderDirectories::VisitDirectory(unsigned int i) void cmOrderDirectories::DiagnoseCycle() { // Report the cycle at most once. - if(this->CycleDiagnosed) - { + if (this->CycleDiagnosed) { return; - } + } this->CycleDiagnosed = true; // Construct the message. std::ostringstream e; - e << "Cannot generate a safe " << this->Purpose - << " for target " << this->Target->GetName() + e << "Cannot generate a safe " << this->Purpose << " for target " + << this->Target->GetName() << " because there is a cycle in the constraint graph:\n"; // Display the conflict graph. - for(unsigned int i=0; i < this->ConflictGraph.size(); ++i) - { + for (unsigned int i = 0; i < this->ConflictGraph.size(); ++i) { ConflictList const& clist = this->ConflictGraph[i]; e << " dir " << i << " is [" << this->OriginalDirectories[i] << "]\n"; - for(ConflictList::const_iterator j = clist.begin(); - j != clist.end(); ++j) - { + for (ConflictList::const_iterator j = clist.begin(); j != clist.end(); + ++j) { e << " dir " << j->first << " must precede it due to "; this->ConstraintEntries[j->second]->Report(e); e << "\n"; - } } + } e << "Some of these libraries may not be found correctly."; - this->GlobalGenerator->GetCMakeInstance() - ->IssueMessage(cmake::WARNING, e.str(), - this->Target->GetBacktrace()); + this->GlobalGenerator->GetCMakeInstance()->IssueMessage( + cmake::WARNING, e.str(), this->Target->GetBacktrace()); } bool cmOrderDirectories::IsSameDirectory(std::string const& l, @@ -625,11 +564,10 @@ std::string const& cmOrderDirectories::GetRealPath(std::string const& dir) std::map<std::string, std::string>::iterator i = this->RealPaths.lower_bound(dir); if (i == this->RealPaths.end() || - this->RealPaths.key_comp()(dir, i->first)) - { + this->RealPaths.key_comp()(dir, i->first)) { typedef std::map<std::string, std::string>::value_type value_type; i = this->RealPaths.insert( i, value_type(dir, cmSystemTools::GetRealPath(dir))); - } + } return i->second; } |