summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorChuck Atkins <chuck.atkins@kitware.com>2014-10-15 20:36:42 (GMT)
committerChuck Atkins <chuck.atkins@kitware.com>2014-11-11 18:39:51 (GMT)
commit2a9ac4bd83f7247539616545ef0772fea1f4a1fc (patch)
treea8b99f4caa8522d130b93727a9a345865f2ac35f /Source
parent32922840e7ea8a0536fec393352ede5b75087543 (diff)
downloadCMake-2a9ac4bd83f7247539616545ef0772fea1f4a1fc.zip
CMake-2a9ac4bd83f7247539616545ef0772fea1f4a1fc.tar.gz
CMake-2a9ac4bd83f7247539616545ef0772fea1f4a1fc.tar.bz2
Encapsulate search path manipulation functions into a seperate class.
The functions for adding the various different types of paths have been factored out into a new class, cmSearchPath. It is to be used as a helper container class for the various find_* commands.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmBootstrapCommands1.cxx1
-rw-r--r--Source/cmFindBase.cxx177
-rw-r--r--Source/cmFindBase.h9
-rw-r--r--Source/cmFindCommon.cxx145
-rw-r--r--Source/cmFindCommon.h45
-rw-r--r--Source/cmFindPackageCommand.cxx72
-rw-r--r--Source/cmFindPackageCommand.h7
-rw-r--r--Source/cmSearchPath.cxx243
-rw-r--r--Source/cmSearchPath.h60
9 files changed, 414 insertions, 345 deletions
diff --git a/Source/cmBootstrapCommands1.cxx b/Source/cmBootstrapCommands1.cxx
index 9093579..29d3671 100644
--- a/Source/cmBootstrapCommands1.cxx
+++ b/Source/cmBootstrapCommands1.cxx
@@ -43,6 +43,7 @@
#include "cmExecuteProcessCommand.cxx"
#include "cmExternalMakefileProjectGenerator.cxx"
#include "cmFindBase.cxx"
+#include "cmSearchPath.cxx"
#include "cmFindCommon.cxx"
#include "cmFileCommand.cxx"
#include "cmFindFileCommand.cxx"
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 2b9acae..52f04ad 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -140,11 +140,11 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
else if(doing == DoingPaths)
{
- this->AddUserPath(args[j], this->UserGuessPaths);
+ this->UserGuessArgs.push_back(args[j]);
}
else if(doing == DoingHints)
{
- this->AddUserPath(args[j], this->UserHintsPaths);
+ this->UserHintsArgs.push_back(args[j]);
}
else if(doing == DoingPathSuffixes)
{
@@ -186,7 +186,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
this->Names.push_back(shortArgs[0]);
for(unsigned int j = 1; j < shortArgs.size(); ++j)
{
- this->AddUserPath(shortArgs[j], this->UserGuessPaths);
+ this->UserGuessArgs.push_back(shortArgs[j]);
}
}
this->ExpandPaths();
@@ -203,107 +203,23 @@ void cmFindBase::ExpandPaths()
if(!this->NoCMakePath)
{
this->FillCMakeVariablePath();
- this->AddPathSuffixes(this->CMakeVariablePaths);
}
if(!this->NoCMakeEnvironmentPath)
{
this->FillCMakeEnvironmentPath();
- this->AddPathSuffixes(this->CMakeEnvironmentPaths);
}
if(!this->NoSystemEnvironmentPath)
{
this->FillSystemEnvironmentPath();
- this->AddPathSuffixes(this->SystemEnvironmentPaths);
}
if(!this->NoCMakeSystemPath)
{
this->FillCMakeSystemVariablePath();
- this->AddPathSuffixes(this->CMakeSystemVariablePaths);
}
}
this->FillUserHintsPath();
- this->AddPathSuffixes(this->UserHintsPaths);
this->FillUserGuessPath();
- this->AddPathSuffixes(this->UserGuessPaths);
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddPrefixPaths(std::vector<std::string> const& inPaths,
- PathType pt,
- std::vector<std::string>& outPaths)
-{
- // default for programs
- std::string subdir = "bin";
-
- if (this->CMakePathName == "INCLUDE")
- {
- subdir = "include";
- }
- else if (this->CMakePathName == "LIBRARY")
- {
- subdir = "lib";
- }
- else if (this->CMakePathName == "FRAMEWORK")
- {
- subdir = ""; // ? what to do for frameworks ?
- }
-
- for(std::vector<std::string>::const_iterator it = inPaths.begin();
- it != inPaths.end(); ++it)
- {
- std::string dir = *it;
- if(!subdir.empty() && !dir.empty() && dir[dir.size()-1] != '/')
- {
- dir += "/";
- }
- if(subdir == "include" || subdir == "lib")
- {
- const char* arch =
- this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
- if(arch && *arch)
- {
- this->AddPathInternal(this->MakeFullPath(dir+subdir+"/"+arch, pt),
- outPaths);
- }
- }
- std::string add = dir + subdir;
- if(add != "/")
- {
- this->AddPathInternal(this->MakeFullPath(add, pt), outPaths);
- }
- if (subdir == "bin")
- {
- this->AddPathInternal(this->MakeFullPath(dir+"sbin", pt), outPaths);
- }
- if(!subdir.empty() && *it != "/")
- {
- this->AddPathInternal(this->MakeFullPath(*it, pt), outPaths);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddCMakePrefixPath(const std::string& variable,
- std::vector<std::string>& outPaths)
-{
- // Get a path from a CMake variable.
- if(const char* varPath = this->Makefile->GetDefinition(variable))
- {
- std::vector<std::string> tmp;
- cmSystemTools::ExpandListArgument(varPath, tmp);
- this->AddPrefixPaths(tmp, CMakePath, outPaths);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddEnvPrefixPath(const std::string& variable,
- std::vector<std::string>& outPaths)
-{
- // Get a path from the environment.
- std::vector<std::string> tmp;
- cmSystemTools::GetPath(tmp, variable.c_str());
- this->AddPrefixPaths(tmp, EnvPath, outPaths);
}
//----------------------------------------------------------------------------
@@ -313,17 +229,18 @@ void cmFindBase::FillCMakeEnvironmentPath()
std::string var = "CMAKE_";
var += this->CMakePathName;
var += "_PATH";
- this->AddEnvPrefixPath("CMAKE_PREFIX_PATH", this->CMakeEnvironmentPaths);
- this->AddEnvPath(var.c_str(), this->CMakeEnvironmentPaths);
+ this->CMakeEnvironmentPaths.AddEnvPrefixPath("CMAKE_PREFIX_PATH");
+ this->CMakeEnvironmentPaths.AddEnvPath(var);
if(this->CMakePathName == "PROGRAM")
{
- this->AddEnvPath("CMAKE_APPBUNDLE_PATH", this->CMakeEnvironmentPaths);
+ this->CMakeEnvironmentPaths.AddEnvPath("CMAKE_APPBUNDLE_PATH");
}
else
{
- this->AddEnvPath("CMAKE_FRAMEWORK_PATH", this->CMakeEnvironmentPaths);
+ this->CMakeEnvironmentPaths.AddEnvPath("CMAKE_FRAMEWORK_PATH");
}
+ this->CMakeEnvironmentPaths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
@@ -335,17 +252,18 @@ void cmFindBase::FillCMakeVariablePath()
std::string var = "CMAKE_";
var += this->CMakePathName;
var += "_PATH";
- this->AddCMakePrefixPath("CMAKE_PREFIX_PATH", this->CMakeVariablePaths);
- this->AddCMakePath(var, this->CMakeVariablePaths);
+ this->CMakeVariablePaths.AddCMakePrefixPath("CMAKE_PREFIX_PATH");
+ this->CMakeVariablePaths.AddCMakePath(var);
if(this->CMakePathName == "PROGRAM")
{
- this->AddCMakePath("CMAKE_APPBUNDLE_PATH", this->CMakeVariablePaths);
+ this->CMakeVariablePaths.AddCMakePath("CMAKE_APPBUNDLE_PATH");
}
else
{
- this->AddCMakePath("CMAKE_FRAMEWORK_PATH", this->CMakeVariablePaths);
+ this->CMakeVariablePaths.AddCMakePath("CMAKE_FRAMEWORK_PATH");
}
+ this->CMakeVariablePaths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
@@ -354,11 +272,11 @@ void cmFindBase::FillSystemEnvironmentPath()
// Add LIB or INCLUDE
if(!this->EnvironmentPath.empty())
{
- this->AddEnvPath(this->EnvironmentPath.c_str(),
- this->SystemEnvironmentPaths);
+ this->SystemEnvironmentPaths.AddEnvPath(this->EnvironmentPath);
}
// Add PATH
- this->AddEnvPath(0, this->SystemEnvironmentPaths);
+ this->SystemEnvironmentPaths.AddEnvPath("PATH");
+ this->SystemEnvironmentPaths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
@@ -367,72 +285,45 @@ void cmFindBase::FillCMakeSystemVariablePath()
std::string var = "CMAKE_SYSTEM_";
var += this->CMakePathName;
var += "_PATH";
- this->AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH",
- this->CMakeSystemVariablePaths);
- this->AddCMakePath(var, this->CMakeSystemVariablePaths);
+ this->CMakeSystemVariablePaths.AddCMakePrefixPath(
+ "CMAKE_SYSTEM_PREFIX_PATH");
+ this->CMakeSystemVariablePaths.AddCMakePath(var);
if(this->CMakePathName == "PROGRAM")
{
- this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH",
- this->CMakeSystemVariablePaths);
+ this->CMakeSystemVariablePaths.AddCMakePath(
+ "CMAKE_SYSTEM_APPBUNDLE_PATH");
}
else
{
- this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH",
- this->CMakeSystemVariablePaths);
+ this->CMakeSystemVariablePaths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
}
+ this->CMakeSystemVariablePaths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
void cmFindBase::FillUserHintsPath()
{
- std::vector<std::string> inPaths;
- inPaths.swap(this->UserHintsPaths);
- this->AddPathsInternal(inPaths, CMakePath, this->UserHintsPaths);
+ for(std::vector<std::string>::const_iterator p = this->UserHintsArgs.begin();
+ p != this->UserHintsArgs.end(); ++p)
+ {
+ this->UserHintsPaths.AddUserPath(*p);
+ }
+ this->UserHintsPaths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
void cmFindBase::FillUserGuessPath()
{
- std::vector<std::string> inPaths;
- inPaths.swap(this->UserGuessPaths);
- this->AddPathsInternal(inPaths, CMakePath, this->UserGuessPaths);
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddPathSuffixes(std::vector<std::string>& paths)
-{
- std::vector<std::string> inPaths;
- inPaths.swap(paths);
- paths.reserve(inPaths.size()*(this->SearchPathSuffixes.size()+1));
-
- for(std::vector<std::string>::iterator ip = inPaths.begin();
- ip != inPaths.end(); ++ip)
+ for(std::vector<std::string>::const_iterator p = this->UserGuessArgs.begin();
+ p != this->UserGuessArgs.end(); ++p)
{
- cmSystemTools::ConvertToUnixSlashes(*ip);
-
- // if *i is only / then do not add a //
- // this will get incorrectly considered a network
- // path on windows and cause huge delays.
- std::string p = *ip;
- if(!p.empty() && *p.rbegin() != '/')
- {
- p += "/";
- }
-
- for(std::vector<std::string>::iterator sps =
- this->SearchPathSuffixes.begin();
- sps != this->SearchPathSuffixes.end(); ++sps)
- {
- // add to all paths because the search path may be modified
- // later with lib being replaced for lib64 which may exist
- paths.push_back(p+*sps);
- }
- // now put the path without the path suffixes in the SearchPaths
- paths.push_back(*ip);
+ this->UserGuessPaths.AddUserPath(*p);
}
+ this->UserGuessPaths.AddSuffixes(this->SearchPathSuffixes);
}
+//----------------------------------------------------------------------------
void cmFindBase::PrintFindStuff()
{
std::cerr << "SearchFrameworkLast: " << this->SearchFrameworkLast << "\n";
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index 14f22c2..8ca311d 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -34,7 +34,6 @@ public:
protected:
void PrintFindStuff();
void ExpandPaths();
- void AddPathSuffixes(std::vector<std::string>& paths);
// see if the VariableName is already set in the cache,
// also copy the documentation from the cache to VariableDocumentation
@@ -61,14 +60,6 @@ private:
void FillSystemEnvironmentPath();
void FillCMakeSystemVariablePath();
void FillUserGuessPath();
-
- // Helpers.
- void AddCMakePrefixPath(const std::string& variable,
- std::vector<std::string>& outPaths);
- void AddEnvPrefixPath(const std::string& variable,
- std::vector<std::string>& outPaths);
- void AddPrefixPaths(std::vector<std::string> const& inPaths,
- PathType pathType, std::vector<std::string>& outPaths);
};
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index aea8e4e..87e98c1 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -15,6 +15,15 @@
//----------------------------------------------------------------------------
cmFindCommon::cmFindCommon()
+: CMakeVariablePaths(this, "CMAKE"),
+ CMakeEnvironmentPaths(this, "CMAKE_ENVIRONMENT"),
+ UserHintsPaths(this, "HINTS"),
+ SystemEnvironmentPaths(this, "SYSTEM_ENVIRONMENT"),
+ UserRegistryPaths(this, "USER_REGISTRY"),
+ BuildPaths(this, "BUILD"),
+ CMakeSystemVariablePaths(this, "CMAKE_SYSTEM_VARIABLE"),
+ SystemRegistryPaths(this, "SYSTEM_REGISTRY"),
+ UserGuessPaths(this, "GUESS")
{
this->FindRootPathMode = RootPathModeBoth;
this->NoDefaultPath = false;
@@ -44,27 +53,8 @@ cmFindCommon::~cmFindCommon()
}
//----------------------------------------------------------------------------
-std::string cmFindCommon::MakeFullPath(const std::string& path,
- PathType pathType)
-{
- // Select the base path with which to interpret relative paths.
- if(pathType == CMakePath)
- {
- return cmSystemTools::CollapseFullPath(
- path, this->Makefile->GetCurrentDirectory());
- }
- else
- {
- return cmSystemTools::CollapseFullPath(path, 0);
- }
-}
-
-//----------------------------------------------------------------------------
void cmFindCommon::SelectDefaultRootPathMode()
{
- // Use both by default.
- this->FindRootPathMode = RootPathModeBoth;
-
// Check the policy variable for this find command type.
std::string findRootPathVar = "CMAKE_FIND_ROOT_PATH_MODE_";
findRootPathVar += this->CMakePathName;
@@ -72,11 +62,11 @@ void cmFindCommon::SelectDefaultRootPathMode()
this->Makefile->GetSafeDefinition(findRootPathVar);
if (rootPathMode=="NEVER")
{
- this->FindRootPathMode = RootPathModeNoRootPath;
+ this->FindRootPathMode = RootPathModeNever;
}
else if (rootPathMode=="ONLY")
{
- this->FindRootPathMode = RootPathModeOnlyRootPath;
+ this->FindRootPathMode = RootPathModeOnly;
}
else if (rootPathMode=="BOTH")
{
@@ -152,7 +142,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
#endif
// Short-circuit if there is nothing to do.
- if(this->FindRootPathMode == RootPathModeNoRootPath)
+ if(this->FindRootPathMode == RootPathModeNever)
{
return;
}
@@ -280,8 +270,6 @@ void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore)
ignore.insert(ignoreVec.begin(), ignoreVec.end());
}
-
-
//----------------------------------------------------------------------------
bool cmFindCommon::CheckCommonArgument(std::string const& arg)
{
@@ -307,11 +295,11 @@ bool cmFindCommon::CheckCommonArgument(std::string const& arg)
}
else if(arg == "NO_CMAKE_FIND_ROOT_PATH")
{
- this->FindRootPathMode = RootPathModeNoRootPath;
+ this->FindRootPathMode = RootPathModeNever;
}
else if(arg == "ONLY_CMAKE_FIND_ROOT_PATH")
{
- this->FindRootPathMode = RootPathModeOnlyRootPath;
+ this->FindRootPathMode = RootPathModeOnly;
}
else if(arg == "CMAKE_FIND_ROOT_PATH_BOTH")
{
@@ -359,91 +347,6 @@ void cmFindCommon::AddPathSuffix(std::string const& arg)
}
//----------------------------------------------------------------------------
-void cmFindCommon::AddUserPath(std::string const& inPath,
- std::vector<std::string>& outPaths)
-{
- // We should view the registry as the target application would view
- // it.
- cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
- cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
- if(this->Makefile->PlatformIs64Bit())
- {
- view = cmSystemTools::KeyWOW64_64;
- other_view = cmSystemTools::KeyWOW64_32;
- }
-
- // Expand using the view of the target application.
- std::string expanded = inPath;
- cmSystemTools::ExpandRegistryValues(expanded, view);
- cmSystemTools::GlobDirs(expanded, outPaths);
-
- // Executables can be either 32-bit or 64-bit, so expand using the
- // alternative view.
- if(expanded != inPath && this->CMakePathName == "PROGRAM")
- {
- expanded = inPath;
- cmSystemTools::ExpandRegistryValues(expanded, other_view);
- cmSystemTools::GlobDirs(expanded, outPaths);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddCMakePath(const std::string& variable,
- std::vector<std::string>& outPaths)
-{
- // Get a path from a CMake variable.
- if(const char* varPath = this->Makefile->GetDefinition(variable))
- {
- std::vector<std::string> tmp;
- cmSystemTools::ExpandListArgument(varPath, tmp);
-
- // Relative paths are interpreted with respect to the current
- // source directory.
- this->AddPathsInternal(tmp, CMakePath, outPaths);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddEnvPath(const char* variable,
- std::vector<std::string>& outPaths)
-{
- // Get a path from the environment.
- std::vector<std::string> tmp;
- cmSystemTools::GetPath(tmp, variable);
- // Relative paths are interpreted with respect to the current
- // working directory.
- this->AddPathsInternal(tmp, EnvPath, outPaths);
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddPathsInternal(std::vector<std::string> const& inPaths,
- PathType pathType,
- std::vector<std::string>& outPaths)
-{
- for(std::vector<std::string>::const_iterator i = inPaths.begin();
- i != inPaths.end(); ++i)
- {
- this->AddPathInternal(this->MakeFullPath(*i, pathType), outPaths);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddPathInternal(std::string const& inPath,
- std::vector<std::string>& outPaths)
-{
- if(inPath.empty())
- {
- return;
- }
-
- // Insert the path if has not already been emitted.
- if(this->SearchPathsEmitted.insert(inPath).second)
- {
- outPaths.push_back(inPath);
- }
-}
-
-//----------------------------------------------------------------------------
void AddTrailingSlash(std::string& s)
{
if(!s.empty() && *s.rbegin() != '/')
@@ -458,17 +361,15 @@ void cmFindCommon::ComputeFinalPaths()
this->GetIgnoredPaths(ignored);
// Combine the seperate path types, filtering out ignores
- this->SearchPaths.clear();
- this->FilterPaths(this->CMakeVariablePaths, ignored, this->SearchPaths);
- this->FilterPaths(this->CMakeEnvironmentPaths, ignored, this->SearchPaths);
- this->FilterPaths(this->UserHintsPaths, ignored, this->SearchPaths);
- this->FilterPaths(this->SystemEnvironmentPaths, ignored, this->SearchPaths);
- this->FilterPaths(this->UserRegistryPaths, ignored, this->SearchPaths);
- this->FilterPaths(this->BuildPaths, ignored, this->SearchPaths);
- this->FilterPaths(this->CMakeSystemVariablePaths, ignored,
- this->SearchPaths);
- this->FilterPaths(this->SystemRegistryPaths, ignored, this->SearchPaths);
- this->FilterPaths(this->UserGuessPaths, ignored, this->SearchPaths);
+ this->CMakeVariablePaths.ExtractWithout(ignored, this->SearchPaths, true);
+ this->CMakeEnvironmentPaths.ExtractWithout(ignored, this->SearchPaths);
+ this->UserHintsPaths.ExtractWithout(ignored, this->SearchPaths);
+ this->SystemEnvironmentPaths.ExtractWithout(ignored, this->SearchPaths);
+ this->UserRegistryPaths.ExtractWithout(ignored, this->SearchPaths);
+ this->BuildPaths.ExtractWithout(ignored, this->SearchPaths);
+ this->CMakeSystemVariablePaths.ExtractWithout(ignored, this->SearchPaths);
+ this->SystemRegistryPaths.ExtractWithout(ignored, this->SearchPaths);
+ this->UserGuessPaths.ExtractWithout(ignored, this->SearchPaths);
// Expand list of paths inside all search roots.
this->RerootPaths(this->SearchPaths);
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index dfb942f..8102392 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -13,6 +13,7 @@
#define cmFindCommon_h
#include "cmCommand.h"
+#include "cmSearchPath.h"
/** \class cmFindCommon
* \brief Base class for FIND_XXX implementations.
@@ -29,15 +30,11 @@ public:
cmTypeMacro(cmFindCommon, cmCommand);
protected:
+ friend class cmSearchPath;
- enum RootPathMode { RootPathModeBoth,
- RootPathModeOnlyRootPath,
- RootPathModeNoRootPath };
-
- enum PathType { FullPath, CMakePath, EnvPath };
-
- /** Generate a full path based on the particular path type */
- std::string MakeFullPath(const std::string& path, PathType pathType);
+ enum RootPathMode { RootPathModeNever,
+ RootPathModeOnly,
+ RootPathModeBoth };
/** Place a set of search paths under the search roots. */
void RerootPaths(std::vector<std::string>& paths);
@@ -60,21 +57,15 @@ protected:
/** Compute the current default bundle/framework search policy. */
void SelectDefaultMacMode();
+ // Path arguments prior to path manipulation routines
+ std::vector<std::string> UserHintsArgs;
+ std::vector<std::string> UserGuessArgs;
+
std::string CMakePathName;
RootPathMode FindRootPathMode;
bool CheckCommonArgument(std::string const& arg);
void AddPathSuffix(std::string const& arg);
- void AddUserPath(std::string const& p,
- std::vector<std::string>& outPaths);
- void AddCMakePath(const std::string& variable,
- std::vector<std::string>& outPaths);
- void AddEnvPath(const char* variable, std::vector<std::string>& outPaths);
- void AddPathsInternal(std::vector<std::string> const& inPaths,
- PathType pathType, std::vector<std::string>& outPaths);
- void AddPathInternal(std::string const& inPath,
- std::vector<std::string>& outPaths);
-
void SetMakefile(cmMakefile* makefile);
bool NoDefaultPath;
@@ -84,15 +75,15 @@ protected:
bool NoCMakeSystemPath;
std::vector<std::string> SearchPathSuffixes;
- std::vector<std::string> CMakeVariablePaths;
- std::vector<std::string> CMakeEnvironmentPaths;
- std::vector<std::string> UserHintsPaths;
- std::vector<std::string> SystemEnvironmentPaths;
- std::vector<std::string> UserRegistryPaths;
- std::vector<std::string> BuildPaths;
- std::vector<std::string> CMakeSystemVariablePaths;
- std::vector<std::string> SystemRegistryPaths;
- std::vector<std::string> UserGuessPaths;
+ cmSearchPath CMakeVariablePaths;
+ cmSearchPath CMakeEnvironmentPaths;
+ cmSearchPath UserHintsPaths;
+ cmSearchPath SystemEnvironmentPaths;
+ cmSearchPath UserRegistryPaths;
+ cmSearchPath BuildPaths;
+ cmSearchPath CMakeSystemVariablePaths;
+ cmSearchPath SystemRegistryPaths;
+ cmSearchPath UserGuessPaths;
std::vector<std::string> SearchPaths;
std::set<std::string> SearchPathsEmitted;
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index ded6eee..258678d 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -248,11 +248,11 @@ bool cmFindPackageCommand
}
else if(doing == DoingPaths)
{
- this->AddUserPath(args[i], this->UserGuessPaths);
+ this->UserGuessArgs.push_back(args[i]);
}
else if(doing == DoingHints)
{
- this->AddUserPath(args[i], this->UserHintsPaths);
+ this->UserHintsArgs.push_back(args[i]);
}
else if(doing == DoingPathSuffixes)
{
@@ -1153,25 +1153,20 @@ void cmFindPackageCommand::FillPrefixesCMakeEnvironment()
{
// Check the environment variable with the same name as the cache
// entry.
- std::string env;
- if(cmSystemTools::GetEnv(this->Variable.c_str(), env) && env.length() > 0)
- {
- cmSystemTools::ConvertToUnixSlashes(env);
- this->AddPathInternal(MakeFullPath(env, EnvPath),
- this->CMakeEnvironmentPaths);
- }
+ this->CMakeEnvironmentPaths.AddEnvPath(this->Variable);
- this->AddEnvPath("CMAKE_PREFIX_PATH", this->CMakeEnvironmentPaths);
- this->AddEnvPath("CMAKE_FRAMEWORK_PATH", this->CMakeEnvironmentPaths);
- this->AddEnvPath("CMAKE_APPBUNDLE_PATH", this->CMakeEnvironmentPaths);
+ // And now the general CMake environment variables
+ this->CMakeEnvironmentPaths.AddEnvPath("CMAKE_PREFIX_PATH");
+ this->CMakeEnvironmentPaths.AddEnvPath("CMAKE_FRAMEWORK_PATH");
+ this->CMakeEnvironmentPaths.AddEnvPath("CMAKE_APPBUNDLE_PATH");
}
//----------------------------------------------------------------------------
void cmFindPackageCommand::FillPrefixesCMakeVariable()
{
- this->AddCMakePath("CMAKE_PREFIX_PATH", this->CMakeVariablePaths);
- this->AddCMakePath("CMAKE_FRAMEWORK_PATH", this->CMakeVariablePaths);
- this->AddCMakePath("CMAKE_APPBUNDLE_PATH", this->CMakeVariablePaths);
+ this->CMakeVariablePaths.AddCMakePath("CMAKE_PREFIX_PATH");
+ this->CMakeVariablePaths.AddCMakePath("CMAKE_FRAMEWORK_PATH");
+ this->CMakeVariablePaths.AddCMakePath("CMAKE_APPBUNDLE_PATH");
}
//----------------------------------------------------------------------------
@@ -1189,14 +1184,12 @@ void cmFindPackageCommand::FillPrefixesSystemEnvironment()
if((cmHasLiteralSuffix(*i, "/bin")) ||
(cmHasLiteralSuffix(*i, "/sbin")))
{
- this->AddPathInternal(MakeFullPath(cmSystemTools::GetFilenamePath(*i),
- EnvPath),
- this->SystemEnvironmentPaths);
+ this->SystemEnvironmentPaths.AddPath(
+ cmSystemTools::GetFilenamePath(*i));
}
else
{
- this->AddPathInternal(MakeFullPath(*i, EnvPath),
- this->SystemEnvironmentPaths);
+ this->SystemEnvironmentPaths.AddPath(*i);
}
}
}
@@ -1280,7 +1273,7 @@ void cmFindPackageCommand::LoadPackageRegistryWinSystem()
//----------------------------------------------------------------------------
void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view,
- std::vector<std::string>& outPaths)
+ cmSearchPath& outPaths)
{
std::wstring key = L"Software\\Kitware\\CMake\\Packages\\";
key += cmsys::Encoding::ToWide(this->Name);
@@ -1350,7 +1343,7 @@ public:
//----------------------------------------------------------------------------
void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
- std::vector<std::string>& outPaths)
+ cmSearchPath& outPaths)
{
cmsys::Directory files;
if(!files.Load(dir))
@@ -1388,7 +1381,7 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
//----------------------------------------------------------------------------
bool cmFindPackageCommand::CheckPackageRegistryEntry(const std::string& fname,
- std::vector<std::string>& outPaths)
+ cmSearchPath& outPaths)
{
// Parse the content of one package registry entry.
if(cmSystemTools::FileIsFullPath(fname.c_str()))
@@ -1400,13 +1393,11 @@ bool cmFindPackageCommand::CheckPackageRegistryEntry(const std::string& fname,
// The path exists. Look for the package here.
if(!cmSystemTools::FileIsDirectory(fname))
{
- this->AddPathInternal(
- MakeFullPath(cmSystemTools::GetFilenamePath(fname), FullPath),
- outPaths);
+ outPaths.AddPath(cmSystemTools::GetFilenamePath(fname));
}
else
{
- this->AddPathInternal(MakeFullPath(fname, FullPath), outPaths);
+ outPaths.AddPath(fname);
}
return true;
}
@@ -1443,7 +1434,7 @@ void cmFindPackageCommand::FillPrefixesBuilds()
if(cmSystemTools::FileIsFullPath(f.c_str()) &&
cmSystemTools::FileIsDirectory(f.c_str()))
{
- this->AddPathInternal(MakeFullPath(f, FullPath), this->BuildPaths);
+ this->BuildPaths.AddPath(f);
}
}
}
@@ -1451,28 +1442,29 @@ void cmFindPackageCommand::FillPrefixesBuilds()
//----------------------------------------------------------------------------
void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
{
- this->AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH",
- this->CMakeSystemVariablePaths);
- this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH",
- this->CMakeSystemVariablePaths);
- this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH",
- this->CMakeSystemVariablePaths);
+ this->CMakeSystemVariablePaths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
+ this->CMakeSystemVariablePaths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
+ this->CMakeSystemVariablePaths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
}
//----------------------------------------------------------------------------
void cmFindPackageCommand::FillPrefixesUserGuess()
{
- std::vector<std::string> inPaths;
- inPaths.swap(this->UserGuessPaths);
- this->AddPathsInternal(inPaths, CMakePath, this->UserGuessPaths);
+ for(std::vector<std::string>::const_iterator p = this->UserGuessArgs.begin();
+ p != this->UserGuessArgs.end(); ++p)
+ {
+ this->UserGuessPaths.AddUserPath(*p);
+ }
}
//----------------------------------------------------------------------------
void cmFindPackageCommand::FillPrefixesUserHints()
{
- std::vector<std::string> inPaths;
- inPaths.swap(this->UserHintsPaths);
- this->AddPathsInternal(inPaths, CMakePath, this->UserHintsPaths);
+ for(std::vector<std::string>::const_iterator p = this->UserHintsArgs.begin();
+ p != this->UserHintsArgs.end(); ++p)
+ {
+ this->UserHintsPaths.AddUserPath(*p);
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index f22433e..17bc456 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -78,14 +78,13 @@ private:
void FillPrefixesCMakeSystemVariable();
void FillPrefixesUserGuess();
void FillPrefixesUserHints();
- void LoadPackageRegistryDir(std::string const& dir,
- std::vector<std::string>& outPaths);
+ void LoadPackageRegistryDir(std::string const& dir, cmSearchPath& outPaths);
void LoadPackageRegistryWinUser();
void LoadPackageRegistryWinSystem();
void LoadPackageRegistryWin(bool user, unsigned int view,
- std::vector<std::string>& outPaths);
+ cmSearchPath& outPaths);
bool CheckPackageRegistryEntry(const std::string& fname,
- std::vector<std::string>& outPaths);
+ cmSearchPath& outPaths);
bool SearchDirectory(std::string const& dir);
bool CheckDirectory(std::string const& dir);
bool FindConfigFile(std::string const& dir, std::string& file);
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
new file mode 100644
index 0000000..19f2c3f
--- /dev/null
+++ b/Source/cmSearchPath.cxx
@@ -0,0 +1,243 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmSearchPath.h"
+#include "cmFindCommon.h"
+
+//----------------------------------------------------------------------------
+cmSearchPath::cmSearchPath(cmFindCommon* findCmd,
+ const std::string& groupLabel)
+: FindName(findCmd->CMakePathName), Makefile(findCmd->Makefile),
+ Emitted(findCmd->SearchPathsEmitted), Label(groupLabel)
+{
+}
+
+//----------------------------------------------------------------------------
+cmSearchPath::~cmSearchPath()
+{
+}
+
+//----------------------------------------------------------------------------
+
+void cmSearchPath::ExtractWithout(const std::set<std::string>& ignore,
+ std::vector<std::string>& outPaths,
+ bool clear) const
+{
+ if(clear)
+ {
+ outPaths.clear();
+ }
+ for(std::vector<std::string>::const_iterator p = this->Paths.begin();
+ p != this->Paths.end(); ++p)
+ {
+ if(ignore.count(*p) == 0)
+ {
+ outPaths.push_back(*p);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddPath(const std::string& path)
+{
+ this->AddPathInternal(path);
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddUserPath(const std::string& path)
+{
+ std::vector<std::string> outPaths;
+
+ // We should view the registry as the target application would view
+ // it.
+ cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
+ cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
+ if(this->Makefile->PlatformIs64Bit())
+ {
+ view = cmSystemTools::KeyWOW64_64;
+ other_view = cmSystemTools::KeyWOW64_32;
+ }
+
+ // Expand using the view of the target application.
+ std::string expanded = path;
+ cmSystemTools::ExpandRegistryValues(expanded, view);
+ cmSystemTools::GlobDirs(expanded, outPaths);
+
+ // Executables can be either 32-bit or 64-bit, so expand using the
+ // alternative view.
+ if(expanded != path && this->FindName == "PROGRAM")
+ {
+ expanded = path;
+ cmSystemTools::ExpandRegistryValues(expanded, other_view);
+ cmSystemTools::GlobDirs(expanded, outPaths);
+ }
+
+ // Process them all from the current directory
+ for(std::vector<std::string>::const_iterator p = outPaths.begin();
+ p != outPaths.end(); ++p)
+ {
+ this->AddPathInternal(*p, this->Makefile->GetCurrentDirectory());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddCMakePath(const std::string& variable)
+{
+ // Get a path from a CMake variable.
+ if(const char* value = this->Makefile->GetDefinition(variable))
+ {
+ std::vector<std::string> expanded;
+ cmSystemTools::ExpandListArgument(value, expanded);
+
+ for(std::vector<std::string>::const_iterator p = expanded.begin();
+ p!= expanded.end(); ++p)
+ {
+ this->AddPathInternal(*p, this->Makefile->GetCurrentDirectory());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddEnvPath(const std::string& variable)
+{
+ std::vector<std::string> expanded;
+ cmSystemTools::GetPath(expanded, variable.c_str());
+ for(std::vector<std::string>::const_iterator p = expanded.begin();
+ p!= expanded.end(); ++p)
+ {
+ this->AddPathInternal(*p);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
+{
+ // Get a path from a CMake variable.
+ if(const char* value = this->Makefile->GetDefinition(variable))
+ {
+ std::vector<std::string> expanded;
+ cmSystemTools::ExpandListArgument(value, expanded);
+
+ this->AddPrefixPaths(expanded, this->Makefile->GetCurrentDirectory());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddEnvPrefixPath(const std::string& variable)
+{
+ std::vector<std::string> expanded;
+ cmSystemTools::GetPath(expanded, variable.c_str());
+ this->AddPrefixPaths(expanded);
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddSuffixes(const std::vector<std::string>& suffixes)
+{
+ std::vector<std::string> inPaths;
+ inPaths.swap(this->Paths);
+ this->Paths.reserve(inPaths.size()*(suffixes.size()+1));
+
+ for(std::vector<std::string>::iterator ip = inPaths.begin();
+ ip != inPaths.end(); ++ip)
+ {
+ cmSystemTools::ConvertToUnixSlashes(*ip);
+
+ // if *i is only / then do not add a //
+ // this will get incorrectly considered a network
+ // path on windows and cause huge delays.
+ std::string p = *ip;
+ if(!p.empty() && *p.rbegin() != '/')
+ {
+ p += "/";
+ }
+
+ // Combine with all the suffixes
+ for(std::vector<std::string>::const_iterator s = suffixes.begin();
+ s != suffixes.end(); ++s)
+ {
+ this->Paths.push_back(p+*s);
+ }
+
+ // And now the original w/o any suffix
+ this->Paths.push_back(*ip);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
+ const char *base)
+{
+ // default for programs
+ std::string subdir = "bin";
+
+ if (this->FindName == "INCLUDE")
+ {
+ subdir = "include";
+ }
+ else if (this->FindName == "LIBRARY")
+ {
+ subdir = "lib";
+ }
+ else if (this->FindName == "FRAMEWORK")
+ {
+ subdir = ""; // ? what to do for frameworks ?
+ }
+
+ for(std::vector<std::string>::const_iterator p = paths.begin();
+ p != paths.end(); ++p)
+ {
+ std::string dir = *p;
+ if(!subdir.empty() && !dir.empty() && *dir.rbegin() != '/')
+ {
+ dir += "/";
+ }
+ if(subdir == "include" || subdir == "lib")
+ {
+ const char* arch =
+ this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
+ if(arch && *arch)
+ {
+ this->AddPathInternal(dir+subdir+"/"+arch, base);
+ }
+ }
+ std::string add = dir + subdir;
+ if(add != "/")
+ {
+ this->AddPathInternal(add, base);
+ }
+ if (subdir == "bin")
+ {
+ this->AddPathInternal(dir+"sbin", base);
+ }
+ if(!subdir.empty() && *p != "/")
+ {
+ this->AddPathInternal(*p, base);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddPathInternal(const std::string& path, const char *base)
+{
+ std::string collapsed = cmSystemTools::CollapseFullPath(path, base);
+
+ if(collapsed.empty())
+ {
+ return;
+ }
+
+ // Insert the path if has not already been emitted.
+ if(this->Emitted.insert(collapsed).second)
+ {
+ this->Paths.push_back(collapsed);
+ }
+}
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
new file mode 100644
index 0000000..88ef0ff
--- /dev/null
+++ b/Source/cmSearchPath.h
@@ -0,0 +1,60 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmSearchPath_h
+#define cmSearchPath_h
+
+#include "cmStandardIncludes.h"
+
+class cmFindCommon;
+
+/** \class cmSearchPath
+ * \brief Base class for FIND_XXX implementations.
+ *
+ * cmSearchPath is a container that encapsulates search path construction and
+ * management
+ */
+class cmSearchPath
+{
+public:
+ cmSearchPath(cmFindCommon* findCmd, const std::string& groupLabel);
+ ~cmSearchPath();
+
+ const std::string& GetLabel() const { return this->Label; }
+ const std::vector<std::string>& GetPaths() const { return this->Paths; }
+
+ void ExtractWithout(const std::set<std::string>& ignore,
+ std::vector<std::string>& outPaths,
+ bool clear = false) const;
+
+ void AddPath(const std::string& path);
+ void AddUserPath(const std::string& path);
+ void AddCMakePath(const std::string& variable);
+ void AddEnvPath(const std::string& variable);
+ void AddCMakePrefixPath(const std::string& variable);
+ void AddEnvPrefixPath(const std::string& variable);
+ void AddSuffixes(const std::vector<std::string>& suffixes);
+
+protected:
+ void AddPrefixPaths(const std::vector<std::string>& paths,
+ const char *base = 0);
+ void AddPathInternal(const std::string& path, const char *base = 0);
+
+ // Members collected from the calling find command
+ const std::string& FindName;
+ cmMakefile* const& Makefile;
+ std::set<std::string>& Emitted;
+
+ std::string Label;
+ std::vector<std::string> Paths;
+};
+
+#endif