summaryrefslogtreecommitdiff
path: root/Source/cmFindLibraryCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmFindLibraryCommand.cxx')
-rw-r--r--Source/cmFindLibraryCommand.cxx197
1 files changed, 151 insertions, 46 deletions
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 0080e55aa..4af7e11bf 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -17,6 +17,7 @@
cmFindLibraryCommand::cmFindLibraryCommand()
{
this->EnvironmentPath = "LIB";
+ this->NamesPerDirAllowed = true;
}
//----------------------------------------------------------------------------
@@ -44,6 +45,9 @@ void cmFindLibraryCommand::GenerateDocumentation()
"SEARCH_XXX", "library");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"XXX_SUBDIR", "lib");
+ cmSystemTools::ReplaceString(this->GenericDocumentation,
+ "NAMES name1 [name2 ...]",
+ "NAMES name1 [name2 ...] [NAMES_PER_DIR]");
cmSystemTools::ReplaceString(
this->GenericDocumentation,
"XXX_EXTRA_PREFIX_ENTRY",
@@ -53,6 +57,12 @@ void cmFindLibraryCommand::GenerateDocumentation()
"CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
this->GenericDocumentation +=
"\n"
+ "When more than one value is given to the NAMES option this command "
+ "by default will consider one name at a time and search every directory "
+ "for it. "
+ "The NAMES_PER_DIR option tells this command to consider one directory "
+ "at a time and search for all names in it."
+ "\n"
"If the library found is a framework, then VAR will be set to "
"the full path to the framework <fullPath>/A.framework. "
"When a full path to a framework is used as a library, "
@@ -220,18 +230,19 @@ struct cmFindLibraryHelper
// Keep track of the best library file found so far.
typedef std::vector<std::string>::size_type size_type;
std::string BestPath;
- size_type BestPrefix;
- size_type BestSuffix;
// Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
bool OpenBSD;
- unsigned int BestMajor;
- unsigned int BestMinor;
- // Current name under consideration.
- cmsys::RegularExpression NameRegex;
- bool TryRawName;
- std::string RawName;
+ // Current names under consideration.
+ struct Name
+ {
+ bool TryRaw;
+ std::string Raw;
+ cmsys::RegularExpression Regex;
+ Name(): TryRaw(false) {}
+ };
+ std::vector<Name> Names;
// Current full path under consideration.
std::string TestPath;
@@ -249,8 +260,9 @@ struct cmFindLibraryHelper
suffix) - this->Suffixes.begin();
}
bool HasValidSuffix(std::string const& name);
- void SetName(std::string const& name);
+ void AddName(std::string const& name);
bool CheckDirectory(std::string const& path);
+ bool CheckDirectoryForName(std::string const& path, Name& name);
};
//----------------------------------------------------------------------------
@@ -273,14 +285,6 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf):
this->OpenBSD =
this->Makefile->GetCMakeInstance()
->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
-
- this->TryRawName = false;
-
- // No library file has yet been found.
- this->BestPrefix = this->Prefixes.size();
- this->BestSuffix = this->Suffixes.size();
- this->BestMajor = 0;
- this->BestMinor = 0;
}
//----------------------------------------------------------------------------
@@ -353,11 +357,13 @@ bool cmFindLibraryHelper::HasValidSuffix(std::string const& name)
}
//----------------------------------------------------------------------------
-void cmFindLibraryHelper::SetName(std::string const& name)
+void cmFindLibraryHelper::AddName(std::string const& name)
{
+ Name entry;
+
// Consider checking the raw name too.
- this->TryRawName = this->HasValidSuffix(name);
- this->RawName = name;
+ entry.TryRaw = this->HasValidSuffix(name);
+ entry.Raw = name;
// Build a regular expression to match library names.
std::string regex = "^";
@@ -369,21 +375,37 @@ void cmFindLibraryHelper::SetName(std::string const& name)
regex += "(\\.[0-9]+\\.[0-9]+)?";
}
regex += "$";
- this->NameRegex.compile(regex.c_str());
+ entry.Regex.compile(regex.c_str());
+ this->Names.push_back(entry);
}
//----------------------------------------------------------------------------
bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
{
+ for(std::vector<Name>::iterator i = this->Names.begin();
+ i != this->Names.end(); ++i)
+ {
+ if(this->CheckDirectoryForName(path, *i))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
+ Name& name)
+{
// If the original library name provided by the user matches one of
// the suffixes, try it first. This allows users to search
// specifically for a static library on some platforms (on MS tools
// one cannot tell just from the library name whether it is a static
// library or an import library).
- if(this->TryRawName)
+ if(name.TryRaw)
{
this->TestPath = path;
- this->TestPath += this->RawName;
+ this->TestPath += name.Raw;
if(cmSystemTools::FileExists(this->TestPath.c_str(), true))
{
this->BestPath =
@@ -393,6 +415,12 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
}
}
+ // No library file has yet been found.
+ size_type bestPrefix = this->Prefixes.size();
+ size_type bestSuffix = this->Suffixes.size();
+ unsigned int bestMajor = 0;
+ unsigned int bestMinor = 0;
+
// Search for a file matching the library name regex.
std::string dir = path;
cmSystemTools::ConvertToUnixSlashes(dir);
@@ -406,7 +434,7 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
#else
std::string const& testName = origName;
#endif
- if(this->NameRegex.find(testName))
+ if(name.Regex.find(testName))
{
this->TestPath = path;
this->TestPath += origName;
@@ -416,25 +444,25 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
// best name found so far. Earlier prefixes are preferred,
// followed by earlier suffixes. For OpenBSD, shared library
// version extensions are compared.
- size_type prefix = this->GetPrefixIndex(this->NameRegex.match(1));
- size_type suffix = this->GetSuffixIndex(this->NameRegex.match(2));
+ size_type prefix = this->GetPrefixIndex(name.Regex.match(1));
+ size_type suffix = this->GetSuffixIndex(name.Regex.match(2));
unsigned int major = 0;
unsigned int minor = 0;
if(this->OpenBSD)
{
- sscanf(this->NameRegex.match(3).c_str(), ".%u.%u", &major, &minor);
+ sscanf(name.Regex.match(3).c_str(), ".%u.%u", &major, &minor);
}
- if(this->BestPath.empty() || prefix < this->BestPrefix ||
- (prefix == this->BestPrefix && suffix < this->BestSuffix) ||
- (prefix == this->BestPrefix && suffix == this->BestSuffix &&
- (major > this->BestMajor ||
- (major == this->BestMajor && minor > this->BestMinor))))
+ if(this->BestPath.empty() || prefix < bestPrefix ||
+ (prefix == bestPrefix && suffix < bestSuffix) ||
+ (prefix == bestPrefix && suffix == bestSuffix &&
+ (major > bestMajor ||
+ (major == bestMajor && minor > bestMinor))))
{
this->BestPath = this->TestPath;
- this->BestPrefix = prefix;
- this->BestSuffix = suffix;
- this->BestMajor = major;
- this->BestMinor = minor;
+ bestPrefix = prefix;
+ bestSuffix = suffix;
+ bestMajor = major;
+ bestMinor = minor;
}
}
}
@@ -447,6 +475,42 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
//----------------------------------------------------------------------------
std::string cmFindLibraryCommand::FindNormalLibrary()
{
+ if(this->NamesPerDir)
+ {
+ return this->FindNormalLibraryNamesPerDir();
+ }
+ else
+ {
+ return this->FindNormalLibraryDirsPerName();
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
+{
+ // Search for all names in each directory.
+ cmFindLibraryHelper helper(this->Makefile);
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ helper.AddName(*ni);
+ }
+ // Search every directory.
+ for(std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p)
+ {
+ if(helper.CheckDirectory(*p))
+ {
+ return helper.BestPath;
+ }
+ }
+ // Couldn't find the library.
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
+{
// Search the entire path for each name.
cmFindLibraryHelper helper(this->Makefile);
for(std::vector<std::string>::const_iterator ni = this->Names.begin();
@@ -454,7 +518,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
{
// Switch to searching for this name.
std::string const& name = *ni;
- helper.SetName(name);
+ helper.AddName(name);
// Search every directory.
for(std::vector<std::string>::const_iterator
@@ -474,19 +538,60 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
//----------------------------------------------------------------------------
std::string cmFindLibraryCommand::FindFrameworkLibrary()
{
- // Search for a framework of each name in the entire search path.
+ if(this->NamesPerDir)
+ {
+ return this->FindFrameworkLibraryNamesPerDir();
+ }
+ else
+ {
+ return this->FindFrameworkLibraryDirsPerName();
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
+{
+ std::string fwPath;
+ // Search for all names in each search path.
+ for(std::vector<std::string>::const_iterator di = this->SearchPaths.begin();
+ di != this->SearchPaths.end(); ++di)
+ {
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ fwPath = *di;
+ fwPath += *ni;
+ fwPath += ".framework";
+ if(cmSystemTools::FileIsDirectory(fwPath.c_str()))
+ {
+ return cmSystemTools::CollapseFullPath(fwPath.c_str());
+ }
+ }
+ }
+
+ // No framework found.
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
+{
+ std::string fwPath;
+ // Search for each name in all search paths.
for(std::vector<std::string>::const_iterator ni = this->Names.begin();
ni != this->Names.end() ; ++ni)
{
- // Search the paths for a framework with this name.
- std::string fwName = *ni;
- fwName += ".framework";
- std::string fwPath = cmSystemTools::FindDirectory(fwName.c_str(),
- this->SearchPaths,
- true);
- if(!fwPath.empty())
+ for(std::vector<std::string>::const_iterator
+ di = this->SearchPaths.begin();
+ di != this->SearchPaths.end(); ++di)
{
- return fwPath;
+ fwPath = *di;
+ fwPath += *ni;
+ fwPath += ".framework";
+ if(cmSystemTools::FileIsDirectory(fwPath.c_str()))
+ {
+ return cmSystemTools::CollapseFullPath(fwPath.c_str());
+ }
}
}